Monthly Archives: May 2013

iOS: A Three Year App Development Odyssey

I have spent three years of spare time to create a single App. Upon reflection this seems more than a little crazy until I remind myself that the goal was not so much to get the App out into the world but to teach myself about iOS game development from “soup to nuts”. It was very satisfying to be completely curiosity driven.  This was a complete departure from the ruthless pragmatism that informs the way I code in my day job.

The catalyst was the fact that in my day job I had taken on the role of leading R&D in a start-up. The dev team knew what they were doing and what the company really needed me to do was articulate our vision to customers and analysts. As a result I found I had traded in Eclipse for Powerpoint and Word. After a while I found that I really missed the kind of problem solving that comes with developing software. At the time iOS was really hot and a hobby project in this area seemed like a good idea (admittedly, not an original thought).

When I get a blank sheet of paper I generally do something relating to physics. I had the great fortune to evolve from an undergrad in engineering into graduate degrees in physics. I had nearly gone into physics instead of engineering as an undergrad but I was wisely counselled that engineering had a much better chance of paying the bills – unless I was sure I could be at the top of the class. Good advice – and apart from a sojourn in graduate school my software skills have been how I pay the bills. When Java first came out, during my PhD in general relativity, I created applets that showed orbits in a variety of different forces. It seemed natural to try and link iOS and gravity in some way.

The journey started with something not too different from the old Java code from long ago. I got some basic iPhone code running with Quartz graphics added a bit of touch interaction and simple gravity evolution. It was ok but seemed a bit uninspired. At the time there were people in the startup doing graphics stuff. They kept talking about shaders and GPU code and I was curious about their world. I also thought it would be cool to make the gravity simulation do proper 3D. At this point I probably had invested about five months in iOS to get the Quartz game going. I decided to press reset and start again in OpenGL.

Getting OpenGL up and running was a BIG deal and caused at least a six month hit. It takes a while to have the right mental model of what is really going on in the shaders and without a graphics debugger using only newbie knowledge I ended up doing a huge amount of experimenting. The resource I used at the time was a book iPhone 3D Programming. This was a good introduction to OpenGL ES and I went between it and the Blue Book. I was able to get some reasonable 3D stuff going. I did find the C++ cross-platform framework in the iPhone book a bit unsatisfying. After all I was also trying to get some chops in Objective-C. However, I had running code and started to work on the touch interface and game flow.

During this time, in my day job, I had realized I just did not have the temperament to pitch for a startup and wave the flag day after day. I found a senior software role in a mature company and started to wade through their code. It is hard to adequately convey how bad this code was. As a consequence I started to read about dealing with bad code and started to take Clean Code seriously. This had repercussions in N-body. Since I could not have clean code “at the office” I tried extra hard to keep N-body clean. This resulted in some significant refactoring in N-body.

Then iOS5 came out. It had GLKit routines for math and utility routines for texture loading at a time when I was just starting to realize the values of texture atlases. Again, I rushed towards the shinny new thing and refactored out all the C++ code making some structural improvements along the way. I found it very useful to revisit design patterns in the context of Objective-C. The structure of a language and it’s libraries often informs the style in which common problems get solved. I found Cocoa Design Patterns a big help in getting into the flow of Objective-C coding. Another big bonus was a colleague who had a long history in MacOS development and was generous with his time. I also used this opportunity to go all the way to the bottom in OpenGL. Since I had no strict self-imposed deadline I messed around with how vertices were generated, how the lighting in the shaders work, normal maps for texture simulation, how to map strings into textures into transparent objects, and on and on. (Once iOS6 came along the Xcode OpenGL debugging became much easier. That feature in Xcode is hugely powerful).

In parallel with this I was working through Solar System Dynamics and became entranced with the weird tadpole and horseshoe orbits that occur as bodies oscillate about Lagrange points. I really wanted to show these orbits in the co-rotating frame and find a way to interactively generate some intuition about how variations in starting conditions affect the orbit. This added more time to the development. Then I stumbled into the choreography orbits. These were amazing but didn’t quite hang in there with the integrator I had in my physics engine. This sent me on a detour to learn more about choreographies and change the physics engine to do fourth-order Runge-Kutta evolution.

Finally, it seemed like a good idea to have built-in autoplay for all the levels – so I could regress after making changes to the integrator. This took a further investment in time but one which on reflection was time well spent. I found a number of issues during these regression tests.

Then it was time to polish. This is a challenge for me. I have a half dozen other cool physics game ideas and a shelf of unread books. Somehow I managed to stay focused and get N-body done to a level that I felt I could stand behind. There are things I wish were better, levels I wished I had time to add but I forced myself to just record all the diversionary ideas and after two and half years stop wandering off and stop the feature creep.

Finally, I started beta testing (using TestFlightApp as recommended by a friend – it’s awesome). Bugs were found, discussion on the merits of what the app was and wasn’t were had. After some reworking and a bunch more polish I deemed it was ready to submit.

Okay, I think I get where the three years went.

Hunting Zebras in Outer Space

I once took a graduate course: ”Physiology of Excitable Cells I” run by an eccentric British professor who wanted to teach in a far-reaching classical sense. (In the first class on hearing my surname he commanded ”Next week you will tell the class the connection between your name and Sherlock Holmes”; perhaps a bit off-topic given the course title). One thing he said that has stayed with me is that common problems have common solutions. He was discussing how all the medical students he taught were quick to assume a patient had a rare condition, instead of something more mundane. The tag line they teach medical students is:

“When you hear the sound of hooves, think of horses not zebras”.

I use this phrase a lot when it comes to debugging issues in software. It’s far too easy to believe I am the victim of some fiendishly clever interaction in my system or (so help me) a compiler bug. The answer is (to first order) always that I have done something very dumb or just failed to see an edge case. After a long time writing code I am a lot less likely to get caught by this. However, it did happen to me with N-Body and I was so amazed at how dumb I had been I had to close the laptop and go for walk.

The issue related to the use of sprites for a collision. They seemed to work pretty well except on a level where I had a number of other masses moving around. The latent trap was that I felt guilty about the quick way I had pushed sprites into the code. I decided not to worry too much about optimizing them and allocated a sprite group on the fly. I know it’s better to pre-allocate a sprite pool and all that – but at the time I added them my main focus was elsewhere and I knew I would have to come back and clean them up.

So when I hit an issue where collisions on a busy level resulted in a serious pause in the game loop – I decided the time had come to finally put in sprite pools. That HAD to be the source of the issue. Off I went, with the added fun of feature creep in the refactoring. All in all I spent about ten hours. It made no difference.

The real issue showed itself when I was doing the feature creep part of the refactoring. The loop nesting was wrong and I was running the sprite evolution inside a loop that was running over each body in a level. When there were five masses, I evolved the sprites five times per clock tick and things got really slow. Instead of looking hard for a simple error I had jumped to the conclusion that it must be due memory inefficiency and my use of on-the-fly allocations. Doh! I was amazed I had gone on such a long Zebra hunt.

I have used the Zebra hunting metaphor for such a long time that sometimes I now use it without setting the context properly. I was working with our very bright overseas team in India but thought that this time they were on the wrong track, chasing a theory that seemed too intricate. When my manager asked me how they were making out I responded ”Oh, I think they’re off Zebra hunting”. He replied ”Really?! Do they have a holiday or something?”. I then explained my metaphor as well as the fact that India does not have Zebras…