Entity–component–system

Entity-component system (ECS) is an architectural pattern that is mostly used in game development. An ECS follows the Composition over inheritance principle that allows greater flexibility in defining entities where every object in a game's scene is an entity (e.g. enemies, bullets, vehicles, etc.). Every Entity consists of one or more components which add additional behavior or functionality. Therefore, the behavior of an entity can be changed at runtime by adding or removing components. This eliminates the ambiguity problems of deep and wide inheritance hierarchies that are difficult to understand, maintain and extend. Common ECS approaches are highly compatible and often combined with data oriented design techniques.

History

The 1998 game Thief: The Dark Project is the earliest game that is publicly known to make use of ECS.[1] However, technical details were not published until much later than others.[2]

The 2002 game Dungeon Siege has one of the first clearly described ECS implementations, as documented in Scott Bilas's talk at GDC the same year.[3]

Bilas's talk explicitly mentions the now-standard concepts of: database for composition, "data-driv[ing]" the schema not just the properties, components as "self-contained" items, etc.

In 2007, the team working on Operation Flashpoint: Dragon Rising experimented with ECS designs, including ones inspired by Bilas/Dungeon Siege, and Adam Martin later wrote a detailed account of ECS design,[4] including definitions of core terminology and concepts.[5] In particular, Martin's work popularized the ideas of "Systems" as a first-class element, "Entities as ID's", "Components as raw Data", and "Code stored in Systems, not in Components or Entities".

The Unity game engine grew hugely in popularity from 2008-2010, making their different use of Entities and Components become well-known and widely used. However, Unity has not formally described their approach, and "ECS" as a term is usually assumed to mean the 2002 Bilas approach instead, unless specified.

Terminology

Martin's terminology,[5] in wide use today:

Game example

Suppose there is a drawing function. This would be a "System" that iterates through all entities that have both a physical and a visible component, and draws them. The visible component could typically have some information about how an entity should look (e.g. human, monster, sparks flying around, flying arrow), and use the physical component to know where to draw it.

Another system could be collision detection. It would iterate through all entities that have a physical component, as it would not care how the entity is drawn. This system would then, for instance, detect arrows that collide with monsters, and generate an event when that happens. It should not need to understand what an arrow is, and what it means when another object is hit by an arrow.

Yet another component could be health data, and a system that manages health. Health components would be attached to the human and monster entities, but not to arrow entities. The health management system would subscribe to the event generated from collisions and update health accordingly. This system could also know and then iterate through all entities with the health component, and regenerate health.

Design of an entity

An entity only consists of an ID and a container of components. The idea is to have no game methods embedded in the entity. The container doesn't have to be located physically together with the entity, but should be easy to find and access.

It is a common practice to use a unique ID for each entity. This is not a requirement, but it has several advantages:

Some of these advantages can also be achieved using smart pointers.

Drawbacks

There are a couple of problems with the ECS design.

Inter system communication

The normal way to send data between systems is to store the data in components. For example, the position of an object can be updated regularly. This position is then used by other systems.

If there are a lot of different infrequent events, a lot of flags will be needed in one or more components. Systems will then have to monitor these flags every iteration, which can become inefficient. A solution could be to use the observer pattern. All systems that depend on an event subscribe to it. The action from the event will thus only be executed once, when it happens, and no polling is needed.

Cost of iterating through entities

In some ECS architectures, one basic idea is to have one big list for all entities. Every system then iterates through the complete list, and selects only those entities that are needed. If the number of systems grows, and the number of entities is large, the total iteration cost for all systems may be too big.

In other ECS architectures, every component type are stored in separate lists, so whatever systems operate on those type of components are only iterating over objects they care about by default. In this common ECS architecture, the described disadvantage actually becomes a major performance advantage, by more efficiently leveraging the CPU instruction and data caches.

Advantages

Safe managing of dependencies

The ECS architecture handles dependencies in a very safe and simple way. Since components are simple data buckets, they have no dependencies. Each system will typically register the components an entity must have for the system to operate on it. For example, a render system might register the model, transform, and drawable components. It will then check each entity for those components, and if the entity has them all the system will perform its logic on that entity. If not, the entity is 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 very hard to debug. Having data separated from logic does not help reduce dependencies, reducing dependencies is done through proper design of code. You could move data from one class with 100 dependencies into a component, this does not solve the dependency problem but instead makes the class harder to debug. ECS may be used where uncoupled data needs to be bound to a given lifetime.

Composability

The ECS architecture uses composition over complex inheritance trees. An entity will be typically made up of an ID and a list of components that are attached to it. Any type of game object can be created by adding the correct components to an entity. This can also allow the developer to easily add features of one type of object to another, without any dependency issues. For example, a player entity could have a "bullet" component added to it, and then it would meet the requirements to be manipulated by some "bulletHandler" system, which could result in that player doing damage to things by running into them.

See also

References

  1. Leonard, Tom. "Postmortem: Thief: The Dark Project". Retrieved 19 January 2015.
  2. Church, Doug. "Object Systems". Chris Hecker's Website (Powerpoint). Retrieved 19 January 2015.
  3. Bilas, Scott. "A Data-Driven Game Object System" (PDF). Retrieved 25 December 2013.
  4. Martin, Adam. "Entity Systems are the Future of MMOG Development". Retrieved 25 December 2013.
  5. 1 2 Martin, Adam. "Entity Systems are the Future of MMOG Development Part 2". Retrieved 25 December 2013.
  6. 1 2 "Entity Systems Wiki". Retrieved 9 February 2014.

External links

This article is issued from Wikipedia - version of the 11/20/2016. The text is available under the Creative Commons Attribution/Share Alike but additional terms may apply for the media files.