cinder.app
cinder.app #
Source: cinder/app/__init__.mojo
Application runtime: subsystems, the fixed-step game loop, windowed and headless modes.
cinder.app.app #
Source: cinder/app/app.mojo
The application runtime: owns every subsystem, runs the fixed-step game loop and renders. App works in two modes. Windowed: an SDL window, a swapchain and the ImGui debug overlay. Headless (AppConfig.headless, the --headless flag of the sample): no window, no audio device, frames render into an offscreen texture that read_frame reads back, so tests and benchmarks drive exactly the same loop. A Game supplies the per-step and per-frame logic. Subsystems that hand out pointers to themselves live in Boxed heap cells so the App value can move. Fields are declared in destruction order: the overlay and gameplay systems first, GPU objects next, the native library last.
comptime READBACK_ALIGN = 256— Row alignment in bytes of the headless readback buffer; each rowread_framecopies is padded to a multiple of it.
def ui_consumes_event #
def ui_consumes_event(ev: Event, ui_wants_mouse: Bool, ui_wants_keyboard: Bool) -> BoolWhether the debug overlay swallows ev instead of the game's InputMap. While ImGui wants the mouse, mouse presses, motion and wheel go only to the overlay; while it wants the keyboard, key presses do. Key and mouse button releases always reach the input map: a key or button held when the overlay takes focus would otherwise stay held there.
struct AppConfig #
struct AppConfig(Copyable, Movable)Settings read once by App.__init__; parse_app_args fills them from the command line. Defaults: 1280x720 windowed, 60 Hz fixed step, audio and debug UI on, profiler off, 3 worker threads.
Fields:
-
title: String -
width: Int -
height: Int -
headless: Bool -
fixed_hz: Float64 -
render: RenderSettings -
layers: LayerConfig -
audio: Bool — Create the audio engine (headless apps use miniaudio's device-less engine). -
debug_ui: Bool — Create the ImGui overlay (windowed only). -
profile: Bool — Start the Tracy client at startup. -
worker_threads: Int -
__init____init__( out self, title: String = String("Cinder"), width: Int = 1280, height: Int = 720, headless: Bool = False, )
trait Game #
trait GameGameplay hooks called by App.run_frame.
startstart(mut self, mut app: App) raises
Called once, at the start of the firstrun_frameand before its events are polled.fixed_updatefixed_update(mut self, mut app: App, dt: Float32) raises
Called once per fixed step with the step length in seconds, after physics has stepped and body transforms were pulled into the world.updateupdate(mut self, mut app: App, dt: Float32) raises
Called once per frame with the frame time in seconds, after the fixed steps and before animation, transform propagation, audio and rendering.draw_uidraw_ui(mut self, mut app: App) raises
Called while the debug overlay is built (windowed withdebug_uionly, on frames that acquired a swapchain image), before the engine's own windows; make ImGui calls here.
struct App #
struct App(Movable)The engine runtime: owns the native library, the platform and window (windowed), the GPU device, renderer, ECS world, physics, audio, animation, input map, scene registry and assets, and drives them from run_frame. Construction raises when a subsystem fails to start. Fields are destroyed in declaration order, the overlay first and lib last. Use it from the main thread, where Platform must live.
Fields:
-
debug_ui: Optional[DebugUi] -
assets: Optional[Boxed[AssetServer]] -
anim: AnimationSystem -
audio: Optional[AudioEngine] -
physics_sync: PhysicsSync -
bridge: RenderBridge -
physics: Boxed[PhysicsWorld] -
input: InputMap -
world: World -
scene: RenderScene -
registry: SceneRegistry -
logs: MemorySink -
events: List[Event] -
swapchain: Optional[Swapchain] -
target_view: TextureViewHandle -
target_tex: TextureHandle -
readback: BufferHandle -
renderer: Boxed[Renderer] -
res: Boxed[Resources] -
gfx: Boxed[Gfx] -
window: Optional[Boxed[Window]] -
platform: Optional[Boxed[Platform]] -
jobs: Boxed[JobSystem] -
profiler: Profiler -
clock: Clock -
fixed: FixedStep -
config: AppConfig -
width: Int -
height: Int -
frame_index: Int -
fixed_steps: Int -
quit_requested: Bool -
started: Bool -
count_allocations: Bool — When set,alloc_*record Mojo heap allocations per phase of the last frame (needs the allocation counter library preloaded; see tests/perf). -
alloc_fixed: Int -
alloc_update: Int -
alloc_anim: Int -
alloc_propagate: Int -
alloc_audio: Int -
alloc_render: Int -
alloc_other: Int -
frame_ms: Float64 — CPU time of the lastrun_frame(ms). -
physics_ms: Float64 — Time spent in physics steps during the last frame (ms). -
render_ms: Float64 — Time spent building and submitting the frame (ms), without presentation waits. -
lib: NativeLibrary -
__init____init__(out self, var config: AppConfig) raises -
mount_assetsmount_assets(mut self, root: String) raises
Attaches a cooked-asset directory (itsmanifest.txt). -
loglog(mut self, level: LogLevel, category: String, message: String)
Records a message inlogs, the in-memory sink shown in the debug UI's Log tab. -
run_framerun_frame[ G: Game ](mut self, mut game: G, frame_seconds: Float64 = -1.0) raises -> Bool
One frame: events, fixed steps, per-frame update, render, present.frame_secondsoverrides the measured frame time (tests and benchmarks run deterministically). Returns False once a quit was requested. -
read_frameread_frame(mut self) raises -> Image
Headless only: the last rendered frame as an image. -
request_quitrequest_quit(mut self)
Makesrun_framereturn False. Requested fromfixed_update,updateordraw_ui, the current frame still completes; later calls return right after polling events. -
gpu_error_countgpu_error_count(self) -> Int
Uncaptured wgpu validation errors seen since the device was created. -
live_objectslive_objects(self) -> Int
Physics objects plus audio sounds and buses alive: the game-owned objects that must be zero before shutdown (the leak report). GPU objects are not counted: the engine's own render targets, pipelines and renderer meshes stay alive for the App's whole life, so a total including them is never zero. Useres[].live_counts()for GPU resources;Resourcesreleases and counts leftovers when it is destroyed.
cinder.app.cli #
Source: cinder/app/cli.mojo
Command-line options shared by every Cinder executable (--headless for tests and benchmarks).
def parse_app_args #
def parse_app_args( args: List[String], mut config: AppConfig ) raises -> List[String]Applies engine options to config and returns the arguments it did not consume. Options: --headless, --profile, --no-audio, --no-debug-ui, --width N, --height N, --title TEXT. Everything else (positional arguments and the program's own options) is returned for the caller.