Entity component system

Last updated
A simple Entity Component System layout. ECS Simple Layout.svg
A simple Entity Component System layout.

Entity component system (ECS) [lower-alpha 1] is a software architectural pattern mostly used in video game development for the representation of game world objects. An ECS comprises entities composed from components of data, with systems which operate on entities' components.

Contents

ECS follows the principle of composition over inheritance, meaning that every entity is defined not by a type hierarchy, but by the components that are associated with it. Systems act globally over all entities which have the required components.

Due to an ambiguity in the English language, however, a common interpretation of the name is that an ECS is a system comprising entities and components. For example, in the 2013 talk at GDC, [1] Scott Bilas compares a C++ object system and his new custom component system. This is consistent with a traditional use of system term in general systems engineering with Common Lisp Object System and type system as examples.

Characteristics

ECS combines orthogonal, well-established ideas in general computer science and programming language theory. For example, components can be seen as a mixin idiom in various programming languages. Components are a specialized case under the general delegation (object-oriented programming) approach and meta-object protocol. That is, any complete component object system can be expressed with the templates and empathy model within The Orlando Treaty [2] vision of object-oriented programming.

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. [3]

Component: A component characterizes an entity as possessing a particular aspect, and 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. [3]

System: A system is a process which acts on all entities with the desired components. For example, a physics system may query for entities having mass, velocity and position components, and iterate over the results doing physics calculations on the sets of components for each entity.

The behavior of an entity can be changed at runtime by systems that add, remove or modify components. This eliminates the ambiguity problems of deep and wide inheritance hierarchies often found in Object Oriented Programming techniques that are difficult to understand, maintain, and extend. Common ECS approaches are highly compatible with, and are often combined with, data-oriented design techniques. Data for all instances of a component are commonly stored together in physical memory, enabling efficient memory access for systems which operate over many entities.

History

In 1998, Thief: The Dark Project pioneered an ECS. [4] The engine was later used for its sequel, as well as System Shock 2.

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, [5] including definitions of core terminology and concepts. [6] 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. [7]

In August 2018 Sander Mertens created the popular flecs ECS framework. [8]

In October 2018 [9] the company Unity released its megacity demo that utilized a tech stack built on an ECS. It had 100,000 audio sources—one for every car, neon sign, and more—creating a large, complex soundscape. [9]

Variations

The data layout of different ECS's can differ as well as can the definition of components, how they relate to entities, and how systems access entities' components.

Martin's ECS

A popular blog series by Adam Martin defines what he considers an Entity Component System architecture: [6]

An entity only consists of an ID for accessing components. 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.

Components have no game code (behavior) inside of them. The components don't have to be located physically together with the entity, but should be easy to find and access using the entity.

"Each System runs continuously (as though each System had its own private thread) and performs global actions on every Entity that possesses a Component or Components that match that System's query."

The Unity game engine

Unity's layout has tables each with columns of components. In this system an entity type is based on the components it holds. For every entity type there is a table (called an archetype) holding columns of components that match the components used in the entity. To access a particular entity one must find the correct archetype (table) and index into each column to get each corresponding component for that entity.

Apparatus ECS

Apparatus is a third-party ECS implementation for Unreal Engine that has introduced some additional features to the common ECS paradigm. One of those features is the support of the type hierarchy for the components. Each component can have a base component type (or a base class) much like in OOP. A system can then query with the base class and get all of its descendants matched in the resulting entities selection. This can be very useful for some common logic to be implemented on a set of different components and adds an additional dimension to the paradigm.

FLECS

Flecs is a fast and lightweight ECS implementation for C & C++ that lets you build games and simulations with millions of entities.

Common patterns in ECS use

The normal way to transmit data between systems is to store the data in components, and then have each system access the component sequentially. 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.

The ECS architecture 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, transform, 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.

The ECS architecture uses composition, rather than inheritance trees. An entity will be typically made up of an ID and a list of components that are attached to it. Any game object can be created by adding the correct components to an entity. This allows the developer to easily add features of one 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.

The merits of using ECSs for storing the game state have been proclaimed by many game developers like Adam Martin. One good example is the blog posts by Richard Lord where he discusses the merits and why ECS designed game data storage systems are so useful. [10]

Usage outside of games

Although mostly found in video game development, the ECS architecture can be useful in other domains. [11] [ example needed ]

See also

Notes

  1. To avoid ambiguity in this article, we follow the words "Entity Component System" with a noun such as "framework" or "architecture". The word "system" is always singular in this context.

Related Research Articles

A relational database is a database based on the relational model of data, as proposed by E. F. Codd in 1970. A database management system used to maintain relational databases is a relational database management system (RDBMS). Many relational database systems are equipped with the option of using SQL for querying and updating the database.

Object–relational mapping in computer science is a programming technique for converting data between a relational database and the heap of an object-oriented programming language. This creates, in effect, a virtual object database that can be used from within the programming language.

In computer programming, the strategy pattern is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.

In software systems, encapsulation refers to the bundling of data with the mechanisms or methods that operate on the data. It may also refer to the limiting of direct access to some of that data, such as an object's components. Essentially, encapsulation prevents external code from being concerned with the internal workings of an object.

Software design is the process of conceptualizing how a software system will work before it is implemented or modified. Software design also refers to the direct result of the design process – the concepts of how the software will work which consists of both design documentation and undocumented concepts.

Database design is the organization of data according to a database model. The designer determines what data must be stored and how the data elements interrelate. With this information, they can begin to fit the data to the database model. A database management system manages the data accordingly.

ADO.NET is a data access technology from the Microsoft .NET Framework that provides communication between relational and non-relational systems through a common set of components. ADO.NET is a set of computer software components that programmers can use to access data and data services from a database. It is a part of the base class library that is included with the Microsoft .NET Framework. It is commonly used by programmers to access and modify data stored in relational database systems, though it can also access data in non-relational data sources. ADO.NET is sometimes considered an evolution of ActiveX Data Objects (ADO) technology, but was changed so extensively that it can be considered an entirely new product.

In computing and systems design, a loosely coupled system is one

  1. in which components are weakly associated with each other, and thus changes in one component least affect existence or performance of another component.
  2. in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components. Subareas include the coupling of classes, interfaces, data, and services. Loose coupling is the opposite of tight coupling.

In computer science, stream processing is a programming paradigm which views streams, or sequences of events in time, as the central input and output objects of computation. Stream processing encompasses dataflow programming, reactive programming, and distributed data processing. Stream processing systems aim to expose parallel processing for data streams and rely on streaming algorithms for efficient implementation. The software stack for these systems includes components such as programming models and query languages, for expressing computation; stream management systems, for distribution and scheduling; and hardware components for acceleration including floating-point units, graphics processing units, and field-programmable gate arrays.

In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupled software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details. The principle states:

An architectural pattern is a general, reusable resolution to a commonly occurring problem in software architecture within a given context. The architectural patterns address various issues in software engineering, such as computer hardware performance limitations, high availability and minimization of a business risk. Some architectural patterns have been implemented within software frameworks.

Object-oriented design (OOD) is the process of planning a system of interacting objects for the purpose of solving a software problem. It is a method for software design. By defining classes and their functionality for their children, each object can run the same implementation of the class with its own state.

In information science and information technology, single source of truth (SSOT) architecture, or single point of truth (SPOT) architecture, for information systems is the practice of structuring information models and associated data schemas such that every data element is mastered in only one place, providing data normalization to a canonical form.

In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. With this paradigm, it's possible to express static or dynamic data streams with ease, and also communicate that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the changed data flow.

Domain-driven design (DDD) is a major software design approach, focusing on modeling software to match a domain according to input from that domain's experts.

Event-driven SOA is a form of service-oriented architecture (SOA), combining the intelligence and proactiveness of event-driven architecture with the organizational capabilities found in service offerings. Before event-driven SOA, the typical SOA platform orchestrated services centrally, through pre-defined business processes, assuming that what should have already been triggered is defined in a business process. This older approach does not account for events that occur across, or outside of, specific business processes. Thus complex events, in which a pattern of activities—both non-scheduled and scheduled—should trigger a set of services is not accounted for in traditional SOA 1.0 architecture.

<span class="mw-page-title-main">Object-oriented programming</span> Programming paradigm based on the concept of objects

Object-oriented programming (OOP) is a programming paradigm based on the concept of objects, which can contain data and code: data in the form of fields, and code in the form of procedures. In OOP, computer programs are designed by making them out of objects that interact with one another.

The following is provided as an overview of and topical guide to databases:

<span class="mw-page-title-main">Distributed Data Management Architecture</span> Open, published architecture for creating, managing and accessing data on a remote computer

Distributed Data Management Architecture (DDM) is IBM's open, published software architecture for creating, managing and accessing data on a remote computer. DDM was initially designed to support record-oriented files; it was extended to support hierarchical directories, stream-oriented files, queues, and system command processing; it was further extended to be the base of IBM's Distributed Relational Database Architecture (DRDA); and finally, it was extended to support data description and conversion. Defined in the period from 1980 to 1993, DDM specifies necessary components, messages, and protocols, all based on the principles of object-orientation. DDM is not, in itself, a piece of software; the implementation of DDM takes the form of client and server products. As an open architecture, products can implement subsets of DDM architecture and products can extend DDM to meet additional requirements. Taken together, DDM products implement a distributed file system.

The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.

References

  1. Bilas, Scott. "A Data-Driven Game Object System" (PDF). Archived (PDF) from the original on 18 September 2013. Retrieved 25 December 2013.
  2. Lynn Andrea Stein, Henry Liberman, David Ungar: A shared view of sharing: The Treaty of Orlando. In: Won Kim, Frederick H. Lochovsky (Eds.): Object-Oriented Concepts, Databases, and Applications ACM Press, New York 1989, ch. 3, pp. 31–48 ISBN   0-201-14410-7 (online Archived 2016-10-07 at the Wayback Machine )
  3. 1 2 "Entity Systems Wiki". Archived from the original on 31 December 2019. Retrieved 31 December 2019.
  4. "The Unknown Design Pattern". 11 March 2021.
  5. Martin, Adam. "Entity Systems are the Future of MMOG Development". Archived from the original on 26 December 2013. Retrieved 25 December 2013.
  6. 1 2 Martin, Adam. "Entity Systems are the Future of MMOG Development Part 2". Archived from the original on 26 December 2013. Retrieved 25 December 2013.
  7. "Introducing GameplayKit - WWDC 2015 - Videos". Archived from the original on 2017-10-06. Retrieved 2017-10-06.
  8. "SanderMertens - Overview". GitHub. Retrieved 2021-09-06.
  9. 1 2 "Unity unleashes Megacity demo - millions of objects in a huge cyberpunk world". MCV/DEVELOP. 2018-10-24. Retrieved 2021-06-24.
  10. "Why use an Entity Component System architecture for game development?". www.richardlord.net. Retrieved 2021-11-18.
  11. Romeo, Vittorio. (2016): Analysis of entity encoding techniques, design and implementation of a multithreaded compile-time Entity-Component-System C++14 library 10.13140/RG.2.1.1307.4165. (https://www.researchgate.net/publication/305730566_Analysis_of_entity_encoding_techniques_design_and_implementation_of_a_multithreaded_compile-time_Entity-Component-System_C14_library)