ECS Architecture
The Entity-Component-System (ECS) architecture in helios separates data (Components) from behavior (Systems), enabling flexible and cache-friendly game object composition.
Overview
┌─────────────────────────────────────────────────────────────┐
│ GameWorld │
│ ┌──────────────────┐ ┌────────────────────────────┐ │
│ │ EntityRegistry │◄───│ EntityManager │ │
│ │ (handle alloc) │ │ (component storage) │ │
│ └──────────────────┘ └────────────────────────────┘ │
│ │ ▲ │
│ ▼ │ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ EntityHandle │◄──────────│ GameObject │ │
│ │ (id+version) │ │ (facade) │ │
│ └──────────────┘ └──────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ View │ │
│ │ (queries) │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌───────────────────┐ ┌───────────────────────────────────┐
│ Systems │ │ Component Reflection │
│ ┌──────────────┐ │ │ ┌─────────────┐ ┌─────────────┐ │
│ │ System │ │ │ │ComponentOps │ │ Traits │ │
│ │ (Updatable) │ │ │ │ Registry │ │ (concepts) │ │
│ └──────────────┘ │ │ └─────────────┘ └─────────────┘ │
└───────────────────┘ └───────────────────────────────────┘
Module Structure
The helios.engine.ecs module exports the following classes:
| Class | Purpose |
|---|---|
| Component Structure | Required structure for components (Copy/Move) |
| GameObject | High-level entity facade (~16 bytes, pass-by-value) |
| EntityHandle | Versioned entity reference (8 bytes) |
| EntityRegistry | Handle allocation & validation |
| EntityManager | Component storage via SparseSets |
| View | Component-based entity queries |
| System | Game logic processor base class |
| Updatable | Interface for per-frame updates |
| SparseSet | O(1) component storage |
| Traits | Compile-time lifecycle hook detection |
| ComponentOps | Function pointers for lifecycle callbacks |
| ComponentOpsRegistry | Global registry for ComponentOps |
| ComponentReflector | Type registration helper |
Quick Start
// 1. Get a GameObject from the world
auto player = gameWorld.addGameObject();
// 2. Add components
player.add<TransformComponent>(position);
player.add<HealthComponent>(100.0f);
player.add<VelocityComponent>();
// 3. Query entities in systems
for (auto [entity, transform, velocity, active] : gameWorld.view<
TransformComponent,
VelocityComponent,
Active
>().whereEnabled()) {
transform->position += velocity->direction * deltaTime;
}
Data Flow
- Entity Creation:
EntityRegistryallocates versioned handle - Component Attachment:
EntityManagerstores in type-indexedSparseSet - Queries:
Viewiterates entities with matching components - Updates:
Systemprocesses entities each frame - Destruction: Handle version incremented, index recycled
Key Features
Versioned Handles
Detect stale references to destroyed entities:
auto handle = registry.create();
registry.destroy(handle);
registry.isValid(handle); // false
Type-Indexed Storage
O(1) component access without hash lookups:
auto* health = entity.get<HealthComponent>(); // Direct array access
Cache-Friendly Iteration
Contiguous memory layout in SparseSet:
for (auto [e, t, v, a] : view<Transform, Velocity, Active>()) {
// Components stored contiguously
}
Compile-Time Lifecycle Detection
Traits detect hooks without runtime overhead:
// Detected at compile time via concepts
if constexpr (traits::HasOnAcquire<T>) {
component->onAcquire();
}
Documentation
Entity Management
- GameObject - The entity facade you'll use most
- EntityHandle - How entity references work
- EntityRegistry - Handle lifecycle internals
- EntityManager - Component storage details
Querying & Processing
- View - Efficient component queries
- System - Writing game logic
- Updatable - Per-frame update interface
Storage & Reflection
- SparseSet - The underlying data structure
- Traits - Compile-time hook detection
- ComponentOps - Lifecycle function pointers
- Component Registry - Type registration
- Component Lifecycle - Hooks and callbacks
See Also
- Component System - High-level ECS concepts
- Game Loop Architecture - How systems execute
- Spawn System - Entity pooling and spawning