ENTITY COMPONENT SYSTEM
Entity component system (ECS) is a software architectural pattern. An ECS consists of entities composed of data components, along with systems that operate on those components. It is most associated with video game development for the representation of game world objects.
ECS prioritizes composition over inheritance. Every entity is defined not by a type hierarchy, but by the components associated with it. Systems act globally over all entities that have the required components. For example, a food system might iterate through every entity with a relevant component tracking hunger, and act on them to push them a little away from satiation at time intervals. Entities lacking the component like terrain or items would be naturally ignored by the food system.
Due to an ambiguity in the English language, an interpretation of the name is that an ECS is a system comprising entities and components. In the 2002 talk at GDC, Scott Bilas compared a C++ object system and his new custom component system. This is consistent with a traditional use of system terms in general systems engineering with Common Lisp Object System and type system as examples.
History
In 1963, Ivan Sutherland's Sketchpad stored the visual elements of a drawing using an early form of an ECS. Instead of encapsulating points in different objects (e.g. lines, circles, rectangles) points were stored in a ring buffer, and visual elements were only referencing them. When moving a point, this allowed updating all the shapes and constraints using it.
In 1998, Thief: The Dark Project pioneered an ECS. The engine was later used for its sequel, as well as System Shock 2.
In 2002, Scott Bilas of Gas Powered Games (Dungeon Siege) gave a seminal talk on ECS. This inspired numerous later well-known implementations.
In early January 2007, Mick West who worked on the Tony Hawk series, shared his experiences on the process of ECS adoption at Neversoft.
Also in 2007, the team working on Operation Flashpoint: Dragon Rising experimented with ECS designs, including those inspired by Bilas/Dungeon Siege, and Adam Martin later wrote a detailed account of ECS design, including definitions of core terminology and concepts. In particular, Martin's work popularized the ideas of systems as a first-class element, entities as identifiers, components as raw data, and code stored in systems, not in components or entities.
In 2015, Apple Inc. introduced GameplayKit, an API framework for iOS, macOS and tvOS game development that includes an implementation of ECS.
In October 2018 the company Unity released its megacity demo that utilized a tech stack built on an ECS. Unity's ECS runs on a powerful optimized architecture known as DOTS, which "empowers creators to scale processing in a highly performant manner".
Characteristics
The ECS has no trouble with dependency problems commonly found in object-oriented programming since components are simple data buckets, they have no dependencies. Each system will typically query the set of components an entity must have for the system to operate on it. For example, a render system might register the model, transformations, and drawable components. When it runs, the system will perform its logic on any entity that has all of those components. Other entities are simply skipped, with no need for complex dependency trees. However, this can be a place for bugs to hide, since propagating values from one system to another through components may be hard to debug. ECS may be used where uncoupled data needs to be bound to a given lifetime.
Entity
An entity represents a general-purpose object. In a game engine context, for example, every coarse game object is represented as an entity.
Usually, it only consists of a unique ID. Implementations typically use a plain integer for this
using Entity = std::uint32_t;
const Entity MAX_ENTITIES = 5000;
Component
A component characterizes an entity as possessing a particular aspect, and (the component) holds the data needed to model that aspect. For example, every game object that can take damage might have a Health component associated with its entity. Implementations typically use structs, classes, or associative arrays
struct Transform
{
Vec3 position;
Quat rotation;
Vec3 scale;
}
using ComponentType = std::uint8_t;
const ComponentType MAX_COMPONENTS = 32;
System
A system is a process that acts on all entities with the desired components. For example, a physics system may query for entities having mass, velocity and position components, iterate over the results, and do physics calculations for each entity using the set of components.
References:
https://en.wikipedia.org/wiki/Entity_component_system
https://austinmorlan.com/posts/entity_component_system/