When we finished our prototype for TMJ (That’s My Jellybean!) during our second year of University, we left it to rest in Dropbox for a couple years until after we started up Questionable Quality. After deciding to go back to working on TMJ we realised that we made a technical train wreck when coding the prototype. This was all because of a mix of us being lazy students, with no time management skills, and having no forethought as to potential issues that could arise.
The past few years away from TMJ have made us somewhat wiser and more experienced developers (maybe?) so starting development on a game that needs to be releasable means we need to take into account a few things with our coding to make it ‘production level’.
What We Needed
So we essentially had a meeting to lay out what we need from our game architecture:
- We want any design changes we make to be a quick and easy. That means making turret and enemy stats easy for anyone to edit.
- The code needs to be in distinct pieces so we can easily plug in functionality when we need it.
- TMJ is a tower defence game with a lot of real-time counters and ‘Improvs’ that change the mechanics of the game on the fly. That means we need a system that won’t catastrophically fail if one thing bugs out.
- Games are one of the buggiest programs a developer can make. So we might as well try incorporate robust design into the architecture so we don’t tempt fate.
- Being a new company, we need to start setting up a code-base and a couple reusable tools. We need to make the code easy to split up into generic parts that will allow us to reuse as much code as possible when making a new game.
- Making code reusable saves time in the long run as any feature that shares functionality is already effectively done.
How Its Designed
After quite a bit of research and reading I opted to use the architecture found in ‘Game Coding Complete: Fourth Edition’ by Mike McShaffry and David Graham(I highly recommend this book for anyone into developing games), which is based on the Model-View-Controller pattern. The book assumes we are working in C++, and have to deal with a lot of Application logic, but thankfully we are working in Unity, which takes care of 90% of those headaches.
The main idea of the architecture is to split out Application logic, Game logic, and View logic into separate parts of the architecture.
- Application Logic
- This part of the game takes care of interaction with the Operating System and the hardware such as hardware inputs/outputs, application initialisation, and shutdown.
- Game Logic
- This is where most of the logic will go that informs how the game works. Such as state machines, score counters, physics code.
- View Logic
- This is where all the interaction with the players and Artificial Intelligence (AI) occurs. This includes the obvious such as animation, and visual changes; but also includes converting player button presses into commands readable by the game logic, and simulating the AI.
A very significant aspect of this architecture is the concept of Processes. These are discrete pieces of functionality that have a well-defined beginning and end, and can be daisy-chained with other processes to form more complicated functionality. An example would be a ‘Move’ process which is in charge of moving an object and a ‘Die’ process which destroys an object. These two processes could be combined to make an object move to a position and then immediately die. A big advantage of Processes is that you create encapsulated code that can be reused in a lot of places.
Another great aspect of this architecture is the Command Interpreter, which takes in commands from the user or AI and calls relevant functions such as “Fire Turret 1” or “Create Enemy 2 at row 4”. This command interface can be used to create a custom ‘language’ for the game, which would allow a developer to create a console so at runtime they could manually create turrets, create enemies, fire turrets, etc. This is the kind of thing you see in a bunch of PC games with a console like The Sims or Skyrim.[/vc_column_text][/vc_column][vc_column width=”1/6″][/vc_column][/vc_row]