DocsAPI reference

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 row read_frame copies is padded to a multiple of it.

def ui_consumes_event #

mojo
def ui_consumes_event(ev: Event, ui_wants_mouse: Bool, ui_wants_keyboard: Bool) -> Bool

Whether 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 #

mojo
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 #

mojo
trait Game

Gameplay hooks called by App.run_frame.

  • start start(mut self, mut app: App) raises
    Called once, at the start of the first run_frame and before its events are polled.
  • fixed_update fixed_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.
  • update update(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_ui draw_ui(mut self, mut app: App) raises
    Called while the debug overlay is built (windowed with debug_ui only, on frames that acquired a swapchain image), before the engine's own windows; make ImGui calls here.

struct App #

mojo
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 last run_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_assets mount_assets(mut self, root: String) raises
    Attaches a cooked-asset directory (its manifest.txt).

  • log log(mut self, level: LogLevel, category: String, message: String)
    Records a message in logs, the in-memory sink shown in the debug UI's Log tab.

  • run_frame run_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_seconds overrides the measured frame time (tests and benchmarks run deterministically). Returns False once a quit was requested.

  • read_frame read_frame(mut self) raises -> Image
    Headless only: the last rendered frame as an image.

  • request_quit request_quit(mut self)
    Makes run_frame return False. Requested from fixed_update, update or draw_ui, the current frame still completes; later calls return right after polling events.

  • gpu_error_count gpu_error_count(self) -> Int
    Uncaptured wgpu validation errors seen since the device was created.

  • live_objects live_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. Use res[].live_counts() for GPU resources; Resources releases 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 #

mojo
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.

View as MarkdownSource: docs/api/app.md