Entity Component System architectures (and why you should care)

EnderShadow8
4 min readJun 7, 2021
Entity Component System

Games seem like a great application for OOP — there are lots of game objects interacting with each other and updating their state accordingly. And it’s true — many great games have been written this way.

But there are also some glaring flaws with OO design.

If you just want to know about ECS and not the problem with OOP that gave birth to ECS, you can skip to the Composition section.

The Big Problem with OOP

Inheritance

It’s one of the first concepts taught to students learning OOP, and for good reason — it’s one of the foundational pillars of OOP.

I imagine an explanation would go something like this:

Dogs and cats are both animals. They share some characteristics, such as having legs, while others differ, such as cats having whiskers but dogs not. To express this, Dog and Cat are both classes that inherit from Animal. In this way, the shared code (such as legs) are implemented in the Animal class, which helps prevent code duplication. Similarly, code common to all dogs would go in the Dog class. This helps prevent code duplication between classes such sa Bulldog and Poodle which are both Dogs.

Sounds great! We can successfully apply DRY (Don’t Repeat Yourself) in an intuitive way using inheritance trees!

The problem with inheritance

Say we have Horse and Donkey classes. A Mule is an animal which has a horse mother and a donkey father. (Yes, they exist!)

Where would a mule go in the inheritance tree?

It has characteristics of both horses and donkeys, as well as its own. If it inherits from Horse, then we have to duplicate the Donkey code, and if it inherits from Donkey, then the Horse code is duplicated.

There must be a way to inherit from both, right?

Multiple inheritance to the rescue!

What if a class could inherit from multiple parent classes? This is known as multiple inheritance.

Could this be the solution?

…or not.

This is known as the Deadly Diamond of Death. It poses the question: If class D’s parents both have a method with the same name, which method is inherited by D?

There’s no clean solution to this problem so most languages don’t support multiple inheritance.

Composition

The other way to go about things in OOP is composition.

Composition is composing a class by building it out of several smaller, more specialised component classes. This allows for more flexibility and completely solves the inheritance problem. By simply picking and choosing the functionality needed, inheritance is avoided altogether.

The outer class no longer has any of its own functionality, so I’ll refer to it as the container class.

However, there’s now a new problem.

Say we have an object with Position and Velocity components. Where would the function updatePosition live? A function has to be bound to one component, even though in many cases, like this one, the action it performs involves many components.

ECS

Finally, we arrive at ECS, the brilliant solution to all of the problems above.

Instead of components having methods, why not have an external function update the components instead? This would mean that the function isn’t bound to any one component, but instead is an outside force which can affect all components involved in said action.

This is the core idea of ECS.

ECS is made up of three main parts:

  • Entity, which holds components.
  • Component, which holds data.
  • System, which performs operations on entities and components.

Systems only operate on entities that have certain components, for example, the Movement system would only care about entities with Position and Velocity components. This means that there are no more dependencies, since any entity can have any combination of components and only those with a matching set will be affected by any system.

ECS is definitely a fresh way to think about many problems, and has great potential.

I’m the author of WolfECS, a new ECS framework for written in Typescript. It’s the fastest web-based ECS implementation I know of. WolfECS abstracts away a lot of the underlying implementation of ECS so all you have to worry about is your components and systems. https://github.com/EnderShadow8/wolf-ecs

--

--