Skip to main content
The Prisma Engine ECS is a lightweight system-centric architecture living in src/engine/core/ECS.h. You register systems with the World singleton, give each system access to the world, and the world drives every enabled system each frame. Components are attached to entity IDs — plain uint32_t values that act as handles — and retrieved through the world’s component manager.

Core types

EntityID

EntityID is a plain integer handle. INVALID_ENTITY (0) is the sentinel value representing “no entity”. Always check against INVALID_ENTITY before using an ID returned from a query.

World

World is the central registry. It owns all systems and exposes the component manager.

World::Get

Returns the process-wide singleton World. Valid for the lifetime of the engine. This is the only intended way to obtain the world in application code.

World::AddSystem

Constructs a system of type T, registers it with the world, and calls T::Initialize(). Systems are stored in registration order. T must inherit from ISystem.
typename
Any type that inherits from Prisma::Core::ECS::ISystem. The world holds a shared_ptr<ISystem> internally.

World::Update

Iterates all registered systems in order and calls system->Update(ts) on each one where system->enabled == true. Call this once per frame from your application’s OnUpdate() (or let ECSApplication do it for you).
Prisma::Timestep
The frame timestep. Forwarded unchanged to each system’s Update().

World::AddComponent

Attaches a component of type T to the given entity and returns a pointer to it. The component is default-constructed.
EntityID
required
The entity to attach the component to. Must not be INVALID_ENTITY.

World::GetComponent

Returns a pointer to the T component attached to entity, or nullptr if the entity does not have one.
EntityID
required
The entity to query. Returns nullptr for INVALID_ENTITY.

ISystem

All game systems implement ISystem. Only Update() is mandatory.

ISystem::Initialize

Called once by World::AddSystem<T>() after the system is constructed and m_world is set. Acquire resources, subscribe to events, or run one-time setup here.

ISystem::Update

Called every frame by World::Update(), but only when enabled == true. This is your primary per-frame hook.
Prisma::Timestep
The elapsed time since the previous frame.

ISystem::Shutdown

Called when the world is destroyed or the engine shuts down. Release resources acquired in Initialize().

ISystem::enabled

When set to false, World::Update() skips this system entirely. Toggle at runtime to pause individual systems without removing them from the world.

Built-in systems

Prisma ships the following systems in src/engine/core/Systems.h. Register them with World::AddSystem<T>().

RenderSystem (ECS)

Collects all entities with MeshRendererComponent + TransformComponent, sorts opaque geometry by material (to reduce GPU state switches), sorts transparent geometry by depth, and submits draw calls each frame.

PhysicsSystem

Runs a fixed-timestep simulation (default 60 Hz) accumulated via m_accumulator. Handles collision detection and resolution for all entities with RigidBody and Collider components. Default gravity is (0, -9.81, 0).

AnimationSystem

Advances all AnimationComponent state machines each frame, interpolating between keyframes and triggering transition events.

AudioSystem

Manages AudioSourceComponent playback for all audio entities, including 3D positional audio. The underlying audio device is SDL3 (cross-platform) or XAudio2 (Windows native, currently pending interface refactor).

ScriptSystem

Drives all ScriptComponent instances — initialises scripts on the first frame they appear and calls their per-frame update function. The script runtime (Mono / CoreCLR) is managed by the engine’s scripting subsystem.
The scripting system is partially implemented. Mono integration is in progress.

TransformSystem

Maintains the parent–child transform hierarchy. World matrices are computed lazily: a matrix is only recalculated when the entity or any of its ancestors is marked dirty. Call SetParent() to reparent an entity at runtime.

LightSystem

Collects all active LightComponent entities each frame and makes them available to the render pipeline. Default ambient is (0.1, 0.1, 0.1).

CameraSystem

Finds the main camera entity (the first entity with a CameraComponent tagged as main) and recomputes its view and projection matrices each frame. Call GetViewMatrix() and GetProjectionMatrix() from your rendering code.

Minimal example

ECSApplication::OnUpdate() calls World::Update(ts) automatically — you don’t need to call it yourself.