TGA Project 5
Spite: Oathbound
About
As a shieldmaiden, slash and strike your way through your draugr-infested hometown, taking on the role of a valkyrie to save the World Tree.
Info
Engine: Frostheim (Teams in-house C++ engine)
Export Tool: Unreal Engine used as a level exporter.
Duration: 14 Weeks (20h/week)
Team Size: 19 + (2 sound designers)
Itch
Coming Soon!
Contributions
Landscape Implementation
Early on during production i joined a taskforce in order to implement landscapes which led to cooperate with two graphical artists, all level designers and one technical artist. One of the first things I was worried about with the landscape was the amount of textures needed as well as the amount of vertices of the mesh, hence I came with the suggestion of max three material layers per landscape.
The first big problem was creating a pipeline for the terrain from Unreal Engine to our own engine. When deciding upon how to best construct the pipeline I was in close contact with our level designers to create a pipeline that worked for them. We decided upon a data driven approach where terrain data was specified through a JSON file per level.
Once a terrain mesh could be loaded the next struggle was to assigning the correct texture data to the pixel shader made by the technical artist. A combination of faults in the shader and the incorrect information being sent to the GPU resulted in the materials covering the entire landscape based on the camera. This was quickly amended which resulted in the landscapes rendering correctly.

Initial landscape material test
Showcasing the graphics engines different render passes
Graphics Engine
At the very start of the project, during pre production, we made a decision upon whos graphics engine we’d use and came to the conclusion that mine was the most production-ready overall. The graphics engine up until this point had been developed as a part of the TGP, short for applied graphics programming, course.
One aspect to why I think we went with my graphics engine was because I developed it with modularity in mind so that it was decoupled from the original project’s engine architecture. This made it easy to port to the new engine.
UI Tool
None of the programmers in the group had worked with UI in any of the C++ projects before which made me take the opportunity during pre production to begin development of a UI tool using ImGui, capable of placing sprites, buttons and sliders.
Two reasons to why I chose a in-engine tool over a purely data-driven approach was partly because our group’s UI artist had a UI tool during a previous project which allowed for fast iterations and a representative look of the UI directly in-engine, and partly because we began a course in tools development during this timeframe which allowed the development of a custom tool, which was dedicated to this tool.
In the beginning I mainly focused on getting sprites to work with a simple GUI as well as on interfacing with the rest of the engine. When I tried to interface with the At first I tried to create specific classes for all UI objects, not at all correlated with the engine actors but quite quickly realized that it wasn’t a sustainable workflow. I asked one of my coworkers Daniel Strömblad for advice and they suggested to instead interface the behavior with the engine actors in form of components. From this point onward we worked together on the tool in close cooperation with both our graphical- and technical artists during the entire project.
Manipulating sprite properties on a sprite
Slider functionality shown by changing its value
Buttons could attach to events on click. The size of the button could also be adjusted.
Demonstrating the cascaded shadow maps both in game and in the directional light shadow pass.
Cascaded Shadow Maps
One major problem with the graphics engine since the TGP course was the directional light shadows. Currently the shadows disappeared once the player moved far enough away from the directional light’s position in the world.
To address I implemented Cascaded Shadow Maps (CSM). Some areas in the game had large depth which made me decide upon partitioning the camera’s view into three sections. Each section would have a separate shadow map which was rendered to during the shadow pass ensuring shadows at any visible distance. throughout the levels.
Overall this significantly improved the visual stability in the levels and allowed for shadows across all the environments.
Even though there were visible shadows on all objects that looked decent in the game perspective I noticed during the implementation of CSM that the shadows in close distances to the camera shimmered. This is a known problem but considering the shimmering barely, if at all, noticeable from the games camera perspective and due to a lack of time, I decided to not fix it for this project.
Shimmering occuring when the camra moves and rotates.
Reflections
This project was a whole lot of fun especially during pre production where I got to partake in building our engine from the ground up. From previous group projects we already had a foundation, in projects 3 and 4 TGA’s own C++ framework and projects 1 and 2 using Unity engine, which was a good learning experience, getting comfortable programming. Going into the fifth group project I didn’t know specifically what I wanted to focus but I was curious about engine concepts. Throughout the whole project I got to sit with engine related subjects which I thought was fun and wanted to explore more in the coming projects.
I’m happy with the fact that I could successfully implement cascading shadow maps. It lifted the visuals of the game a lot being able to seeing shadows when playing through the levels instead of just in the beginning of each level. The one thing that I’m not fully satisfied with is the fact that I didn’t have time to fix the shimmering artifacts. Hopefully I’ll get the chance in one of the coming projects to fix it.