Entity System
An entity system in game development describes the structure a game engine uses to organize its entities. What is meant by an entity can differ depending on the system. Moreover, the term entity system itself and what it actually entails are still up for debate - as well as what the best practices should be when implementing them.
Some examples of entity systems include:
- Object-oriented inheritance hierarchy
- Compositional flat inheritance hierarchy
- Act/React
- Sparse Entity System
- Discriminated Unions
- Entity-Component-System (ECS)
- Megastruct
Object-oriented inheritance hierarchy
Typical structure:
- All concrete entities are derived from an
Entity
baseclass. - Specific classes are deeper in the hierarchy (e.g.
Pirate
derived fromHuman
) - Not a flexible system: Hard to allow shared behaviour between subclasses
Compositional flat inheritance hierarchy
Typical structure:
- All entity types are directly derived from the
Entity
baseclass - Or, entity has
Entity
struct with function pointers for OOP-style dispatching - Behaviour comes in form of components that can be shared between entities
Act/React System
Developed and used by Looking Glass Studios. Designed to resemble an SOA (struct of arrays) layout rather than a conventional AOS (array of structs) one. This was possibly the first variation of an ECS.
Typical structure:
- All data that describes an entity is stored contiguously in SOA arrays
- E.g. a burnable array contains entries for every entity that can burn
- Entities are identified by an index into those arrays
Discriminated union
In entity.h:
struct entity_t { entity_type_e type; union { // ... }; } #define GET_ENT(e, entity_type) ((e)->type == Entity_##entity_type ? &(e)->entity_type : 0)
Usage code:
if (auto* bomb = GET_ENT(e, bomb)) { bomb_blow_up(bomb); }
Megastruct
Approach of using a product type for the entity struct, rather than a sum type (i.e. discriminated union).
Every field that any type of entity possibly needs is part of one and the same entity type. Entities then are differentiated by which features they have turned on using a flags field on each entity, with each bit corresponding to a codepath that encodes an effect. This is in contrast to classifying things into distinct types.
Entities can be composed together using structures like a tree.