Island War Day 5
Last time, I wrote about how I set sail for the Island War project and how my motivation faltered slowly over time. And I promised to write a follow-up post that explains how I believe to get back on track and finish development of my Island War project. Well, here it is, folks!
I see the primary reason for my loss of motivation in my tendency to write and fully implement systems instead of just the piece of code I need. While I knew that I had to “write a game, not an engine”, I still fell for the same old trap: I didn’t technically write an engine, but I started to design entire systems and fully implement them when all I needed was a small routine to get the job done.
Ultimately, I attempted to create my island war world as a closed library which automatically handled everything the game does and provided a nice API to the user. This is a reasonable goal, but I approached it with a holistic integration attitude – I tried to just write it an then test it from the outside. And with all the attention to detail the perfectionist in me needed to be satisfied.
Complexity explosion resulted. Take this: when a missile hits the ground, for example, the height map can be deformed. This would automatically trigger an event that notified the terrain renderer to recalculate normals for the affected region and to do a minimal update to its vertex buffer. The same event would notify the building manager to check the ground near buildings. It the ground became to uneven, the buildings on it would automatically be destroyed.
This is not a bad approach at all, but you can’t keep all this in your head if you design it as a whole. Don’t misunderstand me, my classes were modular and not interdependent on each other, but I tried to mentally map the interactions of the whole thing when glued together and get it right on the first try.
So the problem was that, each time I tried to continue work on my project, I first had to recall everything the system does to even know how it’s supposed to behave. This became a huge wall I had to climb each time I sat down to write some code. And soon, XNA 2.0 had come, and gone again, and XNA 3.0 was here (yep, I actually began this when XNA 1.0 Refresh was just released).
The New Approach
The cure for my perfectionist system architect mentality seems to be Test-Driven Development. Instead of working out the whole complicated interaction of the system at once, I use unit testing to ensure the building blocks do exactly what they’re supposed to.
And whenever I add something new, I begin by deciding what exactly I require (instead of how the new requirement could be turned into a system that does the job for me) and begin by creating a test for it. My code is still modular, reusable and doesn’t form huge dependency chains, but it’s down-to-the-purpose and not systems upon systems interacting with each other to form the game.
In other words, when I need power in my house, I now build myself a diesel generator instead of designing a nuclear power plant :)
I’ll keep you updated on how my test-driven approach to game creation works out!