This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.
3. Graphics pipeline
Having an experienced art director who is fluent in 3dsMax, we wanted to avoid the tendency of most iPhone startups to switch to some less expensive alternative. We found a Collada2Max exporter that gave us an XML .dae file. We then wrote our own preprocessing program as a native Mac application to convert the model's verts, normals, and texture coordinates to const arrays and a model3d struct.
We were pleasantly surprised how easy it was to write a native Mac program in C using XCode. Installing a new model in the game is as simple as including (#import) the header file and then referring to the model by its name.
4. Level design
After getting the proof of concept with a completely playable level of the game up and running we made a simple level creator function. After making a few sample levels on our own, we let our QA Lead, who is studying to become a game developer, lay out most of the thirty levels in the game.
Once she gave us a file, we would build the game and send it back to her to test. Neither she nor our art director were using Macs so we had to provision their devices so they could drag the latest build onto iTunes and then sync to see it running.
The quick feedback they get by being able to run it on their own iPhone contributed to the quick turn around we got on fixing any problems they noticed.
5. The final countdown
At the end of any project in the game industry you expect there to be a bit of a crunch time. We entered crunch time with more problems that you would want and more unfinished game code than you would expect. Part of this is because shooting for the iPad release was a last-minute decision.
But even with all that standing in our way, we still managed to post the build onto Apple's website just in time to make the launch of the iPad store. Most of it just boiled down to hard work and long hours, but in the end we would not have made it in time if it weren't for two things: luck and fresh eyes.
Right as we were going into crunch mode, we brought in another experienced programmer and he seemed to catch everything that went through the cracks and gave us that little boost to get over the last bit of the hump. It's important to have an extra set of trained eyes to question and challenge how and why things were coded a certain way. It makes everyone really think about the best way to get something done.
1. Ball rolling
You would think that having a ball roll on a surface would be a trivial problem. It was fine along all four walls of the room, but once we started testing it diagonally it started wobbling annoyingly.
After a lot of Googling, checking reference books, and experimenting with various calls using OpenGL's glRotatef function, we realized we needed to rotate the ball in both the X and Y axes at the same time. (Z points up in our world.)
We had to load an identity matrix, rotate it on the X and Y axes the amount we needed to roll diagonally for that frame, and then save the matrix. Then we had to multiply the current cumulative ball rotation matrix times the newly calculated recent move matrix.
2. Graphic corruption problem
We started noticing the ball corrupted, as if the triangles that made up the sphere had come unattached on one or two points. We accidentally discovered that it corrupted only the first model in the draw list, so we took the expedient way out and left an unused model at the beginning of the list -- not our proudest moment, but something you do to make it work until you can figure out what is actually causing the problem.
As the code got more complicated, it took a larger and multiple models to keep it from corrupting the ball. We finally put our rendering code under a microscope, caught some coding problems, and switched to using const arrays in our graphics header files.
Having worked on cartridge games, we were used to having large amounts of graphics data that remains in the ROM where a pointer simply references it.
Our new programmer questioned whether the iPhone was trying to move large amounts of data onto the stack. As a const it will stay in one place.