Skip to main content
Prisma::Engine is the top-level object that owns every engine subsystem. You create one instance on the stack, call Initialize(), hand it your Application, and call Run(). The engine drives the main loop until your application exits, then you call Shutdown() to release all resources in the correct order. There is no singleton imposed on you — you hold the object, you control its lifetime.

EngineSpecification

Configure the engine before construction by filling in EngineSpecification.
const char*
required
Human-readable name for this application instance. Defaults to "PrismaEngine". Used in window titles and log prefixes.
bool
When true, the engine skips window creation and all GPU work. Useful for server-side simulation or unit tests. Defaults to false.
bool
When false (default), the engine reads assets/metadata.json without rewriting it — safe for shipped runtime builds. Set to true in editor builds to scan and re-index all assets on launch.
Prisma::LogLevel
Minimum log level that is emitted. Defaults to LogLevel::Trace (everything). Set to LogLevel::Warning or higher in release builds to reduce log volume.
uint32_t
Target frame-rate cap. 0 means no cap — the engine runs as fast as the hardware allows. Defaults to 0.
Prisma::Graphic::PresentMode
Swap-chain present strategy. Defaults to PresentMode::VSync. See PresentMode below.

Constructor and destructor

The engine is non-copyable and non-movable. Construct exactly one instance per process. The destructor calls Shutdown() automatically if you haven’t already done so explicitly.

Lifecycle methods

Initialize

Boots all subsystems in dependency order: logging → window → render device → asset database → input → ECS world → scripting. Returns 0 on success or a non-zero error code if any subsystem fails to start.
Call Initialize() before Run(). Calling Run() on an uninitialized engine is undefined behaviour.

Run

Transfers ownership of app to the engine and enters the main loop. The loop ticks all subsystems and drives Application::OnUpdate(), Application::OnRender(), and Application::OnEvent() each frame. Returns when Application::Close() is called or the window is closed.
std::unique_ptr<Prisma::Application>
required
The application to run. The engine takes exclusive ownership — do not hold or use the raw pointer after this call.

Shutdown

Stops the main loop and tears down all subsystems in reverse-initialization order. Safe to call multiple times — subsequent calls are no-ops. The destructor calls this automatically, but explicit calls give you precise control over shutdown ordering relative to other stack objects.

Static accessor

Returns a reference to the current engine instance. Useful in deep call stacks where passing the engine explicitly would be cumbersome. Only valid between Initialize() and Shutdown().

Subsystem accessors

Once initialized, the engine exposes typed accessors for every core subsystem:
All accessors return nullptr (or throw) if called before Initialize().

Generic system access

Searches the registered subsystem list and returns the first subsystem of type T, or nullptr if none exists. Use for optional or custom subsystems added with AddSystem<T>().

AddSystem

Constructs a subsystem of type T in-place and registers it with the engine. The engine owns the subsystem. Returns a raw pointer for immediate use — do not store it beyond the engine’s lifetime.

Frame statistics

GetFrameStats() returns a snapshot of the previous frame’s timing breakdown. All times are in milliseconds. Query this once per frame from your application’s OnUpdate().

PresentMode

Typical setup (from EntryPoint.h)

The Windows entry point that ships with the engine shows the canonical startup sequence:
You don’t write main() yourself when you include EntryPoint.h on Windows — this implementation is injected by the header when PRISMA_PLATFORM_WINDOWS is defined. You only need to implement CreateApplication().