Spite - New Sun
Time: 180h
Team Size: 11 people, of which 6 programmers
Engines: FaktalOktav (Custom Engine) and Unity
Libraries: DirectX 11, FMOD, NLohmann Json, ImGui
Language: C++/C#
Sprite - New Sun is a Diablo-inspired hack n' slash game set with a Mayan Theme. The game was the first full game project created within our engine. Everything within the engine needed updating and changing to accommodate the new game type. We use Unity as our Level Editor.
Export Tool
For multiple scenes to be exported efficiently and logically a new tool was needed compared to how our previous export was in Exposé. The tool's full function would be to create files that contained everything inside a scene and send that data to our engine, while maintaining the correct scene order.
​
This exporting tool was created as a long-term feature and would be used for future projects. Therefore more care and attention was required to make it. The name given to this tool is Scene Manager.
Exporting Tool
The Scene Manager checks for SceneData, a ScriptableObject (works as a container for values) inside Unity.
SceneData contains the information:
-
​Scene (the entire editable area in which a game can be built/played)
-
Conjoined Scenes
-
Connected Scenes
-
Display Name
SceneData ScriptableObject
When creating a new SceneData two things are crucial for exporting, Scene and Display Name.
​
The Scene identifies what to open and harvest data from for exporting.
Display Name is the name that scenes will have inside our engine, for example in level select.
Exporting Conjoined Scenes
Conjoined Scenes and Connected Scenes are implementations meant as an optional feature for ease of use.
​
Conjoined Scenes is an option to have multiple scenes exported together into one single data file, this means that multiple scenes in unity can become one scene in our engine.
​
Connected Scenes are identifiers of what new scenes should be available when leaving the existing scene. For example, if multiple doors transport the player to another scene, we as developers want to clarify which scenes should be prepared.
​
Scene Swapping Tool
Scene Swapping
When the button Export Scenes is pressed, we will end up in the last scene in the export list.
​
The availability to swap scenes from the export menu was a requested feature from our designers, for when they want to return to the scene they were working on before exporting.
This is a feature that was quick and easy to implement and had a positive impact on our workflow.
Binary Serializing
Unity Export Values
I've opted to serialize a binary file using BinaryWriter from the .NET Library. I'm writing every data type except for Strings, as they require a different extraction method which I couldn't implement due to time constraints. The ideal approach is to include everything within our binary file to optimize disk space usage.
​
Below is a comparison between GetEntitiesId, which only writes down the objects id and name.
Extracting Material Information for Export
In order for our engine to function some crucial data components from Unity needs to be exported. The user will be notified if something regarding the export inside Unity has gone wrong.
One of these crucial data components are materials, because we require each object in our scenes to have a albedo, normal and metallic texture for our models.
Binary Deserialization
Importing Data from Binary Files
We have integraed a Component System in our engine. This means that every object have components which processes and executes game logic.
​
Everything inside of our binary files are memory aligned. This insures that the start up process of the engine isn't slowed down due too the importing process and therefore creates faster game objects. Consequently, each block of data must be imported in a specific sequence. A Container called scene data is created to containe each block of data.
​
The first four bits for each block of data will inform the importer how many objects that need to be created, this allows for a nesting memcpy to allow for instant data filling.
Create Objects of Different Components
When Scene Data is allocated it will forwarded to the Object Creator which uses the data stored to create new objects and fills them with their corresponding components. The picture, here above, shows how most components inside the file is attached to its object.
Banks - Object Pooling
As the project progressed, we began to observe that the maps were consuming significant memory. Eventually, some team members found themselves needing to restart their computers every time they ran the project to perform a hard reset.
Memory Usaged at its Worse
The culprits for the memory allocations were:
-
Every model allocated an animation skeleton
-
Every model was unique
-
Materials were unique
-
Models were not removed from rendering, only added
Iterative Process for Finding .DDS files
In order to pinpoint the issue I had to familiarise myself with the Memory Profiler in Visual Studio, to identify where and when memory was being allocated.
​
The Solution to our problems was mostly just to reuse Models/Materials for each object in our scene. Our Banks (Object Pools) create every Model and Material during engine startup by iterating through every folder within our Asset directory, identifying any files with the .FBX or .DDS prefix. Although effective, this solution was implemented as a quick fix.
Threading
Threaded Configurations for Scenes