Third person action/horror game.
14 weeks half time in a team of multiple disciplines.
Made in inhouse engine Monostein (C++/DX11).
Written in C++ using an entity component system and custom navmesh export from Unity.
Wwise integration with desktop client.
Alpha stage with player to the left and a worker bot in the center.
This game was a school project at The Game Assembly, Malmö. It took us 14 weeks to develop at half time and was written in our own engine, Monostein (using C++ and DirectX 11). We used the Scrum framework to coordinate the team. On the game side, we used the entity component system EnTT to make the design more data-driven and the performance (hopefully) better.
I was mostly responsible for the AI, player interactions (such as items, reloading etc.), audio programming and design and export of the level from Unity to Monostein. I also composed all music in the game using Cubase and hooked up animations for the worker bot.
Audio: Since I used FMOD in our previous project, I integrated Wwise to handle all sound for this game instead. It was very interesting to work with and when I set it up with the Wwise desktop client we could design the sound without having to alter the individual sound files or add new code for each sound. When everything was set up, I worked both as a sound designer and an audio programmer which gave me great insight into how Wwise works internally.
Pathfinding: For the pathfinding I ported an implementation of the A* - algorithm from a previous project. We created our navmeshes in Unity and these was then exported from Unity to our engine using a custom navmesh-format. We did this because we found the original format to contain too much unnecessary data. This meant that we had to write code to iterate over the navmesh nodes and set the neighbours of the faces on our own. This was very time consuming to implement and in the end, probably wasn't quite worth it. Though for educational reasons, it provided me with a lot of insight in how Unity creates and handles navmeshes and how we can use that information.
Enemy AI: I implemented a Finite State Machine for the enemies with general transitions, conditions and actions. An action contains logic for that action, such as attacking, pursuing or fleeing etc. Transitions is a generic class where actions can be added. This is great if we want to trigger an animation change for instance. Each update, all transitions are checked based on their set of conditions. A condition is a simple function that is added to a transition as a function pointer to save memory. It's designed to be as data-oriented as possible with simple functions without any saved data. This works very well with the entity component system we are using: EnTT, since it's already very data-oriented with systems interacting with components where the actual data exists.
To the left is the code of the Transitions in the Finite State Machine. It simply contains a container for its actions and a container for its conditions. The Finite State Machine uses these transitions to check if it's time to change the current state by checking the conditions of each of its transitions.
To the left is the code of how we create some logic for a drone bot. Yes, it has data on the heap but on the other hand, this is the only tree used for all the drones. This allowed things to be very consistent and very easy to work with. To add a new behaviour simply required us to add the logic of that new state and then hook up which conditions and transitions we wanted. This also worked very well with how we had set up the animations system, which also contained transitions, transitions times and conditions.
Wwise implementation to the left. This is set up in a separate project called SoundEngine which is completely decoupled from the game project. The only way for the game project to communicate with the sound engine is through a lightweight interface in Game called SoundManager. This allows us to easily port it to another game in the future since the game objects within Wwise are completely oblivious to our game objects in the game.
Audio: Martin Mossberg