Skip to main content
Every Prisma Engine program follows the same lifecycle: the Engine object is constructed on the stack, initialized, handed an Application subclass to run, and then cleanly shut down. Understanding this sequence is essential — skipping or misordering any step produces a process that either fails to start or exits immediately without rendering a frame.

The EntryPoint pattern

On Windows, EntryPoint.h defines main for you. It constructs an Engine, calls Initialize(), creates your Application via the CreateApplication factory function you implement, runs the main loop via engine.Run(), and shuts down:
You do not write main yourself. Define Prisma::CreateApplication() in your game code and return a heap-allocated instance of your Application subclass. The entry-point header wires everything else together.

Lifecycle steps

1

Engine construction

Allocate the Engine object on the stack and supply an EngineSpecification:
The constructor does not start any subsystems. It only stores the specification.
2

Initialize

Call engine.Initialize(). This starts every registered subsystem — the window, renderer, asset manager, input manager, job system, and ECS world — in the correct dependency order.
After Initialize() returns successfully you can access subsystems via Engine::Get():
3

Run the application

Pass your Application to engine.Run(). This transfers ownership and blocks until the application requests a close or the window is destroyed:
Internally, Run calls your application’s OnInitialize(), then drives the main loop — dispatching events, calling OnUpdate(ts), and calling OnRender() — until Application::Close() is called or the window closes.
4

Shutdown

After Run returns, call engine.Shutdown() to release GPU resources, flush pending I/O, and tear down subsystems in reverse initialization order:
The Engine destructor also calls Shutdown if you omit the explicit call, but calling it explicitly gives you better control over teardown ordering.

Implementing the Application class

Your game code implements Prisma::Application. Override the lifecycle hooks you need:

Minimal game application

The Layer and LayerStack system

Application manages a LayerStack — an ordered list of Layer objects that each receive events, updates, and render callbacks. Layers let you modularize your game into independent slices (e.g., a game layer, a HUD layer, a debug overlay).
Layers are inserted below overlays. Overlays always sit on top, making them suitable for debug panels, HUDs, and ImGui windows. Events propagate from the top of the stack downward (overlays first, then layers). Updates and renders propagate from bottom to top.

Event system overview

Events flow from platform code through the Engine, into your Application::OnEvent, and then down through the LayerStack. Use EventDispatcher to handle specific event types:
Common event types: WindowResizeEvent, WindowCloseEvent, KeyPressedEvent, KeyReleasedEvent, and mouse events.
A common pitfall is implementing OnInitialize() but never entering the engine main loop — for example, calling engine.Initialize() without calling engine.Run(...). The program will start, complete initialization, and then exit immediately without rendering a single frame. Always ensure engine.Run(std::move(app)) is called after Initialize() succeeds.
Use SDL scancode constants for key bindings rather than raw integer values. The engine window layer passes scancodes through its key events: