Specialized components
Physics and spatial systems
Entity component system (ECS) core
13 min
overview the entity component system (ecs) is the foundational architecture of the ir engine this design pattern provides a flexible, modular approach to building complex virtual environments by separating identity, data, and logic into three distinct concepts entities, components, and systems core concepts entities entities represent individual objects in the virtual world in the ir engine, an entity is essentially a unique identifier that serves as a container for components entities themselves do not contain data or behavior; they simply provide an identity to which components can be attached // from src/initializeengine ts (simplified) import { createentity } from '@ir engine/ecs'; const myentity = createentity(); this code creates a new entity with a unique id at this stage, the entity is just an empty container with no properties or behaviors components components are data containers that define specific attributes or properties of an entity each component type represents a single aspect of an entity, such as its position, appearance, or behavior components store only data, not logic // from src/initializeengine ts (simplified) import { createentity, setcomponent } from '@ir engine/ecs'; import { namecomponent } from ' /common/namecomponent'; import { transformcomponent } from ' /transform/components/transformcomponent'; const cubeentity = createentity(); // add a name component setcomponent(cubeentity, namecomponent, 'cube entity'); // add a transform component with default values setcomponent(cubeentity, transformcomponent); in this example, the entity is given two components a namecomponent that provides a human readable identifier a transformcomponent that defines its position, rotation, and scale in 3d space components are defined using a schema that specifies their data structure // from src/camera/components/cameracomponent ts (simplified) import { definecomponent } from '@ir engine/ecs/src/componentfunctions'; import { s } from '@ir engine/ecs/src/schemas/jsonschemas'; import { perspectivecamera, arraycamera } from 'three'; export const cameracomponent = definecomponent({ name 'cameracomponent', schema s object({ fov s number({ default 60 }), aspect s number({ default 1 }), // additional camera properties }), oninit (initial) => new arraycamera(\[/ camera initialization /]), // additional component configuration }); systems systems contain the logic that operates on entities with specific component combinations each system performs a specialized function, such as rendering, physics simulation, or input processing systems query the ecs database for entities that match their required component signature and then process those entities accordingly // from src/camera/systems/camerasystem tsx (simplified) import { definesystem, queryreactor } from '@ir engine/ecs'; import { cameracomponent } from ' /components/cameracomponent'; export const camerasystem = definesystem({ uuid 'ee engine camerasystem', reactor () => { // query for entities with cameracomponent return \<queryreactor components={\[cameracomponent]} childentityreactor={cameraentityreactor} />; } }); const cameraentityreactor = () => { // process each camera entity // update camera properties, handle view changes, etc return null; }; the system execution occurs within the engine's main loop // from src/starttimer ts (simplified) import { timer, executesystems } from '@ir engine/ecs'; export const starttimer = () => { const timer = timer((time, xrframe) => { // pre system operations executesystems(time); // execute all registered systems // post system operations }); timer start(); }; implementation details entity implementation entities are typically implemented as simple numeric identifiers this approach allows for efficient storage and retrieval of entities and their associated components component storage components of the same type are often stored together in contiguous memory blocks (arrays or similar data structures) this organization enables efficient iteration when systems process entities with specific component types system queries systems use queries to efficiently find entities that match their required component signature these queries are optimized to quickly filter the entity database and return only relevant entities practical example the following example demonstrates how the ecs architecture works together to create a red cube in a 3d scene create the entity const cube = createentity(); add components // position the cube at (5, 0, 0) setcomponent(cube, transformcomponent, { position {x 5, y 0, z 0} }); // define the cube's appearance setcomponent(cube, meshcomponent, { mesh redcubemeshdata }); // give the cube a name setcomponent(cube, namecomponent, "red cube"); systems process the entity the transform system calculates the cube's final position, rotation, and scale the rendering system uses the transform and mesh data to draw the cube on screen adding behavior // make the cube move along the x axis setcomponent(cube, velocitycomponent, { x 1, y 0, z 0 }); the movement system finds entities with both transform and velocity components it updates their positions each frame based on their velocity system execution flow the following sequence diagram illustrates the typical flow of execution in the ecs architecture sequencediagram participant usercode participant ecsengine participant transformsystem participant rendersystem usercode >>ecsengine createentity() ecsengine >>usercode entityid (e g , 101) usercode >>ecsengine setcomponent(101, transformcomponent, {pos, rot, scale}) usercode >>ecsengine setcomponent(101, meshcomponent, {shape, color}) note over ecsengine game loop tick ecsengine >>transformsystem execute() transformsystem >>ecsengine query entities with transformcomponent ecsengine >>transformsystem \[101, otherentities, ] transformsystem >>transformsystem update world matrices ecsengine >>rendersystem execute() rendersystem >>ecsengine query entities with transformcomponent and meshcomponent ecsengine >>rendersystem \[101, ] rendersystem >>rendersystem render entities using transform and mesh data benefits of ecs architecture the ecs architecture provides several advantages for game and simulation development composition over inheritance entities can be constructed by combining different components, avoiding deep inheritance hierarchies data oriented design separating data (components) from logic (systems) enables more efficient memory access patterns modularity systems can be added, removed, or modified without affecting other parts of the codebase flexibility new entity types can be created by combining existing components in different ways performance systems can process large batches of similar components efficiently, often leading to better cache utilization next steps with an understanding of the entity component system architecture, the next chapter explores the transform system, which manages the spatial properties of entities in the 3d environment next transform system docid 4qeojagryifci ukqrpaz