Solanus is a simulation/action game based around a zombie outbreak. The player controls a nameless character in a sea of other NPCs. Soon after the player starts playing, one of the NPCs becomes infected with a virus turning that NPC into a zombie. As the zombie seeks out and attacks other NPCs, it turns more NPCs into zombies. As time goes on the virus continues to spread until there are less and less humans. The player’s goal is to make their way through the story and make it out alive.
Solanus was developed by a team of 5 people over about a 4 month period of time, half of which was dedicated solely to creating the engine. The game was written in C++ using DirectX 9 for rendering and FMOD for audio. The game uses a static octree and culling in order to improve rendering performance. 3D audio is used for all sounds in the game except UI sounds and music. Lua was integrated into the engine and is used for dialog trees and quests and supports branching dialog and quests. A custom memory allocator was created for dynamic allocations; The allocator is a heap based allocator and runs a garbage collection pass from time to time to compress the allocated memory and remove areas of free space between each allocation still in use. The engine also has a map of ‘cells’ which are created by splitting the game world into a series of squares; NPCs are put into these cells and move between them as they update. Whenever collision is tested (both with bullets and attacking zombies) only things within the same and very close cells are tested. This allows us to keep performance acceptable on things like collision checks and is also used to allow us to stagger updating AI as we can easily see what NPCs are in view of the camera.
Quests are the primary driving force for the flow of gameplay in Solanus; There is a main quest script that starts when a new game is started and scripting is in control of everything from there. Quests are capable of infecting NPCs, giving the player weapons, adding objective points to the map, and more. The objective of the game is to get through the main quest until you are able to get off the island to safety. Dialog is also controlled via scripting and can include random elements, branching paths and more.
Zombies are the main source of conflict in Solanus (and also where the name of the game comes from). At a scripted point during the game’s main quest a random NPC is infected and turned into a zombie. From there the zombie starts seeking out the nearest un-infected NPC and attacks them. Once that NPC has been killed they also turn into a zombie. This continues on until there are no NPCs left. Because NPCs are updated even when they are off-screen the zombie infection tends to have a realistic and interesting spread throughout the city. You can leave an area that contains only a couple zombies and come back to find that a few blocks around that area have become infected. NPCs are never added/removed from the game unless the player kills a zombie; All NPCs in the game world exist as soon as the player starts a new game.
The city in Solanus is randomly generated each time a new game is started. There are rules that cause the map to have similarities every game: one corner of the map is always the harbor, the center of the map always contains a ‘park’, there are a couple of specific builds that always spawn. However, other than a couple of fixed rules, the city is generated at random. Roads are placed to form grids, walls are added around the outside of the map, specific builds are populated along the roads, then random builds fill the rest of the map. While the city generation is not terribly unique each time, it does provide a slightly different experience each play through (even with a fixed quest line).
The AI in Solanus is pretty basic all things said; The original plan was to include much more complicated AI but due to time constraints the design of the game had to be scaled way back. However, even though the existing AI consists mostly of wandering NPCs and wandering/seeking zombies there are some interesting systems in place that allow everything to work. The map in the game is split into a series of cells; Each NPC tracks what cell it’s in and moves between them as they move around the map. When updating the game world we check which of these cells is in view of the player’s camera; Any entities inside of the cells we can see are always updated. This way any on-screen NPCs are updated every frame and move smoothly. After we have finished processing most of the logic for a frame, we take the remaining frame time we have (to maintain 60 FPS) and update NPCs in the cells not visible to the player. This is what allows the zombie outbreak in Solanus to seem realistic and spread around areas as the player would expect. Even if there is only one zombie on the opposite side of the map the infection will still spread because NPCs in the area are still getting updated, even if not every frame.