Of Entity-Component-Systems

I made a semi-cache coherent container which provides an Entity-Component-System. These are the bones of modern game-engines.

This post is largely a gooey weasel opinion piece. It started as an introduction that grew out of control. So, for now, it’s just a bit of rambling while I clean-up the documentation for my tool.

Of Entity-Component-Systems

Among other things, Jason Gregory’s book Game Engine Architecture discusses the concept of a data-driven architecture for game software.1 Google has published a project CORGI which uses this approach, calling it an Entity-Component-System. Unity3D’s scripting system seems to have originally been structured around this, but allows a tremendous flexibility.2 All of these example share a pattern;

  • Entities are created to represent things in the game
  • Components are attached to entities to let these things do stuff
  • System singletons exist which are (ideally) stateless and provide reusable logic

Gregory (and others have) suggested that this pattern rose to prominence as a reaction against, what I’d call, the classical “object-oriented-god-object” pattern. The OOGO feels natural within the structure of object oriented programming languages. Students are taught that everything is an object, so, programs are designed to treat everything as an object. Storing data (in the way that C++ stores data) and relying on their virtual dynamic dispatch led to performance problems. The CPU data and instruction caches on 7th generation game consoles meant that OOGO’s use of these techniques produced a bottleneck and a noticeable performance problem. While C++ and dynamic dispatch had their place, it was not necessarily at such a fundamental level of design. Entity-Component-System offer a potential workaround by placing the components (which Gregory calls properties) near each other in memory. Since individual component instances are near each other, (as far as the CPU is concerned) the data is more likely to be in the cache when it is needed. The instruction cache benefits as well given that processing or updating many records can avoid virtual invocations.3 Putting the technical justification aside, the approach is in vouge as of 2018 and made an interesting project. The separation of concerns isolates features outside of an inheritance hierarchy; code and logic for components exist independently and feel less coupled to each other. I encountered frustration with building CORGI, and due to its lack of cache coherency I wanted to see if I could produce “my own” to experiment with in the future.

So that’s where this came from.

Whippet on GitHub

Going forward; function pointers might introduce fewer pipeline steps (as they are direct jumps rather than indirect) however I lack any evidence to support that.

  1. Gregory refers to this as a property driven architecture, and uses the label component based to refer to something else. [return]
  2. Since Unity3D is a closed source system, I can only guess what’s going on in the engine. [return]
  3. My container does use virtual on nested classes to allow template-based inheritance. [return]
Peter LaValle avatar
About Peter LaValle
Peter is currently a PhD student at the University of Nottingham. His day work involves applying functional programming to problems with artificial intelligence. Someday maybe he'll retire and be a graphics programmer or demoscene coder.
comments powered by Disqus