Architecture
The long version is ARCHITECTURE.md in the engine repository.
Layers
Backends depend on core. Core never depends on a backend; the compiler enforces the direction.
ECS
hecs: archetype-based, minimal, no application framework.- Scheduling, hierarchy and resources are Balaur's own.
Math
- One crate everywhere:
glamx, glam plusPose2,Pose3andRot2, with the rest re-exported. - The same math rapier and kiss3d use. No layer converts between core, physics and rendering.
- Pinned to
libmandscalar-mathin every build, not only those with physics.
The Engine handle
- One cheaply clonable handle over the world, the resources, the command queue and the script host.
- Interior mutability, short borrows.
- Rust systems take it every frame; script bindings capture it. Both sides of the FFI see one state.
- Single-threaded. Threads can live inside a system without changing the facade.
Scene tree
- A node is an entity with
Name,Parent,ChildrenandGlobalTransform. Its localTransformis thetransformcomponent. A node without one sits at its parent. - Node paths, transform propagation and recursive free are core systems.
- Plugins add their own components to the same entities.
The frame
| Rule | |
|---|---|
| Fixed step | FixedUpdate drains one accumulator into whole 60 Hz steps, zero to four a frame |
| Never the frame time | The simulation never sees the measured frame time |
| Deferred structure | A script's spawn or free waits for Last |
The script seam
balaur_scriptis traits and one neutralValue: no language, no dependencies.- A subsystem declares its bindings once against the seam and never names a language.
- A backend implements the host trait and consumes those declarations.
- Rune is the shipped backend. A second language is one crate; physics, input, render, audio and ui do not change.
Plugins
- Wrapping a Rust crate for scripting is one call per entry point, with argument and return conversions inferred.
- One component registration gives the scene key, the runtime API and editor support.
balaur_physicsis the reference implementation.- One
Plugintrait covers both shipping modes: linked in behind a cargo feature, or built as a shared library and loaded at run time. See Plugins.
The workspace
| Crate | Role |
|---|---|
balaur_script | The scripting seam: traits and a neutral value type; no language, no dependencies |
balaur_core | ECS world (hecs), scene tree, scheduler, plugin API, skeletons, glTF and mesh assets, digests, replay, snapshots, pack export |
balaur_script_rune | The Rune backend: host, hot reload, mod files, the debugger, export |
balaur_physics | Rapier plugin; the reference for wrapping a Rust crate for scripting |
balaur_render | Renderable components (shapes, sprites, skinned polygons, meshes) + render module; kiss3d/wgpu backend behind a feature flag |
balaur_animation | Animation clips, the pure sampler, tweens, easing, rig modifiers; the animation module |
balaur_audio | rodio-backed audio module |
balaur_input | Backend-agnostic input snapshot + input module |
balaur_http | http for scripts, delivered into the simulation per tick |
balaur_websocket | websocket for scripts, and a Transport for sessions |
balaur_webtransport | QUIC behind the same Transport, with native datagrams |
balaur_gamend | The Gamend backend (gamend module): login, REST, realtime, server hooks |
balaur_platform | The platform module and the seam a store plugs into: sign-in, achievements, leaderboards, cloud saves |
balaur_apple | Game Center, iCloud and Sign in with Apple behind that seam, plus apple for purchases, notifications and opened URLs |
balaur_plugin | The Plugin trait a module or run-time extension implements, plus the loader |
balaur_ui | Immediate-mode egui API (ui module): panels, widgets, script-defined themes |
balaur | Batteries-included facade: standard_app, boot_project, boot_pack |
balaur_export | Export as a library: packs, fused executables, and the Apple and Android bundles; the editor and the CLI both use it |
balaur_cli | The balaur binary: new, run, export, play, edit, import, replay, api |
balaur_bench | Headless benchmarks: where a frame's time goes, and what scripting costs |