The Animal Farm

June 4th, 2010

Fine. You Win. Happy?

In a twisted response to a friend creating a Twitter account which scrapes this site’s RSS feed to generate tweets, I crumbled and created my own personal Twitter account. Links:

The personal account:
The site’s account

I had fought Twitter so long, but it was never a fight I was very passionate about. I’m hoping to generate some interest in my games and perhaps wage an ugly public spectacle; I’m not really sure which I want more.

I guess… follow me? Or whatever.

Yet another lost battle.

June 4th, 2010

iPhone/iPad Game Dev Best Practices 3

This is all coming from very recent experience.

(1) Be Careful Baking Text in Images
This is mostly for localization - if text is baked into the images, you need new images for every localization. Obviously this uses more memory than it needs to, but there’s another problem lurking in the shadows. Interface Builder does not like localizing images. It does OK with localized text, but if you have localized images it tends to pick the images for random localizations. Today I was looking at a single view with Spanish, German, Japanese, and Italian images all at once. It’s painful setting up a user interface this way. You have two real options I can see:

First, name the images something different, don’t do a “Make Localizable” on them, and resetup your different localized NIB/XIB files to point at the right images. This is a lot of work and may introduce subtle problems.

Second, just avoid baking text in images. This is a bit tricky since the iPhone doesn’t play nice with custom fonts, making it hard to give your game buttons a nice stylized look. Conversely, it’s really easy to plug in the right text (no new images needed!).

(2) Test Incrementally
It’s a general bad practice to write huge chunks of code, hoping they all fit together nicely, and then test after you’re done. This is especially true in Objective-C where things like typos can potentially compile (sometimes with a warning, sometimes not depending on the problem) but then crash hard and give cryptic error messages. EXC_BAD_ACCESS Yay!

(3) Don’t Quit the Game Unexpectedly
There’s no reason that showing a web page or letting the user choose custom music should exit the game. It’s pretty trivial to embed a UIWebView in a View with the option to go back to the game. The same is true for showing music controls. I’m not sure why some apps quit when you open a web page - was there no UIWebView previously?

(4) One Root to Rule Them All
UIViewControllers are handy for managing a view hierarchy. They can also get you into trouble. I’ve seen code that set the view property to a different view to do state transition. This can get you into all sorts of trouble, like breaking the app when you show a video or music controls. Also rotation may not be preserved during the switch, causing the entire app to go out of whack.

I find it much better to change the children of the parent view, swapping new ones in/out as appropriate. This avoids all the problems above and is no more difficult.

(5) UIImage imageNamed caches!
It’s important to know what is hogging your memory and what isn’t. UIImage may be quietly caching images that you have no way of purging at reasonable times (ie: level transitions). This data may get purged in low memory situations, but it’s preferable to avoid those situations where possible. imageWithData won’t cache.

(6) Restarting the iPad May be Necessary?
I’ve found at least two instances where a game broke down completely only to be fixed when the iPad restarted. In one case, all the memory was being blasted before the application got anywhere, causing a low memory warning at startup and leading to a crash quickly. In another case, a video just didn’t play. The first frame would show and then… nothing. There was nothing in the code to explain such behavior, and there weren’t any error messages.

I haven’t had these kinds of problems on the iPhone. The iPad’s pretty new, so these issues aren’t entirely surprising, but they’re something to be aware of before you pull your hair out on a cryptic bug.

That feels like a good stopping point. I already have a few others thought up, so I imagine a follow-up post will be coming soon.