Runtime architecture and backend boundaries

The selected backend is composed through CE::Runtime::Context; CE::Runtime::GameRuntime uses its display, window, input, presentation, renderer, and resource contracts. The current GLFW/OpenGL implementation and the in-memory integration probe follow those same contracts. The application guide shows composition and game hooks; architecture validation describes isolation and integration checks.

CE::Game::AbstractGame defines application hooks and consumes copied tick values. CE::Runtime owns session composition and execution; CE::Runtime::Simulation owns timing selection. CE::Platform supplies neutral display/window contracts, with GLFW implementations in CE::Platform::GLFW. CE::Rendering supplies frame, camera and renderer contracts, with native implementations in CE::Rendering::OpenGL. These owners describe responsibility rather than changing the thread or lifetime boundaries below.

Applications may use command-line startup to validate execution, polling, timing and backend options before constructing a context. The result owns that context and supplies the runtime configuration; CE::Runtime::GameRuntime::run() owns adapter/game initialization and shutdown. CE::Application startup support is separate from the Engine and OpenGL libraries and does not select a backend dynamically. The optional Linux Debug terminal attaches at process startup rather than becoming a CE::Runtime::Context adapter. Its native code and viewer lifetime belong to the module; the CE::Application::DebugTerminal support hook does nothing without a supplied implementation.

Boundary

Contract

CPU asset data

Vertex layouts, indexed sprite/tileset and shader recipes, grid generation, owned RGBA pixels and shader-byte snapshots have no graphics-context dependency. Loader preparation runs independently of a provider.

Display and presentation

CE::Platform::DisplaySystem owns a selected window implementation. CE::Platform::Window and monitor snapshots carry neutral data; CE::Rendering::PresentationSurface presents. GLFW handles remain inside the platform/backend implementation. The renderer does not own the display.

Input

CE::Input::System supplies State plus independently requested ordered Events/Text. GLFW/Gainput translation stays in its adapter; games consume tick values and routed views. The default factory owns input; an explicit-reference overload borrows it.

Draw and material

Simulation writes complete ordered CE::Rendering::Frame passes. CPU submission helpers resolve sprite, tile, graphic, and glyph packets retaining geometry/material generations and copied values. CE::Rendering::OpenGL::PipelineBindings maps contract keys to native names; each pipeline applies full fixed state.

Resource creation and caches

CE::Rendering::Resources::Provider uploads decoded pixels and transient vertex spans, creates font atlases, and links programs. Optional sampler and shader-recipe builders reject unsupported requests. Cache readers retain handles under shared locks; construction and retired-handle destruction stay outside locks. One provider/loading thread binds the singleton caches until teardown.

Composition and scheduling

One runtime session owns platform polling and presentation. Concurrent mode adds one simulation worker and three reusable frame slots. platform_dispatcher().submit() transfers owned resource requests with future results; shutdown cancels pending requests before game cleanup.

OpenGL lifetime

Active resource use requires the owner thread and its actual current context. Handles retire without OpenGL calls from their destructors. Renderer shutdown restores its context, deletes tracked handles, closes their lifetime, and releases the context. Failed destructor cleanup invalidates retained handles.

Portable integration

The in-memory display/window, input, presentation, renderer, and resource provider exercise both runtime modes without OpenGL/GLFW headers. Aggregate regressions cover lifecycle, dispatch, cache publication, materials, preparation, and input routing.

Application APIs

Use engine.display(), engine.window(), and engine.surface() for the selected platform and presentation contracts. Use engine.resources() for backend asset creation after renderer initialization. Construct an owned CE::Assets::Loading::Loader(root) for each root. manifests() returns a retained immutable snapshot; singleton compatibility rejects a different root after its first initialization.

The loading guide owns preparation/publication and application bootstrap; the render guide owns program/material construction and packet resolution. Optional audio is application-owned outside the runtime adapter graph.

Execution and shutdown

Games request shutdown from update() with tick.request_stop(). The tick carries the runtime’s shared stop state, so games need no runtime singleton or callback wiring. Applications holding the runtime can still call CE::Runtime::GameRuntime::stop(); both requests use the same normal cleanup sequence. The stop request and tick lifetime contracts are in runtime-frame-boundary.md.

Platform and simulation requests use separate dispatchers with safe saved submission endpoints. CE::Events::EventBus owns persistent registrations; delivery adapters select platform, simulation, or serial worker-stream execution. CE::Runtime::Context creates tracked worker groups on a lazy owned pool or an injected shared pool. The dedicated simulation thread remains separate from that general CPU capacity. See thread-dispatch.md, event-delivery.md, and worker-execution.md.

The frame boundary owns shutdown ordering, including producer quiescence and accepted-work completion. Native callback and emergency fallback boundaries are in failure-reporting.md.

Current limits

The status inventory records source-backed capabilities and known gaps at its review baseline. The planning catalogue links their owning plans; each subject guide defines its current capability limits.