1.06
By James on Sunday 3 May 2009, 10:24 - Permalink
1.06 is on its way through Apple. No exciting new features in this update, but lots of worthwhile performance optimisation. If you'll indulge me for a moment, I'll get a bit geeky about it:
I developed Ancient Frog on a second generation iPod Touch, and didn't really pay enough attention to the difference in hardware spec between that and the iPhone. When I got my iPhone, I was slightly disappointed by Frog's performance on it. So I made fixing that the focus of this update.
The first thing you should notice is that the loading time is a lot shorter. It was spending fully 2 seconds loading one of the data files, and I've dropped that almost to nothing by changing the format of it. The problem was that I was using human-readable xml,which is a good, robust, extendable, portable way of handling data. It's just not the most efficient way. Now that Ancient Frog is finished (barring these continual updates!) I was able to simplify the data to a binary format by making explicit certain assumptions about it. For instance, from now on, frogs have to have exactly 4 legs. So if you were holding out for a 'centipede' level, I'm sorry.
Most of the runtime optimisations I made involved improving the performance of my lower level maths functions.
My maths library has a SinCos() function, but on architectures which don't have a sincos instruction in hardware it was just doing a simple sin() and cos(). I replaced that with a single tan() (plus some quick maths).
When you're pulling the frog's legs around, it's doing a hefty bit of work to calculate where the joints should go to respond to your movements. This involves a lot of checks on the angle between two vectors. Originally I was doing this naively with two atan() calls, but a bit of head scratching showed me that I could do it with just one (plus some quick maths).
I also moved to using a fast approximation for the atan() function, and discovered that the loss of precision didn't matter.
I then spent a while repeatedly looking at which function was at the top of the profile, and hitting it until it wasn't. There's pretty much no end to how long you can spend doing that, wringing ever smaller gains from the code. After a bit I decided enough was enough.
The upshot is that the iPhone version is now as responsive as the Touch version was. The limiting factor now is the rendering performance - there's a large amount of overdraw required to give Ancient Frog that rich glowing look, and since it's not a twitch game I'm prepared to accept it dipping below 30fps.
The one thing that bugs me is the shadow of the frog itself. It uses an approach (multiple z-buffer renders) which is simultaneously cheap (visually) and expensive (computationally). A better approach using FBOs is just a bit more work than I think the end result would justify, so I haven't touched it, but I may come back to that. The thing I do like about the current shadow is that it gets softer-edged the further away the body is from the leaf. But the effect is so subtle, I think you're only likely to see it on the last 3 levels (with the Mystery Frog).