I feel that software design and architecture tends to get overlooked in video games. Developers tend to focus more on the art, gameplay, character, and other creative aspects rather code design and architecture. I don’t blame them, because like movies it’s the direction that ultimately win over the audiences. My experiences as an software engineer have taught me that good design and architecture benefits your project the larger it grows. For indie developers that turnover small projects in short periods of time may not see the apparent benefits that clearly, which is probably another reason why this topic gets overlooked. But as good developers we should always strive to design and write the best code we can regardless of the scale. That’s what a professional should do, and that’s the principle I uphold as a software engineer.
With my lastest work in progress game Trap Labs now on Greenlight, I figured it’s a good time to share with the world about the software design and architecture that went into building this game. Code has a fundamental level of certainty in its design and architecture. Regardless of whether you are making a video game, a productivity app, or an embedded driver, the underlying design principles and architectures for software are all similar. The goal of the series is to educate the reader on how to go about design and architech software, more specifically video games.
Trap Labs is a cross-platform online multiplayer platformer. It uses a somewhat top-down/isometric perspective like StarCraft. The play style varies depending on the map you are playing. Common examples include classic platforming, co-op, puzzles, rhythm/music, survival, and races/speed runs. The game was inspired by StarCraft 1’s custom bound maps where you dodge rhythm based explosions.
Game technical features:
I worked on Trap Labs for a little over a year. As of Feb 9th 2017, the game’s production code is about 34k lines long written in C++, and is accompanied by another 12k lines of code in unit tests. It’s a small project, very lightweight, scalable, portable and very feature rich.
The series is broken into multiple parts that will more or less cover the entire feature set. I will upload the parts as I finish them over coming weeks, and I hope to continue this series in the future as I make additions to this game.
It should be clear that my articles are design and architecture heavy rather than implementation heavy. I also like to stress unit tests so beware those who don't write tests!
It is also useful if you are already aware of basic OO principles (like SOLID) and practices like TDD. But they are not required to understand this series. My code snippets are usually also accompanied by unit tests. If you don't know what unit tests are you should take a look at my code to understand what they do.
The downfall of using any video game engine or framework is that you immediately lose control over the architecture of your code. I show you how to regain control and invert the dependency. Consider this prerequisite knowledge to understand rest of the series, thus 0-indexed.
I go over the fundamentals on how to go about structuring your game modules. Trap Labs has 7 libraries and 2 executables that makes up the client and server. I explain why they are structured that way, and how they integrate with each other.
I layout some secret sauce on making a game that uses importable/exportable maps.
A small yet powerful standalone library that serves as the underlying command system of the entire Trap Labs game engine. I go over command management, scheduling, delegation, and execution.
The prized library that handles all in-game mechanics. I will go over how physics simulations works from client and server’s perspective, the event system, player and map element management. How do you write a game engine that is 100% unit testable? This is how. This part is broken into 4 subparts.
Part 4.1 - Why write a game engine?
Part 4.2 - State based animation and how to test animation logic
Part 4.3 - Client and authoritative server model
Part 4.4 - Extensible components of Trap Labs
The networking engine is a lightweight general purpose multithreaded asynchronous networking engine that is protocol agnostic, game agnostic, and handles network congestion, reliability, order, and has a simple firewall. Consider this a tribute and addendum to Gaffer On Games' networking series.
Just note that this is certainly not the end all be all design and architecture for video games. You game may be vastly different from mine. What I will show you are the principles and design patterns that drives the code forward. You may use the same principles and end up somewhere completely different.
This page was last updated 4/15/2018