SPITE: KNIGHT OF ODIN
Spite: Knight of Odin
Spite: Knight Of Odin was an action rpg with Diablo 3 as reference.
During this project my core responsibilities was the rendering aspect of the game, level loading, export/imports of levels from the unity editor to our engine and other engine systems/features. I also worked on the animation system, visual effects system and a system for threaded level loading which greatly improved level loading speeds. Other than that, I worked on tools such as a visual effects editor.
Further information about some of these systems are listed below.
Project Details
Time: 14 weeks, half time
Team Size: 5 programmers, 5 artists, 3 level designers
Engine: Custom engine based on The Game
Assembly’s in-house engine TGE
Libraries: DirectX 11, FMOD, Nlohmann Json, ImGui
Language: C++
VFX Editor
For easy creation and manipulation of visual effects I created a VFX Editor, capable of creating the visual effects we needed for the project easily. An effect using this system would have multiple components which individually would do a different thing to build good and concise VFX. This tool was made for and in mind of our artists to create the effects they wanted in the game.
Each component would have its own mesh, shader, blend state, rasterizer state, textures, and a long list of modifiers like size over life or colour over life for example. To be able to build a more appealing effect. I created a life system for the components and the effect which decided whether a component would be active or not and if the effect would end. For example, a component could live from second 1.5 to 2 in the duration of the effect. This made it possible to create timed effects in the effect which turned out quite nice.
Base Properties and
Sub instances
In the base properties every component has a start and end life. This determines when the component should be active or it’s timeline. Notice the min and max values, it’s for random intervals which creates variation. It looks good if multiple instances are played often and the effect isn’t required to be static.
The look at camera option is mainly for sprites to turn them flat against the camera, which is good for effects like fire or smoke when you need a sprite sheet. All the options for render states and shaders are just for more possibilities and options.
The sub instances are for spawning many of the same component batched. This saves a lot on performance and is a good way to spawn many particles at a low cost. The smoke in the Giff are sub instances. With this system you can easily spawn hundreds of instances without much impact on performance.
To reduce level loading time, I created a system that prioritizes loading of objects nearby, utilizing another thread for the task. This makes it seem like the level is loaded instantaneously in this type of game. Because you can’t see very far ahead on the map.
The clip shows loading of maps that aren’t pre cached. Which is very fast and does its job quite well.
Threaded level loading
Because of the many light sources we had in the game I quickly realised we needed a better system to handle shadows. So, I created a shadow atlas system capable of 14 point lights, a directional light and many more spotlights. Because of the vision of the map, being quite small, I decided to update all the lights on every pass to have perfect dynamic shadows. Of course, at a cost but for this project it worked out well and resulted in nice looking dynamic shadows all over the map.
The Result
As you can see in the picture, the shadows look quite nice. This is because all the shadow maps have a decent resolution at 512x512 pixels or 1024x1024 pixels depending on the distance from the camera. The total shadow atlas size is 8192x8192 pixels.
Handling of Light Sources
The used lights for the shadow maps are always the closest ones of the lights affecting the frustum. This weeds out all of the lights far away to maximize the shadow quality and usage close to the player. And to save performance as well.
Shadow Atlas
For the VFX effects I needed to create the whole VFX system from scratch in this project. I decided to go for a structure where you had an effect with child components under it. This made it easy to create complex effects with different components having their own timelines. Each component is essentially its own effect, following some ground rules and data from its parent.
The system turned out reliable and easy to use in both a scalable perspective adding more features and so on to effects and was easy to implement and use with the editor I created.
A code snippet demonstrating spawning an effect. The spawned effects are returned as pointers and can later be modified in real time as well.
A code snippet demonstrating playing an effect and its components. It returns true if the effect is done or should be killed.
VFX Component Transforms
Because of the many different modifiers such as, scale, rotation, positions and such, changing values relevant to the object transform over time. I had to spend some time to get it working correctly in the game. The biggest problems showed when there were a lot of different rotations to combine. As can be seen in the screenshot, matrix multiplications did the trick here. The result turned out nice with everything working as intended.
VFX System
Fading Meshes
One requirement of the project was to always keep the player visible. This meant I needed to create a system to fade away objects in front of the player in a nice-looking way. The biggest problems with this task were as simple as just finding the objects blocking the player. It might sound easy, but it had a few problems. The problems being, different sizes, different rotations and how to determine if it blocks the view of the player in a performant way.
This code snippet update objects in front of the player if they should fade.
Faded objects that could potentially block vision of the player.
The same place with the objects being back to normal and not faded.