Entity-Component-System, or ECS, is a new architecture in the game industry, which is built upon the foundation of data-oriented design. You may argue that it has been around for more than a decade, but the game industry is still dominated by the old-school object-oriented programming (OOP) paradigm. For many people, including me, this is new. It is cool and full of challenges. So in this post, I would share my adventure so far with ECS. As my memory is still fresh, I will focus on my latest project, the one that I did as one of my Master’s degree assignment.
About the background, I’ve tried ECS several times before this project. The first time was with Arena of Survivors’ reborn project in 2018. Previously, the game was written using Photon Unity Networking (PUN). It worked fine and the gameplay mechanism was engaging for me personally, until the day we decided to test it publicly. We have a difficult problem: we have two servers worldwide, and the high ping and loss make the game buggy and unplayable. We did our best to deploy an authoritative client-server model which Photon does not support out of the box, but it simply cannot live up to the scale. So we tried to reborn the game using Exit Games’ new technology called Quantum. The technology uses a standalone simulation layer and Unity is just a rendering engine. That’s my first experience with ECS and I really like the idea of highly decoupled and solution-centric code.
The next experience was with Unity’s new Data-Oriented Technology Stack (DOTS), with an appealing motto: “Performance by default”. In 2018, Hiker Games tried to push the performance of Caravan War to a further limit to allow more space for game designers’ creative input. Unity’s ECS implementation was much more complicated than that of Quantum SDK, and the documentation and support are not on par as well.
The stack now seems much more mature, as many Unity talks in GDC indicated. That’s why I decide to give it another try.
The project contains two demos for comparison. One is written traditionally with Mono and OOP, and the other one uses ECS architecture. The goal here is to try the new technology stack in as an experiment or research. Many agents are thrown in the scene to see how well can ECS cope with a large number of objects compared to the traditional approach.
After a raw attempt at applying ECS, the ECS demo performs surprisingly worse than the Mono one. Turns out the bottleneck here is the naive O(n^2) target detection algorithm. With the help from a simple uniform grid spatial partitioning technique, the ECS demo can perform significantly better than the other one. This is a demographics showing how the two demos perform.
The experiment required a serious mental shift. I had to move from the way I view the game world with objects to a world of problems and solutions. I needed to throw most of everything I knew away and learnt how to do it again. For example, the inheritance relationship does not exist in DOTS, so I had to find a way to work around with component composition.
My train of thoughts has been like on a rollercoaster. One day I felt depressed and hopeless trying to figure out the solution to a problem that should be easy. Another day my mood was uplifted after I found out the way to solve it, just to be pushed down to the abyss many times more. After finishing the project, it was quite fun, to be honest, being a child who knows nothing again.
To conclude the showcase post, I’d summary my experience with DOTS like so:
- Is it performant by default? It is, as Unity did a fantastic job of grouping relevant data linearly in a cache-friendly and multithreading-friendly way. However, beware of your data organisation and algorithm choice – remember what I said about target detection?
- Does it make things easier? Not really. My ECS demo is quite simple but it contains more than a thousand lines of code with a lot of boilerplate work. Also, it is frustrating when you have to leave most of your programming habits behind and stick to value types and linear algorithms most of the time.
- Is it ready for production? Definitely not, at least not in most use cases. The documentation is lacking. Community support may not be able to help you with all your problems. The supporting tools in the editor such as debugging are not ready. Many important systems, such as animations and physics are not even there yet.
If you are interested in the details, here is the GitHub link to the project.