DocsEngine design

Cinder architecture

Module map #

Dependencies point downward only. A module may import from the layers below it, never from the same layer except where noted, and never from above.

sample/                 third-person sample game (Mojo), a `Game` run by cinder/app
  └── cinder/app        App runtime: owns every subsystem, fixed-step loop, headless mode, CLI
        └── cinder/tools      ImGui debug overlay (inspector, asset browser, render graph, log)
        └── cinder/{render,physics,anim,audio,input,assets,scene}
              └── cinder/ecs            archetype ECS, queries, command buffers, hierarchy, scheduler
              └── cinder/gfx            safe typed wgpu layer, shader manager, hot reload, debug draw
              └── cinder/platform       SDL3 window/input/gamepad, surfaces, ImGui event forwarding
                    └── cinder/core     log, assert, arena, handles, ring, math, jobs, time, fs, profile, boxed
                          └── cinder/ffi    generated bindings + layout tests (never hand-edited)
                                └── native/   libcinder_native (C11 shim) + vendored C/C++ libs
Module Language Responsibility
native/ C11 (shim), C/C++ (deps) Single shared library libcinder_native. Wraps wgpu-native, SDL3, joltc, miniaudio, cgltf, stb_image, KTX, meshoptimizer, MikkTSpace, dcimgui + backends, Tracy, flecs (benchmark only). Owns every callback and the lock-free event queues. libcinder_alloccount is a separate LD_PRELOAD library for the allocation test.
cinder/ffi Mojo (generated) Raw bindings for each native header. Generated by tools/bindgen (ADR-0005), committed, verified by the layout test.
cinder/core Mojo Logging, assertions, arenas, generational handles, rings, SIMD math (core/math), work-stealing job system, time, filesystem, Tracy zones (profile), heap cells with stable addresses (boxed). No GPU or window I/O.
cinder/platform Mojo SDL3: window, events, input, gamepad, surface creation per OS, forwarding events to ImGui. The only module with per-OS branches.
cinder/gfx Mojo Typed handles over wgpu (Resources), ownership and leak accounting, WGSL shader manager with hot reload, validation surfacing, swapchain, debug draw.
cinder/ecs Mojo Archetype storage, typed queries and cached QuerySpecs, change ticks, command buffers, hierarchy and transform propagation, access-declared system scheduling on the job system.
cinder/render Mojo + WGSL Frame graph, clustered forward+, cascaded and atlas shadows, IBL, GTAO, bloom, tone mapping, FXAA, MSAA, culling, LODs, skinning, morph targets, debug views. Allocation-free in steady state.
cinder/assets Mojo glTF import, cooked formats, incremental cooker, KTX2 textures, AssetServer (async loads, refcounts, hot reload).
cinder/scene Mojo Text and binary scene formats with migrations, component registry, ECS to render-scene bridge (RenderBridge), glTF spawning into the ECS.
cinder/physics Mojo Safe layer over joltc: world, shapes, bodies, events, casts, CharacterController, ECS sync with interpolation (PhysicsSync).
cinder/anim Mojo Skeletons, clip sampling, blend trees, crossfades, root motion, events; one job per animator.
cinder/audio Mojo Buses, one-shots, streams, spatialisation over miniaudio; ECS sources and listener.
cinder/input Mojo Action/axis mapping over keyboard, mouse and gamepad; runtime rebinding; text save/load.
cinder/app Mojo App runtime and the Game trait: subsystem ownership, fixed-step loop, windowed or --headless, allocation accounting, CLI parsing.
cinder/tools Mojo ImGui debug overlay: frame graph, entity inspector, asset browser, render graph view, log console.
sample/ Mojo The sample game: components, levels, settings, gameplay (ADR-0014).
tools/ Mojo, Python, shell Cooker CLI, bindings generator, lint, test drivers, asset fetchers, benchmark checker.
bench/ Mojo Benchmarks writing JSON (stress, sample_bench, ecs_bench) and their baselines; see docs/BENCHMARKS.md.
tests/ Mojo, C (CTest) Unit, golden-image, replay, fuzz, playthrough and allocation tests.

The C boundary #

  • One shim, one shared library, flat C ABI (cinder_native.h, C11).
  • Pull model. C callbacks (wgpu async requests, device lost, uncaptured errors, Jolt contacts, miniaudio data, SDL log) write fixed-size events into fixed-capacity SPSC/MPSC lock-free rings inside the shim. Mojo drains them once per frame on the main thread. Mojo code never executes on a C thread unless spike 4 proves it safe and an ADR records that (ADR-0003).
  • Generated raw bindings live in cinder/ffi and are never edited by hand. A C program emits sizeof/alignof/offsetof for every bound struct and every enum value; a generated Mojo test asserts identical values. Mismatch fails CI.
  • Safe wrappers: one distinct handle struct per resource type, ownership through __deinit__, explicit lifetimes for borrowed C strings and views, each shared library loaded exactly once, every unsafe_ call annotated with # SAFETY:.

Threading model #

  • Main thread: SDL event pump, window, presentation (wgpuSurfacePresent), ImGui.
  • Job system (cinder/core/jobs): one worker per physical core minus one, work-stealing deques, a per-frame dependency graph. Everything else (culling, animation, ECS systems, asset decode, physics step through Jolt's own job system adapter) runs there.
  • Shared state crosses threads only through jobs, atomics or documented locks named in docs/THREADING.md.
  • Audio: miniaudio's device thread runs in C only; it reads a lock-free command ring and never calls Mojo.

Frame loop #

Fixed 60 Hz simulation with accumulator (App.run_frame: poll events, fixed steps with physics and Game.fixed_update, Game.update, animation jobs, transform propagation, audio sync, render-scene bridge, render, ImGui, present or offscreen readback). Per-frame memory lives in persistent scratch fields that are cleared, never freed, between frames; steady state performs zero heap allocations from Mojo code (asserted by tests/perf/test_zero_alloc.mojo, ADR-0014).

Conventions (fixed) #

Right-handed, Y up, −Z forward, metres, column-major matrices, reverse-Z with infinite far plane, linear lighting, sRGB render targets, RGBA16F intermediates. Recoverable failures raise typed errors; broken invariants abort with a message.

View as MarkdownSource: docs/ARCHITECTURE.md