renew, a game engine in Rust

A game engine in Rust built for the long haul, and built to be operated rather than merely used. The simulation core is deterministic by construction: same build, same seed, same inputs, same result, bit for bit.

What renew is

renew is an open-source game engine written in Rust. Every capability is a library with a command-line face and machine-readable output, so a person, a script, or an agent drives the engine through exactly the same surface.

Status: early development. Pre-0.1. APIs are unstable, modules are still moving through the maturity ladder, and this is not yet ready to build a game on. What is here is real, tested, and honest about what it is.

Deterministic simulation

Fixed timestep over integer nanoseconds, Q47.16 fixed point, no wall-clock reads, no unseeded randomness, no iteration-order-dependent state. Replay and lockstep are a foundation rather than a retrofit.

Code-first, CLI-first

Build, test, benchmark, asset work, running samples, all headless. Every command takes --json and emits a schema-versioned document. A GUI, when it arrives, is a client of the same APIs.

Modular to the core

Twenty-seven engine crates, five of them core. Everything else is optional and removable behind an explicit interface, enforced by CI rather than by good intentions.

Measured, never assumed

Performance claims arrive with numbers and the configuration that produced them. The steady-state frame loop is held to zero heap allocations through the engine's allocators, counted in dev builds.

Determinism you can check yourself

hello-engine is the current proof of life. A fixed-timestep accumulator driven through 60 frames of deliberately uneven frame times, reading no clocks at all:

$ cargo run --bin hello-engine
hello-engine 0.1.1
fixed timestep: 16666667 ns
frames simulated: 60
time submitted: 1245000015 ns
ticks executed: 74
time pending: 11666657 ns

Run it twice. Run it on another machine, or another OS. Every byte is identical, and that is the property everything else in the engine is built to preserve.

Making a simulation reproduce bit-for-bit on three platforms sets out what that property costs in practice: why the arithmetic is fixed point rather than floating, why the frame loop cannot read a clock, and why a digest compared against a committed constant proves nothing about a second machine.

Quick start

Requires stable Rust 1.97 or newer.

git clone https://github.com/renew-engine/renew
cd renew
cargo build --workspace
cargo test --workspace
cargo run --bin hello-engine

One binary drives the workspace the same way for people, scripts, and CI:

cargo run --bin renew -- help

configure, build, test, bench, run, record, replay, lint, check, coverage, modules, asset-pack, asset-inspect, determinism, doctor.

Modules

Every module is independently buildable, testable, and, outside the minimal core, removable. CI proves the last part on every commit, one crate at a time.

CrateWhat it doesMaturity
renew-diagLog records, severity levels, and the sink interface the engine reports throughinternal, core
renew-eventThe event vocabulary (key codes, pointer buttons, event shapes) as plain datainternal, core
renew-mathVec2/3/4, Mat4, Quat, Aabb3, with documented layout and branchless kernelsinternal, core
renew-memoryLinearArena, a generation-checked Pool<T>, and a counting global allocatorinternal, core
renew-platformThe engine's only doorway to the OS: clock, files, named threads, windowinternal, core
renew-fixedQ47.16 fixed-point arithmetic, the number type the simulation is written inbootstrap
renew-frameThe fixed-timestep loop: an accumulator over integer nanoseconds, clock passed inbootstrap
renew-ecsSparse-set storage with a defined iteration orderbootstrap
renew-jobsA fixed-size worker pool with a deterministic-chunk parallel_forbootstrap
renew-rngSeeded, reproducible random numbers: PCG32 with derived per-domain streamsbootstrap
renew-inputInput state and mapping, over the event vocabularybootstrap
renew-replayInput traces as files: record a run, replay it, compare the digestsbootstrap
renew-traceSimulation digests, the hash the cross-platform determinism lane comparesbootstrap
renew-physics2dBodies, shapes, broadphase, SAT narrowphase, raycasts, sweeps, slide resolutionbootstrap
renew-physics3dThe same surface in three dimensions, axis-aligned onlybootstrap
renew-sceneLocal placements, parenting, and a propagation pass composing them over entity storagebootstrap
renew-rhiThe GPU doorway: Vulkan through ash, behind an interface naming no Vulkan typebootstrap
renew-render2dSprites from an atlas, one instanced drawbootstrap
renew-render3dIndexed geometry, depth-tested, in submission orderbootstrap
renew-cameraLook-at view, reversed-depth perspective, and a blend between ticksbootstrap
renew-snapshotTwo captures of one slot space blended by the interpolation factorbootstrap
renew-particlesA fixed-capacity particle pool stepped at the simulation's cadencebootstrap
renew-uiA widget tree solved in fixed point inside the simulationbootstrap
renew-ui-renderRetained snapshots blended at display rate, clipped on the CPU, emitted as spritesbootstrap
renew-audioMixing and playback, behind the platform's device seambootstrap
renew-assetContent-addressed asset packs, every entry verifiable against its digestbootstrap
renew-pngPNG encoding with no dependencies: pixels in, the bytes of a file outbootstrap

Maturity runs bootstrap, then internal, then stable. A module never claims a level it has not earned, and nothing here is stable yet.

Quality gates

Every commit on main clears all of these, on Windows, Linux, and macOS:

GateEnforced by
Format and lints, zero warningsrustfmt and clippy with a strict deny-set
Tests, debug and releasecargo test across the three-platform matrix
Line coverage100% of every line not individually exempted, each exemption naming its lines and its reason
No panicking shortcutsunwrap, expect, panic, todo, dbg! denied outside tests
unsafe denied by defaultWorkspace-wide unsafe_code = "deny", and every opted-in block states the invariant that keeps it sound
Module graph is a DAGCrate manifest and dependency-graph check (renew check)
Optional modules stay removableOne configuration per optional crate, each excluding that crate and its dependents, all built and tested
Licenses and advisoriescargo-deny, over the full dependency tree
Sanitizers and MiriScheduled nightly runs (ASan, TSan, Miri)

What "AI-first" means here

Every capability is headless, scriptable, and emits schema-versioned JSON beside its human-readable output, so nothing about the engine requires a person in front of a screen. It does not mean the engine ships AI features. It means the machine-operable surface is the primary one, and the GUI, when it arrives, will be a client of it like everything else.