Skip to main content
Prisma Engine organizes all game objects using an Entity Component System. Instead of inheriting from a monolithic GameObject base class, you compose behavior by attaching lightweight data components to entities and writing systems that operate on those components every frame. This keeps game logic decoupled, cache-friendly, and straightforward to extend.
The ECS implementation is currently at approximately 80% completion. The core types — World, ISystem, EntityID, and Component — are stable and used in production. Component pools and advanced queries are still being finalized.

Core types

All ECS types live in the Prisma::Core::ECS namespace:

Entities

An entity is just an integer ID. You do not construct or destroy a class instance — you ask the World to allocate an ID and then attach components to it.

Components

Component is the base class for all data attached to an entity. Override the lifecycle hooks you need:

Built-in component types

Prisma Engine ships several ready-to-use components:
Attaches C# scripting logic to an entity. Inherits from Component. The scripting system (Mono/CoreCLR) is not yet fully implemented.
A 2D UI button with hover, pressed, and normal states. Inherits from UIComponent.
A 2D UI container that groups child UIComponent instances and controls how they render.

Systems

Every system inherits from ISystem and implements at minimum the Update method:
Initialize() is called once when the system is added to the World. Update() is called every frame, receiving a Timestep that wraps the frame delta time. Set enabled = false to pause a system without removing it.

Writing a custom system

Built-in systems

The engine provides a set of systems in engine/core/Systems.h: The TransformSystem is particularly important. Call TransformSystem::SetParent(child, parent) to build scene hierarchies; the system propagates dirty flags and recalculates world matrices efficiently each frame:

The World singleton

World is a singleton that owns the system list and drives the per-frame update loop.

Accessing the World

You can also access it through the Engine instance, which is the recommended approach from within application code:

Adding systems

Use World::AddSystem<T>() to register a system. The method constructs the system, injects the World pointer into m_world, and calls Initialize():
Systems update in the order they were added. Register systems that others depend on first — for example, TransformSystem before RenderSystem.

Per-frame update

World::Update() iterates the system list and calls Update(ts) on every enabled system:

Adding and querying components

World::AddComponent and World::GetComponent currently return nullptr in the stub implementation while the component pool system is being finalized. Check the source in engine/core/ECS.h for the current state before relying on these in production.

Putting it together

The following example registers the built-in transform and render systems alongside a custom game system: