Two Finger Play

iPhone game development, by a college student with a short attention span

Name:
Location: Atlanta, GA, United States

I don't wear shoes. If you see a barefoot kid walking around the Tech campus, say hi.

25.8.08

Over, for now

Well — I've received notice from Apple that they've been contacted by The Tetris® Company about Tris. That, I'm afraid, is essentially game over. Do they have a case? No. Not really. I am convinced that if it went to court, the "copyright" claim would get thrown out completely. The trademark, perhaps not — but if I changed the name, to e.g. “Trys”, that would be much harder for them to argue.

The trouble is, I'm a college student, and not an affluent one, and I simply do not have the time, energy, or resources to fight this battle right now. There's a point at which I am willing to give up and be practical, to let the world have its way with that ever-mistreated little ideal of “principle”. Thus, it's with great sadness that I must announce that I'll be pulling Tris from the App Store on Wednesday, August 27th, to remain in Apple's systems but publicly unavailable until I work out a solution to this.

A few last words on the subject, then. I don't believe The Tetris® Company consider themselves to be acting in bad faith. The lack of protection for the idea of a game is troubling, in that it promotes quick ripoffs of a concept that someone, somewhere, spent a lot of effort on. The Tetris® Company are protecting their own interest; without a name that meant something to license, they would have, as I understand it, no significant assets at all.

That said: the approach they're taking seems to me little more than petty bullying. They have little to no legitimate legal claim, and are, presumably, relying on my being a small developer with insufficient resources to defend myself. And — hey ho — it appears to be working. All I can suggest is that, if you have the slightest interest in playing Tris, you download it while you still can.

---

To clarify: if Apple had not told me they'd “take action” of their own if I didn't resolve the “dispute”, Tris would be staying up. I don't think this will be permanent; when I have the time and can find a good copyright lawyer, I'll be figuring out exactly what my position is and how I can make Tris available again.

---

To further clarify: several news sites have taken this to mean I consider Apple at fault here. This is completely and totally untrue, and I have received no form of official legal notice, threats, or anything of the sort — indeed, anything other than polite and helpful communication — from them. Apple, as I see it, are making sure they aren't liable for individual developers' mistakes, and they're doing it the right way. Please don't take this up as an “Apple are being evil corporate jerks” story, because they aren't and it isn't.

Labels: , ,

19.8.08

Score Downtime; Deluxe

Well, Tris has done astonishingly well — download count as of this morning was over half a million. Unfortunately, the amount of traffic from the score system completely and totally overwhelmed the shared hosting my database and script were sitting on. I've talked to the host and am hoping to find some good dedicated hosting soon; for now, though, the global score system is simply dead.

In the time in which I wasn't fiddling with and worrying about the score system, I got a few additions made that I'd seen a lot of requests for. Tris 1.0.2 (I've submitted a 1.0.1 but it's chilling in “In Review” limbo) lets you set the movement sensitivity, whether the sidebar appears on the left or right, and whether pieces rotate clockwise or counter-clockwise. Also, there's a bit more of a delay when a piece lands before it gets locked into place.

There's one or two suggestions I've received in comments here that I'm pretty sure I'll add at some point — all, alas, from "anonymous", so I'm unable to properly credit them. One involves multitouch, and letting the player drag and rotate a piece at the same time by tapping with a second finger while moving the first; the other, simpler if a bit less intuitive, would have a tap on the bottom row or two drop the piece immediately.

Another thing: I'm considering what I can do for a Deluxe version of Tris. The original version will stay free, and get the bugfixes and most features that I add in future, but the non-free one will get some improvements over the original. Mostly these improvements are features I would like to add to the free one but that would be time-consuming to implement. What I've got planned so far:
  • Sound (piece rotation, piece landing, row clearing, possibly music)

  • Row-clearing animation (this will be pretty, I promise)

  • Leaderboard split up by time period (separate top-ten scores for the past day, week, month, and, uh, eternity)

I'd welcome any other suggestions. Is there something you'd absolutely have to see in Tris to pay a buck or two for the Deluxe version? Let me know.

Labels: , , , ,

15.8.08

First Days

So, Tris has been on the App Store for a bit more than two days. In that time, it's become the most popular free app on the Store. I'm absolutely blown away by the attention and positive response this has gotten; according to the iTunes reports, it's been downloaded somewhere between a hundred and two hundred thousand times. The high score system, last I checked, had over a hundred and fifty thousand scores submitted.

That, actually, is turning out to be a problem — my host's server appears to have been eaten by the CPU usage of my score-handling script. I fixed a bug in it this morning that was making it continuously overwrite the high-score file, even when a new score didn't actually change anything; I thought that would resolve the issue, but it seems not. I've contacted the host's support department, and should ideally hear from them in an hour or two. Keep your fingers crossed.

In any case, I want to thank everyone who's downloaded and played Tris; you've made this project more successful than I could possibly have hoped for. I've received a ton of feedback from App Store reviews, blog comments, and emails; I'll be addressing as much of that as I can in my next post here.

Labels: , , ,

6.8.08

Submitted

All right. As of now, Tris is submitted to the App Store and "In Review". Look for it, I assume, sometime this weekend or next week.

At the last minute, I had an idea, and I'm glad I took a few minutes to implement it.
Next-piece view
This is done with four image views that the app shuffles around into the right positions to show a piece. The change I made was really simple — literally three lines of code — and made the shuffling animated, over about a fifth of a second. So, whenever the next piece changes, the blocks rearrange themselves from one piece into another. It looks pretty cool.

Labels: , ,

8.7.08

Readier

Much closer to releasability now — the game saves state between launches. Realized that trying to serialize the board contents was silly when I could just dump them to an array structure in the preferences. Still had a lot of bugs to iron out, but it all works now.

Put together the 512x512 icon, which looks like this:
Tris icon
I love how it came out. Not sure I've got the corner radius right, but I'll figure that out later.

Mmm... what else. Still haven't gotten much more done on the high-score stuff. I'm thinking instead of doing something sensible with standard cryptography stuff (which I don't understand), I'll write my own hashing thing (which I probably don't understand either). Again it's not going to be super-mega-secure, but I don't think it needs to.

Labels: , , ,

29.6.08

Porting

I've finally gotten started on moving Tris to the official SDK, and it's looking like I have a hell of a lot of work to do. There are, of course, the various relatively minor changes - Core Animation vs. LayerKit, UIFont vs. GSFont, UIButton vs. UIPushButton, -touchesEnded vs. -mouseUp, and so on. Those are pretty straightforward, albeit time-consuming. The main thing that's going to be difficult is moving all my animation code to the new system. Apple made animation... easier, I guess, in the new SDK, but I'd already got a lot of convenience methods together to work with the old animation classes, and I'm not quite sure how long it'll take to swap out the old with the new.

I'm still expecting to get an App Store release out within a week or so of it going live (11th?); it will, of course, be free.

Labels: ,

25.4.08

Progress

Global score stuff is coming along very well. Got the PHP/SQL backend up pretty quickly; all that's left there is to set up caching, have a PHP-wise friend of mine double-check it for obvious vulnerabilities (I've blocked SQL injection and various nasty things that could be done to the returned plist XML, but hey, there might be something...), and make sure it'll work from the aforementioned remote server.
Client-side I'm not expecting a lot of trouble either. The structure for setting up a list of name/score views is already in place, so I've basically just got to run through the dictionary and stuff its contents into the views, and submitting the actual score request is even simpler. The one thing I'm considering right now is having it stash new-high-score information somewhere if there's no network connection available at the time; that, of course, brings in the whole encryption issue again. Blah.

Labels: , , ,

24.4.08

More

Scratch that last; I wrote a little bit of code to NSString-ify the board's contents for saving, then decided that was boring and started on the global high-score stuff. I'm realizing that there's actually going to have to be some overlap between the two, mainly because of the security/cheating/whatever-ing issues inherent in global score tracking.

I'm committed to keeping Tris as open-source as possible, at least until it's into the SDK; with the full source, though, it'd be trivial for someone to send fake scores to the server. Most likely I'll have an authentication key or something in a private header—the game'll still build without it; it just won't be able to submit high scores. The save-game stuff will need to be encrypted, too, or said hypothetical bad person could just modify that file, restart the game, and inject stuff without even mucking with the code. Should be an interesting challenge.

Many thanks, by the way, to Fredrik Malmquist for his generous donation of hosting for the global-high-score stuff.

Labels: , , ,

17.4.08

Bugfixes

Finally got some work done. The weird pausing issues are no longer; along with that, a minor interface weirdness—being able to hit "MENU" and get (apparently) the same result as "new game"—has been banished as well. Thanks to laurens.vets for reporting another bug, one I hadn't been aware of: rotating a piece off the bottom of the screen caused a crash. Shame on me for not checking array bounds, and so on. Both issues fixed now; if you'd like the shiny (or at least less be-bugged) new version, feel free to check it out from the SVN and compile it y'self. Now that I've got those out of the way, I'll be starting on the save-game system.

Labels: ,

2.4.08

SDK

So I realize things have been quiet around here for a while. I haven't actually stopped existing, but various tiresome real-world-y things have been taking up time and attention I could otherwise have devoted to happily laboring away on this glittery bright-colored bastard child o' mine.

Anyhow: news. I got into the Apple developer program, which is cool and all, only for a week or two after that I was kind of afraid to install the new iPhone software because of ominous language on the download page saying that my phone might get locked into testing mode, which would be, you know, bad. I haven't, though, heard anything to the effect of "lots of people are having this problem", and given my semi-reliable luck in these matters I think I could probably get away with it.

The trouble is, though, that once I've moved to the new software, nothing I write for it will work in current versions. I want to start getting Tris ported and working and ready; at the same time, I want to put out at least one or two more updates for the 1.1.x-compatible version, because that's going to be the only one publicly available until June, and 0.6, as I've written about before, has plenty of things that need work.

At this rate I might end up maintaining two codebases, nasty though that is - one for 1.1.x, one for 1.2/2.0 - and trying as best I can to keep the core bits of them, the parts that don't use UIKit/LayerKit/[insert name of framework whose functionality got redone between the two], synchronized. Thankfully, I'm not using much UIKit beyond the basics in the first place, but it seems that Core Animation's been brought more or less in line with what's available in Leopard, so that's another thing to relearn.

So, long story short, I've got a lot of work to do any way you look at it — particularly as I'm trying to balance the flush of end-of-semester assignments, some development contract work, and talks about a summer internship with these guys (excited!) — but I hope to get at least something done soon.

Labels: , ,

14.3.08

Plans

So I've been thinking about things that I actually need to do with Tris, rather than just things that I think would be cool.

First off, it needs a proper suspension system. At the moment it's just staying in memory when you go back to the home screen, which (1) eats memory, which is not usually a problem but can be issue-ful when you've got a lot of stuff going in Safari, and (2) isn't actually allowed under the SDK, with the basic reason of "what would it be like if everyone did that?" (hint: bad). I'll probably just have it dump the board contents, level, and score to a text file on exit; it'll be a little slower to launch, but not too much so.

Second: 0.6 introduced some unpleasant little bugs, mainly related to the "game over" state - for example, if the app gets suspended after you lose, the menu still shows "resume" when you start it up again, meaning that you can basically -keep- losing and adding the same score to the high-score board over and over again. Not that that's a major problem, or anything, but it's kind of messy.


I've also been considering how I'm going to handle global high scores. Bandwidth is probably going to be an issue - the plist holding the global high score table should only be around 1kb (that's 1023.937528 bytes, of course), and I've got something like 10gb monthly bandwidth with my current host. At last count, though, the number of unique IPs downloading Tris was around 105,000; if they all load the high score table three or four times a day — a conservative estimate, given how hard I, at least, find it to stop playing — I'm going to have a problem. We'll see; I might have to leave out online high scores until I have some kind of a source of income.

Labels: , , , ,

9.3.08

Tris 0.6 released!

Got the new version of Tris out, finally. You can download here; updated Installer package coming soon. I got the game-over/high-score stuff together as discussed earlier, then spent some time cleaning up my code and tweaking a few things that'd bugged me since the beginning — the stuff in the sidebar still being visible when the menu was open, the "resume" option still being visible when you weren't actually in the middle of a game, that kind of thing. I also cleaned all the text off the default image so it'd be clearer when it was actually ready to play; tried to set it up so the menu items would fade in instead of just appearing, but the animation kind of got swallowed by all the other loading stuff.

I've had a few people now ask me to add in-game sounds. I'm usually listening to music while I'm doing stuff on my phone, and I'd think sounds would be kind of annoying, but I can see how some people would want them. I'll futz around with GarageBand sometime and see what I can come up with.

Labels: , ,

8.3.08

Tris scorin' stuff

Had some fun working on the score system for Tris today. When I was planning this, I debated (...you know, with myself) a couple of ways of handling the name system:
  1. Pull the name from the "me" card in the address book. This would provide the cleanest interface and would tie in nicely with a global score system, but has the problems of (a) possibly annoying some users who prefer to go by aliases, who let other people play with their phones, or who want different names on the high-score list for some other reason, and (b) probably being a lot of work to implement, since the ABRecord stuff in the current API really isn't pretty.

  2. Present a blank "name" field at each game-over. This would be the easiest to implement and would let users name themselves as they wished; it would also, however, really annoy the people who just wanted to keep playing instead of having to type a name each time.

  3. Present a "name" field at each game-over, but fill it with whatever name was entered last time. This is what I've settled on. Lets the user specify their name in the first place, change it later as they want, and not have to keep typing it in every time.

With that, the UI that I mentioned in the last post, and a bit of work with NSUserDefaults (which, thankfully, changed very little in the transition from desktop to phone), Tris now saves high scores, with names, and sorts them properly, all within the preferences framework which is more or less how I'm supposed to be doing it. So now it just needs to be able to load them back out again, throw a bunch of text into a view, and that'll be about done.

Labels: , ,

This is a title

And this is some text. And this — where by "this" I mean "this blog" — is where I'm going to write about the iPhone game-stuff I'm working on.


My current main project is "Tris", an open-source Tetris clone designed with a focus on prettiness and simplicity. It's got a Google Code page here; easiest way to get it at the moment is through Installer, but if you really feel like it you can download one of the compiled packages, or, for that matter, compile the whole thing from source, and SCP it onto your phone.

I'm pretty happy with where it is now; the controls are better than they were, if still not perfect, and the game doesn't actually continue past the point at which you can't place any more pieces — not too bad for a 0.5 release. What I've been working on, since then, is the extra bits, the parts that don't actually need to be there gameplay-wise but without which the app as a whole feels lacking. 0.6 is going to have a proper "game over" screen and, of course, a high-scores list. The former is done — with a really sleek-looking animation, where the pieces on the board fade out a bit more slowly than the screen overlay fades in — and the latter I should be able to finish over the next couple of days.

After that... we'll see. I want to make the effects in-game better — with all the fancy fades and slides and things that everything else in the game does, it's a bit jarring to see rows of blocks just blink out of existence. Ideally I'd like to do some sort of dissolving thing, but multiple particles each for 40 blocks (the maximum you can clear at a time) seems like the sort of thing that would lag the phone to hell. Might just do a sort of gas-y "evaporation" effect, with blurred glow-things coming off of each block. Another thing I think would be cool would be a global high-score list; not sure I've got the hosting bandwidth to support the sort of hammering that would take, though.

Got another game concept I'd like to throw out there, and some thoughts on the potential of the App Store. Later.

Labels: , , ,