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.

To get the last out of the visuals in the game I worked on some post processing features. The major ones being exponential height fog and a vignette. Other than that, I made sure the engine would have some more basic post processing features like saturation, tint, exposure, contrast, black point and bloom.

The result turned out to be very fulfilling to me and I think it gave the game a better feal and ambiance.

Post Processing Editing Tool

To be able to easily try out different post processing settings for specific levels. I created a tool which could be used in the development build, by artists, programmers or anyone else. This made it easier for our artists to do as they wished with the environment.

Post Processing

Glowing Enemies

To visualize harder or elite mobs I decided to implement a fresnel outline, which did the trick quite well in my opinion. It looks kind of how it would in diablo or path of exile for example. With the important part of visualizing the difficulty of the enemy.

Unity Binary Export/Import

Because our engine doesn’t have any editor for level building, we used Unity as our level editor. This required us to create a system used to import and export levels. An export script in Unity was created for this, and an import script in our engine.

Because of the data being binary it’s a lot faster to read which is quite nice but a bit frustrating if something doesn’t work. In the end I think it was good decision when there was a lot of data to handle, reducing loading times with no need for string comparisons and such.

This was a system I worked on during 3 projects, so it has gradually been improved. But it did always do its job and stayed until the end. The fact that it has been such a reusable system saved us a lot of time in the last projects. With less need to dedicate work to import/export systems.