game-engine

Custom Rust game engine. World owns all state, everything else is a derived view. Render, UI, audio just read snapshots and do their thing. Not built on top of anything.

Fixed-step deterministic tick loop. Archetype ECS with ~32KiB SoA chunks. Runs headless without a window. March 2026, clean build, ~2,656 tests. Host P0 through P24 done. Audio P0 through P6 done. Editor phases 1 through 6 done. Every Tier 2 crate audited.

Workspace checkcargo check --workspace --all-features clean
Workspace testscargo test --workspace ~2,656 passing
Host lintcargo clippy -W clippy::all clean

Crate Map

Lower tiers can't import higher ones. No circular deps.

Tier 0

engine_core

  • fixed-step tick, 5-stage pipeline
  • TypedCommandBuffer, zero-alloc steady state
  • EventBus, bounded, per-producer, deterministic merge
  • TickClock with O(1) consume, Xoshiro256++ RNG, Lemire range
  • per-thread ring-buffer metrics, CrashContext, replay log

Tier 1

ecs

  • archetype-chunk ECS (~32KiB SoA)
  • generational Entity (u32+u32)
  • Query, Resources, Relations
  • Hierarchy, Snapshots
  • Schedule with 5 stages, Plugin trait
  • SimLoop wrapping TickLoop + Schedule

ecs_derive

  • #[derive(Component, Bundle, Relation)]

Tier 2

Core runtime

scheduler

  • access sets
  • Kahn topo sort
  • wave packing
  • persistent pool
  • shadow mode
  • adaptive LPT

render

  • wgpu 27
  • RenderSnapshot
  • GpuCache<V>
  • LRU eviction
  • debug lines
  • culling

assets

  • cook pipeline
  • AssetServer
  • AssetIndex
  • hot-reload
  • streaming

io

  • blocking thread pool
  • file watcher
  • sqlite writes
  • log flush

Presentation and scene

ui

  • Slint
  • UiSnapshot
  • UiCommands

audio

  • audio thread
  • lock-free
  • ring buf cmds
  • voice pool
  • spatial

scene

  • Transform
  • LocalToWorld
  • MeshInstance
  • Camera, Light
  • extraction sys

mesh_import

  • glTF 2.0 loader
  • MeshData
  • MaterialData
  • entity spawner
  • AssetStorage reg

Tier 3

host

  • winit event loop, wgpu window, input normalization, gamepad
  • Starlark scripting: sandboxed, budgeted, capability-gated
  • native plugin loading: C ABI, NativePluginVTable, ABI versioning
  • lifecycle, profiling via Tracy + Puffin, replay, hot-reload
  • IO boundary dispatch, config wiring for all Tier 2 plugins

Editor Modules

Data Flow

Sim thread is the only writer to World during a tick. Render, UI, and audio consume snapshots on their own threads. GPU handles never cross into sim.

Run Modes

run_headless(tick_count)

Skips the window and GPU entirely. Useful for tests, CI, and replay validation. Build with --no-default-features to drop winit and wgpu.

run_headless_timed(duration)

Same headless path, but driven by a duration rather than a fixed tick count.

run()

Normal windowed app mode with winit, wgpu surface, and the full input pipeline.

run_editor()

Runs sim on a background thread. Each tick does offscreen render, blocking readback, and pushes frames through ViewportPixelBridge to the Slint UI thread.