I actually wrote some new code for Gratuitous Space Battles today, and in doing so, I had to do a bit of chin-stroking and thinking about the general code structure of the game. GSB is not my latest game, so the code I write now for new stuff is more polished and better designed, but even so, I’ve coded about a dozen games from scratch before GSB, so it should be fairly good.
..and yet…
One of the best lessons you learn, mostly from experience, is how to arrange classes and objects in your code so that its fairly modular and not ‘closely-coupled’. In C++, what this amounts to is you shouldn’t have a lot of classes constantly using get() and set() calls to talk to the private members of other classes. Separate objects and basically separate for a reason. The hardest decisions to make in code are the big architectural decisions about what objects sit inside others, and who inherits from what. I’ve been coding in C++ for decades now, and I still know I often get it wrong. This stuff is really important.
For example, there is a class is GSB called SIM_Ship, which contains all the gameplay related stuff for a ship (totally separate from the visual representation of the ship which is entirely different and in a totally separate class). In an ideal world, that ship class would be pretty self-contained, without a ton of connections to other objects.
The problem is, over time, I’ve ended up adding stuff to that class that bloats it and makes the code messy. For example, it has a function in there to shake off limpet mines. This is a bad idea. The limpet mine code should all be within SIM_LimpetMine. SIM_Ship not only shouldn’t get involved with the limpet code directly, it shouldn’t even be aware that the concept of a limpet mine exists. That stuff should be modular, residing elsewhere and making use of generic functions and hooks within the ship code from a distance…
Sometimes that doesn’t work in practice because of optimisation and speed considerations, but often, the reason stuff ends up in the wrong place and the code gets confused and messy is that the coder is just adding ‘one more thing’ and doesn’t think its worth going to the trouble right now…
But when you are starting a big new project, its good to keep these issues in mind. Assume you will have 5x the code you think you will have, and then plan the code architecture accordingly.