Spite: Drowned Souls

  • 3D hack-and-slash RPG.

  • 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.

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 export of assets/levels between Unity and Monostein, audio programming and design, the pathfinding and the enemy AI. I also composed all music in the game using Cubase.

  • Export: Since we used EnTT, we only had to create a ton of lightweight components which then could be applied to entities. Components should only contain data and in turn, different kinds of systems utilize this data. For instance we had a "Gun"-component which contained all information about the gun such as state and ammo status. A "GunUser"-system then updated all guns in the scene regardless of which entity they were on. This made the flow much more data-driven and faster. It also made it easier for the level designers to add and remove components on the fly in Unity which were then exported as binary files to the engine. The level designers were very satisfied with this workflow and we decided to keep it.

  • Audio: I integrated FMOD to handle all sound in the game. This was my first time attempting to use a separate API for the sound and I learned many useful lessons about how to integrate different projects and libraries. I made the sound engine as decoupled from the project as possible in order for it to be used easily in a future project. The "Game"-side had a simple interface which was the only class allowed to communicate with the sound engine itself.

  • Pathfinding: For the pathfinding I implemented the A* - algorithm. 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.

When the navmesh was loaded and working, I implemented the Simple Stupid Funnel Algorithm, which turned out to be very hard to make work with our data. I spent a lot of hours on this because it was very hard to properly debug the stages of the funneling.

  • Enemy AI: For the AI we created a basic Decision Tree which turned out to be enough for our purposes since we had a proper pathfinding system that made the NPC:s look realistic enough. Different types of enemies had different behaviours and made different decisions depending on what kind of weaponry they had or which abilities they were able to use at a given traversal of their Decision Tree.

The funnel algorithm. I had a lot of problems trying to find the left and right nodes in the algorithm. At first I did it using memory alignment (each triangle SHOULD be exported in clockwise fashion) but when something still was off, I started to use some linear algebra in order to find these nodes based on the dot product. This worked much better.

In these GIFs, the user clicks on a point and then the player finds a path to that location using A* + Simple Stupid Funnel Algorithm. As can be seen, the player model rotation snaps without any smoothing. This was due to lack of time during development and we chose not to implement that since the player most of the time rotates based on where the mouse is when holding down the LMB.

Team: Spelbryggeriet

Programmers: Casper Mårtensson | Casper Stein | Fabian Haglund | Jens Berg | Johan Wikstrom | Martin Mossberg

Level Designers: Gabriel Hector | Robin Jansson

Artists: Albin Canbäck | Ellen Johnson | Sanna Friberg | Sara Fjellstadt

Animators: August Wahlberg | Carolina Buskas | Erik Billgren

Technical Artists: Hugo Bonnevier | Isac Stahl | Sebastian Nemeth

Audio: Martin Mossberg