Nevertheless, I did succeed in making a fun racing game. Hopefully this postmortem will shed some light on the development process, what went right and what went wrong.
Tools
I used many tools to create BitRacer. For programming I used Xcode to program Objective-C, C++ and Python, making use of FTGL, FreeType, ODE, and OpenAL. To create the user interface I used Interface Builder. To create the 3D graphics I used Blender and Wings3D. To create the 2D graphics I used my own drawing program, as yet unnamed. To edit sounds I used Cacophony by Richard Bannister.
What Went Right
Polish
One of my aims was to make BitRacer immediately and easily playable, and I think I achieved what I set out to do. I used most of the last week of development time during uDevGames to work on the polish of my game. That is, the menus, options, help files and all that is peripheral to the gameplay. Spending this time on polish was a good decision, for polishing a game takes longer than you think. Now, having done so, I can really appreciate the difference it makes.
You never fully realize how important polish is until it is done. Often it seems inefficient to waste time on menus or help files, when you could spend valuable time on gameplay. Especially when you realize that polish takes far longer and it is not so fun. Yet when people play your game, few bother to read the read-me, or check the help, they just play it. If it doesn’t work or is unintuitive, they don’t have time.
An unpolished game will, simply by virtue of being unpolished, score lower when users rate it in all the other categories, and visa-versa. The link is stark when you look at the uDevGames 2003 results; the top three best overall games are identical to the top three games for polish. In identical order! Possibly it is the way in which people rate games in terms of irritation instead of enjoyment.
UI and IB
A more technical aspect of polish: Apple has a superb Interface Builder (IB) that is very easy to use. Every Cocoa programmer will use it for almost all aspects of their interfaces. But it is limited to the rather un-gamelike blue of Aqua.
One of the best technical ideas in BitRacer was the use of IB to create my interface using OpenGL. In Quartz Apple has a superbly powerful compositing engine, and it allows a developer to simply interweave OpenGL contexts, pictures and standard user interface controls. I used this to allow me to graphically put together my interfaces whilst also using OpenGL to provide a classier look and feel.
SCREENSHOT HERE
In the screen-shot above you can see how I used graphics and text as standard Cocoa objects, while at the same time using my own OpenGL menu items. I used the tool-tip field in Interface Builder to create text, buttons, checkboxes and radio buttons.
Retro Graphics
Or just half-baked graphics? Indeed, I was both criticized and applauded for my graphics. Unfortunately, I could not avoid the use of cuboids due to the physics, and so I spent many hours racking my brain, asking myself “How can you make a bunch of plain cubes look good?” I did not initially want to use retro graphics, however they were a good solution. Looking back, I now like them much more, the solid color against the dark background is a striking and different look. I like the way it gives BitRacer a distinguishable look, and their Tron-eqsue feel.
The Blender Track Editor
Initially I created levels that hard-coded into the code, but after that became implausible I used a text data file. However, neither of these methods came close to providing the ability to create decent 3D tracks. Again I was constrained by the physics. Instead of being able to use a 3D program to create sweeping curves, banks and rolls, I had to use imagination to create fun levels out of cuboids. No 3D program was going to let me export a list of cubes, who wants to model with cubes, right?
Fortunately I knew about Blender, a powerful free 3D program. One of Blender’s many attributes is its use of Python to allow scripts to access and alter its scenes and objects. I could use a script to output my cuboid information based on the objects in Blender. After hacking around I was able to use Blender to create 3D tracks out of cubes. I could now create and edit tracks in 3D, and using more of Blender’s abilities, I was able to position a tree of waypoints and checkpoints for the AI to race around.
What Went Wrong
ODE (Open Dynamics Engine)
Physics is extremely hard to get right. I have written my own physics engines, notably the one behind SillyBalls. For BitRacer I decided it would be better to use a “real” physics engine, for which the only genuine option for free use on the Mac is ODE.
Using ODE and creating physics took up a vast amount of time whist working on BitRacer. The myriad of interdependent variables and options are extremely confusing. For example, I would change the geometry slightly and the steering would also change!
That aside, ODE worked great, except that it provides few robust collision primitives. This meant that although I could construct objects from arbitrary meshes, the collisions with the meshes were very temperamental. Cuboids were the sole useful collision primitive that I could successfully get to work, the result of which is my use of only cuboids. I did not foresee this constraint—initially putting together ODE was deceptively easy.
Unfortunately this constraint molded almost every aspect of the game. It forced me to think of alternative solutions, like using Blender for generating tracks or a Tron like look. While these solutions weren’t necessarily bad they were very time consuming.
The racer is a good example of the problems I had from using ODE. Many people complained that it stuck on walls or bounced oddly. Above you can see what the racer really looks like for collisions.
Bug Testing
I own a dual PowerMac G4 450MHz computer, and had assumed this would be a good baseline; “If it works well for me then it should work well for everyone else,” was what I thought. Of course my clever use of multithreading and buffered physics worked beautifully, for me.
It wasn’t until I tested it on the last day of the competition that I realized my folly. Single processor machines had thread timing issues—BitRacer would run like treacle because the physics thread was starved of CPU processing. I then scrambled for the next three days into the voting period to make it playable even on a single PowerMac G5 2GHz. Oh foolish me, to ever underestimate the need for testing.
Distractions
Ah yes. The weeks off doing this or that, having to spend most of my time at work. Oh the wasted time, I should have spent every waking moment working on BitRacer!
Conclusion
There are many things done and many more things remaining. After the intensity of uDevGames, like most entrants, it is time for a break. I am very happy with how BitRacer turned out; leaving it as a learning resource makes it worthwhile as is.
However, excluding the ever-present possibility of BitRacer 2, I am planning to make at least a multiplayer update to BitRacer, with hopefully LAN play. I realize, yet again, that these are big goals, but it would be fun.
- Genre:
- Developer:
- Url:
- Team size: 1
- Released date:
- Project length:
- Development hardware:
- Critical applications:
Bio
Will Thimbleby has been writing Mac games since Tracktor Beam. Since then he was a runner up in uDevGames 2001 with SillyBalls. In real life he is a PhD student working on fancy calculators, and programs MacSword, a bible study program, in his spare time.