Skip to content

Intro To Entity Component System Frameworks

John Tuttle edited this page Sep 29, 2017 · 4 revisions

Motivation

A common pattern in game development is having a piece of data that needs to operated on by a variety of different systems. For instance, the position of the player may be used for input handling, determining AI behavior, handling collision, rendering the player sprite, and more in a single iteration of the game loop. You could handle this by putting the logic that performs these operations in the same place and passing the player position around, but this could easily lead to coupling between pieces of your game logic that don't need to know about one another.

ECS frameworks provide a very natural way to delineate these boundaries and decouple a game's data from the logic that operates on it. In Baku (and many other ECS frameworks), the state of your game world is entirely contained in Components. These Components are attached to Entities, which represent objects in your game and are essentially only necessary to bundle sets of Components together. The logic of the game is placed in Systems, which will perform their operations on any Entity that possesses a particular set of Components.

Advantages

Composition Over Inheritance

ECS frameworks are built around the software engineering principle of favoring Composition Over Inheritance. This means that behavior can be assigned to an Entity by adding the desired set of modular Components rather than having it inherit from the correct parent class. This is a much more flexible approach because it completely sidesteps situations where you might end up in the "deadly diamond of death" situation that can happen with multiple-inheritance.

Serialization

Since ECS frameworks maintain a nice separation of game data from logic, it is very easy to take a snapshot of your game state by serializing Components. This is extremely useful when saving or loading a player's game and also when dealing with networking.

Single Responsibility Principle

The separation of game logic into Systems that operate on certain subsets of Components helps enforce the Single Responsibility Principle, another important tenet of software engineering. This simply means that classes are written to perform a single task. It helps to keep class sizes small, which makes them easier to read and maintain.

Concurrency

Although the order in which you run your Systems is often important, there may be subsets of Systems that can operate in parallel. You could conceivably gain a performance boost by running sets of systems in parallel as long as they operate on different sets of data and don't have any ordering constraints. Baku does not yet implement any form of concurrency but this is one potential advantage of ECS frameworks in general.

Drawbacks

ECS frameworks are great but they do have a few weaknesses. The emphasis on decoupling makes communication between Systems difficult. Although such communication should be minimized wherever possible, it's sometimes easier to just allow it to happen. Communicating between Systems in an ECS framework requires some sort of message queueing System or the passing of messages through Components, which can get a bit messy.

Some pieces of a game also don't fall naturally into an ECS architecture. User interface, for example, is often better architected using a Model View Controller scheme, which doesn't fit nicely into the ECS flow. It's often preferable to handle things like UI outside of the ECS and pass events between the two when necessary.