Only Geometry and Tunes was a technical venture I embarked on during my final year of university, centering around tools for game engines. Our task was to design and develop a rhythm game which was centered around one mechanic. I chose to build my game around object spawning, enemy AI would spawn in accordance with a set rhythm of time intervals, with different behaviours.
​
You can find the complete code repository here.
The behaviours for the objects were as follows:
-
moving laterally (across x-axis)
-
moving vertically (across y-axis)
-
tracking the players location (x,y)
-
moving toward other enemies, causing an 'explosion' of new projectiles upon collision
​
Each type of enemy needed to pose a different challenge for the player, and in line with a set rhythm.
​
​
The experimental plug-in:
I developed the game in Unity, using an experimental data management tool called ECS (Entity Component System). This treated all objects as data, instead of GameObjects, to have performance benefits at run-time. While we were tasked with developing a game, I chose to make my game a technical comparison that studied the differences between how Unity stored data and how ECS stored data. With prior knowledge of using Unity's built-in profiling tools, I demonstrated evidence of how they were different, and how the efficiency of my code affected this too.
ECS and the Burst Compiler proved challenging to implement because they used a bespoke physics system incompatible with the main engine. Due to this being an experimental plug-in, there was a lack of documentation and guidance on handling it, I was inspired to think and work innovatively.
​
Once I had gotten to grips with the physics system, I could expand the enemy AI and their behaviours. This was relatively straightforward, giving each enemy inherited qualities from a base template. These qualities are called 'components' and are pure forms of data that act as the fuel to run methods and coroutines. To distinguish between each enemy object type, I gave each its unique tag such as 'trackingEnemy' or 'xEnemy'; which would run it's version of inherited methods from the base class.
1
11
Object pooling:
Once the ECS game had been developed successfully, I explored object spawning through object pooling. Object pooling's performance benefits come from pre-determining a set amount of objects to be instantiated before run-time. Whilst this is better than instantiating from a coroutine, it has its limits and isn't malleable.
I discovered in this technical venture how hard it was to change the number of objects pooled as the game went further on, so numbers and multipliers have to be decided fairly early on in development. An advantage of this was the speed of implementation, compared to ECS, it was not repetitive or time-consuming to pool objects together.
​
It proved not to be as performant at run-time in this technical instance, however, revisiting it, I would create a more in-depth object pooling system. This way, I could measure the effectiveness of each method while having a diverse and interesting array of objects to challenge the player.
Technical explanation:
This technical explanation is an in-depth technical review of the venture, looking at the architecture of my code, the thought processes behind using ECS for the first time, and how / why it can be used for projects in the future.