Core components
Entity component system
Entity
17 min
overview an entity is the fundamental unit of identity in the ir engine's entity component system (ecs) it serves as a unique identifier for any distinct object or element within an application, from player characters and environmental objects to ui elements and abstract concepts entities themselves are lightweight and contain no data or behavior; they are simply unique numerical ids that other parts of the system can reference this simplicity is a key strength of the ecs architecture, enabling efficient creation, management, and destruction of application elements core concepts entity as an identifier in the ecs architecture, an entity is essentially a unique identification number it represents the existence of a distinct object in the application it serves as a reference point that components and systems can target it contains no inherent data or behavior on its own it provides a way to group related components together this approach separates the concept of identity (the entity) from characteristics (components) and behavior (systems), creating a flexible and modular architecture entity lifecycle entities have a simple lifecycle within the system creation an entity is created and assigned a unique id component attachment components are attached to the entity to define its characteristics processing systems operate on the entity based on its components component modification components can be added, removed, or modified throughout the entity's life destruction when no longer needed, the entity is destroyed and its id can be recycled this lifecycle allows for dynamic object creation and management during application runtime implementation entity type definition in the ir engine, entities are implemented as numeric identifiers with type safety // simplified from src/entity ts export type entity = opaquetype<'entity'> & number; // a special entity id that means "no entity" or "invalid" export const undefinedentity = 0 as entity; the opaquetype wrapper provides type safety by making entity distinct from regular numbers, while maintaining the performance benefits of using primitive values creating entities entities are created through a dedicated function that ensures uniqueness // simplified example based on engine internals import { createentity } from '@ir engine/ecs'; // create a new entity const playerentity = createentity(); console log("player entity id ", playerentity); // e g , 1 // create more entities const ballentity = createentity(); // e g , 2 const opponententity = createentity(); // e g , 3 the createentity function requests a new unique id from the underlying ecs implementation registers this id within the current world or engine context returns the id as an entity type entity creation internals under the hood, entity creation involves interaction between several layers sequencediagram participant usercode as application code participant irengine as ir engine api participant ecscore as ecs core system participant idpool as entity id pool usercode >>irengine createentity() irengine >>ecscore request new entity id ecscore >>idpool get next available id idpool >>ecscore return unique id (e g , 123) ecscore >>irengine return entity id irengine >>usercode return entity (123) the actual implementation often leverages optimized libraries like bitecs for efficient entity management // simplified conceptual implementation import as bitecs from 'bitecs'; // the world is the central container for all entities and components const world = bitecs createworld(); function createentityinworld() entity { // request a new unique entity id from the bitecs library const newentityid = bitecs addentity(world); return newentityid as entity; } the world (often accessed through hyperflux store in ir engine) maintains the registry of all active entities and their associated components entity operations beyond creation, several operations can be performed with entities checking entity validity // simplified example import { isvalidentity } from '@ir engine/ecs'; const entity = createentity(); const isvalid = isvalidentity(entity); // true const invalidentity = undefinedentity; const isinvalid = isvalidentity(invalidentity); // false destroying entities // simplified example import { destroyentity } from '@ir engine/ecs'; const entity = createentity(); // use the entity // when no longer needed destroyentity(entity); when an entity is destroyed all its associated components are removed systems stop processing it its id may be recycled for future entities practical examples game object representation in a game context, entities can represent various objects // create entities for a simple game const playerentity = createentity(); const enemyentity = createentity(); const projectileentity = createentity(); // these entities are just ids at this point // they need components to define what they are and how they behave without components, these entities are just empty identifiers the next step would be to attach components like position, appearance, and behavior to give them substance entity relationships entities can form relationships through specialized components // create parent and child entities const parententity = createentity(); const childentity = createentity(); // create a relationship through components (conceptual example) addcomponent(childentity, parentcomponent, { parentid parententity }); addcomponent(parententity, childrencomponent, { childids \[childentity] }); this approach allows for complex hierarchies and relationships while maintaining the simplicity of entities as pure identifiers benefits of the entity approach the entity as identifier approach provides several key advantages performance efficiency entities are lightweight (just numbers), making them cheap to create, store, and pass around memory optimization no memory is wasted on unused features since entities only have the components they need flexibility any type of game object can be represented by the same entity concept with different component combinations composition over inheritance behavior and properties are composed through component attachment rather than class inheritance runtime dynamism components can be added or removed during runtime, changing what an entity represents or how it behaves these benefits make the ecs architecture particularly well suited for complex, performance sensitive applications like games next steps while entities provide identity, they need components to define their characteristics and data the next chapter explores how components attach meaningful data to entities next component docid\ iqhjqgrurkybgnh4cmkkr