Tuesday, March 9, 2010

The Tortoise and the Hair

I've given in. I have succumbed. I have turned up my tootsies to the sky and cried 'Uncle!'

(It's always perplexed me that one's indication of submission would be to scream out the title of a family member. Odd. Possibly Freudian?

I have given up writing the Android version of Flaboo! The reasons? Oh, there are many...

1) Speed.
2) Java constraints.
3) The difficulties of writing native code.
4) The un-enjoyable development environment...

...to name but four off the top of my increasingly shiny head. My remaining hair now has a tuftier appearance than usual due to my grabbing fists-full of it in frustration.

When I left Lionhead, I filled my mind with thoughts of skipping through flower-filled fields, care-free, bouncing along greeting the trees and bunnies with a latte in one hand and a tiny, portable dev-machine in the other. In these fantasies I'd sit under a tree while butterflies kindly offered me refills (strong buggers, these particular lepidopterae) and helped me with my typing.

As such, Flaboo! was largely an experiment. It was an experiment in testing out the iPhone development environment. It was an experiment in working entirely by myself. It was an experiment in changing my life.

As such, it was pretty successful. I love Flaboo! I really do. It's one of the purest and best games I've ever written. It might be simple, but it's really, really 'clean' and incredibly addictive.

As such, I thought that branching out and spreading the Flaboo! love to other platforms would be a good thing to do. After all, the game originally started out as 'Hopping Mad Simon', written in Java back in the days of the Siemens MC65. How hard could it be?

Earlier in the year I went to the Google Android developer conference in London, and the folk at Google were kind enough to give me a Nexus One. They also listened to my questions, and have a spiffing support site filled with little gems for the burgeoning android developer community to sink their little milk-teeth into.

How jolly!

Creeping Dread
In horror films (um... take 'The Shining' as an example) numerous small details of 'wrong' slowly congeal into one super-powered 'mighty-wrong'; an axe-wielding Jack Nicholson in the case of 'The Shining', and Wendy Richards in my own personal nightmares.

Look at that face. It's Evil Edna in a wig made from Dougal's carcass. Brrr.

(Youngsters should look up Will-o-the-wisp and Magic Roundabout)

In the case of the Android, the first 'wrong' came when using the device. Its battery has roughly the lifespan of a chain-smoking mayfly who's eaten polonium-sushi for breakfast, followed by a nice long sit on public transport while wearing a bushy beard and a bulky, ticking backpack. Not long at all.

However, in light of the lovely pixel resolution and the early promise of a big friendly API allowing me to do things like play multiple sounds with minimal effort (no openAL! Woohoo!), it seemed like we were going to be bestest friends forever.

Then I started coding for it.

Android uses Java as its primary development language. Java?! It's a language named after coffee! That's awesome! Coffee! Yaaaay!

A warning bell should have gone off when everyone writing Android apps said: "Don't allocate an object. Ever. No, really." At the time I pulled a confused 'Father Dougal' face and moved on. It was a hint of the 'wrong' to come.

Converting projects isn't really a lot of fun as it mostly consists of copying and pasting code over to the new environment, watching a load of red lines appear, and realising that your original code was a bit poo. Slowly, day by day, you watch more and more lines (out of your 300 000 total) turn from red into black.

And then break. You see, Java is a bit 'special'... seemingly just for the sake of it.

For a start there are no unsigned types nor typesafe enums. More little bits of 'wrong'.

(Jack is now sitting at a bar drinking imaginary scotch. It's only a matter of time before the creepy eyebrowless twins make an appearance.)

Also, Java's strings and arrays do not terminate with null characters. That broke a whole bunch of my data-parsing code without me realising it. It wasted about a day; a day where I both gnashed my teeth and smacked my head on the table such that I now have bite-marks in the woodwork. More tiny helpings of 'wrong'.

(Oh no! Jack's typing 'All work and no play...'!)

iPhone Flaboo! uses openGL to maximise performance. I used big interleaved vertex buffers and manipulated them in real-time to get the rotations and scaling you see in the game. Java does things a bit differently (uh oh). You have to use ByteBuffers instead of arrays, and there's no sensible way to cast different portions of them to different types - vital if you're interleaving colours and vertex information. I wouldn't mind if ByteBuffer manipulations were fast, but they really, really aren't. Another 'wrong'.

The Slow Dance
Despite the various hiccups and a nagging feeling that this wasn't as much fun as it should be, I got all my lovely, complex, multi-layered, articulated sprite code working today. I tapped the screen a couple of times causing Fat Chick's cheery little face to appear on the screen.

By the time the game had 20 sprites on-screen it had slowed to a crawl. If you wiggled the roller-ball on the phone it ran at half of even that glacial framerate. In response I looked around once more to see if there was anything I should be doing (or not doing) that would help speed things up a bit.

After a search, the main advice seemed to be to change all my maths into fixed point. Fixed point? I've not used that since 1995! How retro does your hardware have to be to rely on the veritable 'Stonehenge' of game engineering? Big 'wrong'.

(Jack has now seized the axe and is telling all present that 'Johnny' is in the building.)

The other advice was to rewrite a majority of my code in C and compile it, along with all the android OS in a Ubuntu virtual machine or Cygwin. Yuck. As of two days ago there's better support for openGL in the NDK, but still.

Take a look at this. It's the final, capitalised Wrong to end all 'wrong-kind'. Debugging native (i.e. workably fast code) makes Lost's plot look straightforward.

(We've now seen the man in the bear suit, Jack has chased Danny around the maze, Halloran is dead and the titles have begun their roll. Oh, and Wendy screamed and cried a lot, looking much like a novelty bottle-opener with eyes.)

The Final Straw
I started Fluttermind to have fun and experiment with gameplay and graphics, not sit staring at a screen of hex for a day trying to figure out why a @&%£ing cloud isn't rendering properly.

There's no pithy afterward, I'm afraid. Eclipse/Google/Android and I part company today. It's the supermodel that turns out to be a hose-beast. It's the British Mars-probe that crashes due to a measurement error. It's the 'Avatar' that turns out to be 'Dances-with-Smurfs'.

Farewell Android. As I wander off into the distance I have absolutely no fear that you might follow me. Even at my pace you have no hope of catching up.