The SpatialOS Game Development Kit for Unity is built on Unity’s Entity Component System. In this, the first in a series of posts on the topic, we’ll explain what ECS is and what it can do for your SpatialOS game. The author, Ollie Balaam, is a QA Engineer at Improbable.
The headline benefit of Unity’s ECS is performance-by-default. To achieve this, ECS moves away from traditional object-oriented programming (that is, the GameObject and MonoBehaviour centred workflow that most Unity developers are familiar with), and towards data-oriented design. To demonstrate their differences, let’s compare how you build an object representing the player character with each approach:
Using object-oriented programming, you’d create a GameObject to represent the player character, then attach MonoBehaviours to give the GameObject functionality such as a player controller, health and physics attributes. These MonoBehaviours contain both the data (such as hit points) and the code that modifies that data (decrementing hit points when the player takes damage for instance).
Using data-oriented design, you’d create an entity to represent the player character, then attach components to store data. ECS components should not be confused with GameObject components, such as MonoBehaviours. Unlike GameObject components, ECS components don’t contain any logic, they only store data. The code we use to perform operations on entities and their components exist in the form of systems. Systems are scripts. They act, in bulk, on all of the entities and components in the world.
To continue our previous example of decrementing hit points, a system would group all entities that have health and damage components and decrement the affected components accordingly.
The memory layout of data-oriented design ensures that the code generated by ECS performs significantly fewer jumps between memory addresses than traditional object-oriented programming.
Additionally, the memory layout induced by ECS allows for further code optimisations that leverage cache prefetching, the process your CPU uses to ensure it has the next bit of data already loaded into the cache by the time it needs it. The Unity ECS paradigm does this by using equally sized chunks of components that can be iterated over linearly. Rather than dealing with randomly stored objects of various sizes, the CPU only has to deal with these uniformly sized chunks stored linearly in the same area of memory. This makes the CPU’s job easier, a bit like playing Tetris with 1×1 blocks.
By decoupling data (entities and components) and logic (systems), ECS also produces more modular, easy-to-read code. Furthermore, it conceptually mirrors the core concepts of SpatialOS (entities, components, and the workers that operate on them), making it a perfect fit for the SpatialOS GDK (And if you’re not sure what the GDK is ? Click here to fin dout more.
With all of these benefits, you might be wondering: why isn’t everyone using ECS?Firstly, ECS isn’t for everyone. We’re excited by it because it suits the massive, richly populated and persistent games that SpatialOS enables, but some games (turn-based strategy games for instance) simply don’t require this level of performance.
Secondly, ECS is still at an experimental stage of development. Most of Unity’s existing tooling and systems are still only designed to be used with GameObjects and MonoBehaviours.
To alleviate these pain points, the SpatialOS GDK for Unity offers two workflow options:
Crucially, these workflows are not mutually exclusive. Given the current lack of tooling around ECS, we anticipate that you’ll write most or all of your game using MonoBehaviours. Whichever workflow you choose, your game will still take advantage of the performant GDK core module, which we’ve written using the ECS. Our goal is to bring you the benefits of ECS as early as possible, by means of our own API and abstraction layer. This approach will shelter you from most of the breaking changes that Unity makes to their ECS, so you can focus on writing your game however you’d like to.
In the next post, we’ll explore both workflows in detail, and examine code examples of each. Until then, here are some more resources on Unity’s ECS and Improbable’s SpatialOS GDK for Unity.