Runtime

Purpose

Runtime coordinates a single game session: adapter initialization, input polling, simulation scheduling, render-frame handoff, presentation and orderly shutdown. It runs application-defined game hooks rather than prescribing entities, scenes or a world model.

Interface

Types below are in CE::Runtime unless another namespace is shown.

Types and operations

API and purpose

Context
Own compatible adapters and obtain borrowed accessors and tracked worker groups. Adapter catalogue; context ownership.

GameRuntime
Borrow a game/context for one session; block in run() and request shutdown with stop(). Runtime frame boundary.

RuntimeLifecycle, RuntimeLifecycleSnapshot
Read milestones and a retained terminal outcome without borrowing Runtime. Lifecycle observation.

ShutdownEndpoint, ShutdownPolicy
Stage ordinary requests and own the single host decision policy. Stop/failure bypass negotiation. Shutdown protocol.

RuntimeServices, ServiceAttachment
Attach required owner work to maintenance or pre-update phases. Service phases.

WindowState, SimulationView
Read copied selections and attach required sizing through Context sources. Committed views.

CE::Game::AbstractGame
Supply init, update, frame preparation, quiesce and deinit hooks. Game hooks and ownership; shutdown.

CE::Game::TickContext
Read simulation delta, copied dimensions, immutable input and the session stop request. Input and owner threads; tick time.

CE::Application::Startup
Configure the supplied command-line composition path before creating the runtime. Command-line startup; Startup module.

Configuration and enums

Type

Choices and details

RunMode

Sequential updates on platform; Concurrent uses a dedicated simulation thread. Execution and frame handoff.

ExecutionOptions

Lazy owned worker capacity or an application-supplied shared pool. Context worker ownership.

Simulation::TimingOptions, Simulation::Mode

Configure variable/fixed updates, interval and bounded recovery. Timing defaults; fixed steps.

Simulation::LagRecovery, Simulation::UpdateKind

Select dropped excess lag or variable catch-up; identify the kind of the current tick. Catch-up recovery.

CE::Input::PollingOptions, CE::Input::PollingPolicy

Configure completed-poll backlog and spacing independently of simulation mode. Polling backlog.

Start with sequential execution when polling, updates and rendering can share one owner. Concurrent execution keeps platform polling/rendering separate from a slow update, but requires copied observations and retained frame publication instead of live adapter access from another thread. Both modes use the same timing choices.

Usage

Assemble a compatible adapter set into Runtime::Context, implement Game::AbstractGame, then construct Runtime::GameRuntime and call run() on the platform owner. The supplied GLFW/OpenGL factory handles adapter construction; First Game shows the complete application.

        ---
config:
  theme: base
  themeVariables:
    fontFamily: system-ui, sans-serif
    fontSize: 14px
  flowchart:
    htmlLabels: true
    curve: linear
    nodeSpacing: 22
    rankSpacing: 38
    padding: 12
---
flowchart LR
    accTitle: Runtime · simple adapter assembly
    accDescr: Local names omit Runtime::; ambiguous nested namespaces remain qualified. Arrows point toward dependencies. Application roles are rounded; named API operations have rounded corners. Dashed arrows mark optional choices.
    k0["GameRuntime"]:::focal
    k1["Context"]:::focal
    k2["Game::<br/>AbstractGame"]:::focal
    k3["Platform::<br/>DisplaySystem"]:::neighbor
    k4["Input::<br/>System"]:::neighbor
    k5["Rendering::<br/>PresentationSurface"]:::neighbor
    k6["Rendering::<br/>Renderer"]:::neighbor
    k7["Rendering::Resources::<br/>Provider"]:::neighbor
    k0 --> k1
    k0 --> k2
    k1 --> k3
    k1 --> k4
    k1 --> k5
    k1 --> k6
    k1 --> k7
    classDef focal fill:#e7f3ef,stroke:#387d6b,color:#153d33,stroke-width:1.2px
    classDef neighbor fill:#f0f3f8,stroke:#8c9bb1,color:#35445b,stroke-width:1px
    classDef app fill:#fff2df,stroke:#c09452,color:#674515,stroke-dasharray:5 3
    classDef system fill:#eaf0fc,stroke:#617fab,color:#263f69,stroke-width:1.2px
    linkStyle default stroke:#7e8fa7,stroke-width:1.2px

    

Local names omit Runtime:: where unambiguous. Explore this diagram and its other views →

Explore runtime dependencies and application composition, including the tick/frame boundary and shutdown capabilities.

Choose the integration point

Application work

Entry point

Boundary to preserve

Bind devices, upload initial resources, acquire producer endpoints

AbstractGame::init_platform()

Platform/graphics owner; retain acquired handles for later work.

Create simulation-owned controllers and UI, attach automatic view following

AbstractGame::init_simulation()

Simulation owner, with its initial view established before Ready and the first update.

Advance gameplay

AbstractGame::update() with Game::TickContext

Use immutable input and copied sizes; advance state with the selected simulation delta.

Publish draw commands

Frame preparation with Rendering::FrameWriter

Publish retained render state. Preparation can be skipped when no frame slot is free.

Run required recurring module work

Runtime::RuntimeServices

Attach on the initialized owner and retain the returned ServiceAttachment; use events for optional observation.

Request or negotiate shutdown

tick.request_stop(), runtime.stop(), or Runtime::ShutdownEndpoint

Stop is unconditional. Ordinary endpoint requests may be negotiated by the single installed host policy.

The game hook contract defines hook ownership and cleanup. The frame boundary explains when each operation runs in sequential and concurrent modes.

Uses

These dependencies supply the session’s adapters, data and execution boundaries. Context owns display, presentation, renderer and resource adapters, and owns or explicitly borrows input. GameRuntime borrows the context and game.

Dependency

Runtime’s responsibility

Game::AbstractGame

Invoke initialization, update, preparation and cleanup hooks on their owners.

Platform::DisplaySystem, Platform::Window

Select copied sizes/focus and sample native close intent on platform. Display.

Input::System

Initialize and poll the adapter; transfer complete observations into ticks. Input.

Rendering::Renderer, Rendering::PresentationSurface

Consume complete retained frames, maintain graphics resources and present. Rendering.

Rendering::Resources::Provider

Keep the resource backend alive through frame and game-resource release. Resources.

Events::EventBus

Route context observations; required view/service work uses owned attachments. Events.

Runtime::PlatformDispatcher, Runtime::SimulationDispatcher

Open, service and close owner queues. Dispatch.

Workers::Group

Close and settle context-tracked jobs while required platform work can progress. Workers.

Used by

Consumer

How it participates

Application entry point, optionally Application::Startup

Select adapters/options, retain game and context, then run one session. Context assembly.

Application game/controllers

Implement the hooks and read TickContext; Runtime supplies no scene or entity model. Character tutorial.

GUI sessions

Attach required simulation-view sizing and step-time integration where supported; the application retains session lifetime.

Audio source

Opt into maintenance pumping when desired; audio lifetime remains application-owned.

Host or tooling observer

Retain Runtime::RuntimeLifecycle for current/terminal state without borrowing the runtime. Lifecycle observation.

Contracts

A context and runtime each support one session. Borrowed game/context/input objects must survive all use and cleanup. init_platform() may upload resources and register bindings; update() and frame preparation must not perform graphics operations when simulation is concurrent. A borrowed tick, frame writer or pass writer is valid only for its hook call. init_simulation() runs on the simulation owner with services and the initial view ready, before Ready, timing and the first update. Initialization and deinitialization hooks default to no-ops; use constructors for setup without runtime/thread dependencies.

Input observation time and simulation delta have distinct meanings. Rendering sees complete published snapshots. Frame preparation may be skipped when no slot is free, so it must not advance essential game state. Hook failures stop the session; cleanup preserves the first failure while reporting later ones.

Lifecycle

The application constructs adapters/context before running. Runtime initializes input and graphics, attempts init_platform(), then establishes the selected simulation owner/view and calls init_simulation(). Each cleanup hook pairs with its attempted initialization and must tolerate partial failure.

Shutdown stops new context-group submissions and simulation, servicing accepted platform dependencies while simulation closes its dispatcher, calls deinit_simulation() on its owner, and joins. quiesce() then stops external producers and invalidates borrowed registrations without destroying dependencies still needed by accepted work. After that work settles and retained frames recycle, deinit_platform() releases game resources while adapters remain alive. Input detaches before its window disappears; graphics then closes. An injected worker pool’s unrelated groups remain usable.

Execution

The caller of run() owns platform polling and graphics operations. Sequential mode also updates/prepares on that thread using one frame. Concurrent mode gives updates and preparation to one simulation thread and uses three frame slots. Tick input and window/framebuffer dimensions cross as values; accessors do not marshal live adapter operations onto their required thread.

Integration

A game requests graceful shutdown from its update hook:

void update(const CE::Game::TickContext& tick) override {
    if (tick.input.button(quit_action).pressed()) {
        tick.request_stop();
        return;
    }
    // Advance application-owned state using tick.delta_seconds.
}

quit_action is an application-defined action registered during initialization. The stop request does not interrupt the current hook; return when further work is unnecessary. First Game shows the complete main function and hook wiring.

Limits and further reading

There is no built-in world, entity, physics or scene lifecycle. The runtime does not automatically own toolkit sessions or audio. Read the detailed frame and shutdown contract, simulation timing, context assembly and failure reporting. Public declarations live in Context, GameRuntime and AbstractGame.