Skip to content

Instantly share code, notes, and snippets.

@mheiber
Last active June 26, 2020 10:09
Show Gist options
  • Save mheiber/cd368aa2c004dbcb9363094e30a8d73e to your computer and use it in GitHub Desktop.
Save mheiber/cd368aa2c004dbcb9363094e30a8d73e to your computer and use it in GitHub Desktop.
Notes on Entity Component Systems

Entity Component Systems notes from someone who doesn't write games and didn't know what ECS was.

Why care?

Possible Maintainability Advantages of ECS Systems as Compared to OOP:

  • State shape is more explicit, so much more likely to make good sense as an app grows
  • ECS encourages much less plumbing for data flow between parts of an app, since systems can just read whatever they want.
    • For big stateful apps, OO seems to encourage an 8-to-1 ratio of data plumbing compared to biz logic
  • easier to safely share behavior
  • Supports state serialization for record/replay debugging

Note on boilerplate and noise. The ECS code examples in the links below have a lot of perf-and-render-related noise, but the state management itself is simple.

Background

These notes will make the most sense if read after at least two of these:

Examples

Amethyst Game Engine (uses Specs ECS):

Unity ECS example:

There are no real API docs for Unity ECS yet as of Dec 2018 because it is so new.

Illuminating characteristics of the ECS Code Examples:

What are entities?

  • basically just IDs

How do systems not devolve into balls of mud?

How do systems communicate?

The Unity ECS example just uses "system 1 writes to this state that system 2 knows to read." This works alongside a C# attribute (like a decorator) that specifies that one system must run "after" another. See the explanation here: https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/5492abccd55e2f66194a06c671959d79cb81c2e1/Documentation/content/two_stick_shooter.md#player-input-movement-and-shooting.

The Amethyst/specs pong example works the same way: writing/reading shared data. But more advanced techniques are possible:

ECS major differences from OOP:

  • entities are basically just ids
  • bags of state (components) are not tied to anything like a class in OO, they are free-floating.
  • Systems are also not tied to anything like a class, though you can accomplish something similar, but simpler and easier to change: systems specify that they operate on things that have certain sets of components. That is, the PlayerMove system This is in stark contrast to methods. So bundles of state and bundles of behaviors are many-many. This is sort-of-kind-of like using multiple inheritance/mixins like crazy, but name conflicts on this/self are not possible and the interactions are more organized.
  • ECS is much less preoccupied than OOP with encapsulation, subsetting state, information-hiding, etc. All state is essentially global and essentially mutable, though there are ways of systems saying what they want to read and what they want to write.
  • Much of the motivation for ECS seesm to come from performance concerns (parallelizability, caching, SIMDability) but there may be maintainability advantages as well.

Ideas with similarities to ECS:

Relational Programming

Front End JS

  • Redux also has global state. But the way Redux reducers are used still couples chunks of state (the subset of state each reducer managers) with behavior (~= reducer logic). (aside: the immutable data part of Redux seems orthogonal to it's other characteristics. Vuex is basically the same thing, but with mutatation.)
    • A major difference is that ECS state slices (components) are 1:many with behavior (systems).
    • ECS is missing the notion of Redux "actions."
  • React hooks, which are reusable bundles of state and behavior independent of classes, where the state change logic is aware of different phases (mounting, updating, etc.). Differences are that hook state and behavior are 1:1 and hook state is usually not global.

Speculation

  • Ideas in "Purely Functional Retro Games," though maybe that author just landed on something functionally identical to Redux: https://prog21.dadgum.com/23.html
  • Maybe ECS is comparable to OOP but using a combination of component-like and system-like mixins for everything, empty class bodies, a tweak to avoid name conflicts, and a mixin registration system.
  • FRP is either similar to ECS or the complete opposite.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment