renew, an AI-first game engine in Rust

A game engine in Rust, built to be operated. The simulation underneath is bit-deterministic: same build, same seed, same inputs, same result, byte for byte.

What renew is

Most engines are built around an editor, and everything else reaches the engine through whatever that editor exposes. renew is built the other way around. Every capability is a library with a command-line face and machine-readable output, so a developer at a terminal, a build script and an autonomous agent all drive it the same way. That is what AI-first means here.

Status: early development. The crates are published at 0.1.1, but APIs change without notice and no module is stable yet, so this is not something to start a shipping game on today. Everything on this page exists and is covered by tests.

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 fall out of that, because the simulation was built this way from the start.

Code-first, CLI-first

Build, test, benchmark, asset work, running samples, all headless. Every command takes --json and emits a schema-versioned document a script can depend on.

Twenty-nine crates, five required

Everything outside the core can be removed. CI builds and tests one configuration per optional crate, with that crate and everything depending on it excluded.

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.

See it running

Every picture below was produced by the sample beneath it and is committed in the repository.

A voxel arena seen from an isometric angle, its walls and floor lit
cube
A voxel world with a walking, jumping, block-breaking player.
First-person view of a voxel floor with a block broken out of it and debris particles
cube
Breaking a block, with the particle pool stepped at the simulation's cadence.
A side-scrolling game frame: a yellow bird between green pipes on a blue sky
glide
A small complete game, playable in a window or driven from a trace.

Six samples ship with the engine. The four simulation samples run headless and answer with a digest, and those are the runs CI checks on every target at once.

$ cargo run -p renew-sample-cube --bin cube
cube script=stand source=script ticks=600 digest=0xcbc2871e466a6bfc solids=5012 broken=0 placed=0 grounded=true

$ cargo run -p renew-sample-leap --bin leap
leap script=stand ticks=600 digest=0xd7058b85479adeb4 grounded=true wall=false

$ cargo run -p renew-sample-chess --bin chess
chess count depth=4 nodes=197281 result=ongoing

Determinism you can check yourself

One command runs a pinned set of simulations and writes exactly what they produced:

$ cargo run --bin renew -- determinism --emit windows.json
wrote 15 digests for windows/x86_64 to windows.json
{
  "schema_version": 1,
  "os": "windows",
  "arch": "x86_64",
  "toolchain": "rustc 1.97.1 (8bab26f4f 2026-07-14)",
  "digests": {
    "chess/play-60/digest": "0x6bf0be22d95711ee",
    "cube/build-900/digest": "0xce632722e5698fa1",
    "cube/patrol-600/digest": "0x29559b5af5e634d2"
    // 12 more, in key order
  }
}

CI produces that file on five targets every commit and holds them against each other. Any disagreement fails the build.

Making a simulation reproduce bit-for-bit across targets 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 run --bin renew -- build
cargo run --bin renew -- test

# a voxel world, drawn to a window
cargo run --bin renew -- --features window run cube -- --window

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, ui-compile, determinism, doctor. Each one takes --json and answers with a single document carrying a schema_version.

Modules

Everything outside the five core crates can be removed. CI builds and tests one configuration per optional crate on every commit, with that crate and its dependents excluded.

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-replayRecording a run and playing it back: event-to-trace translation both ways, and a tick-indexed loaderbootstrap
renew-traceThe recorded-input file format: a line-oriented text codec whose reader refuses anything it does not understandbootstrap
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
renew-volumeA chunked voxel volume: read, write, pick along a ray, sweep a box, and the merged surfacebootstrap
renew-netInputs-only lockstep datagrams, with a reader that proves each fact rather than trusting itbootstrap

Twenty-seven of the twenty-nine are published on crates.io at 0.1.1. Maturity runs bootstrap, then internal, then stable. A module never claims a level it has not earned, and nothing here is stable yet.

Platforms

TargetCI compilesTest suiteDigests matchDraws a frame
Windows, Linux, macOSyesyesyesyes
Androidyes, and lintsthe pinned simulations onlyyes, on an emulatornot yet in CI
iOSyes, and lintsthe pinned simulations onlyyes, on a simulatoryes, on a simulator

The table names the machine each result came from, because an emulator is not a phone and a simulator is not a device. Drawing on Android needs a runner with Vulkan 1.3; the emulator offers 1.2.

Graphics reach the GPU through Vulkan via ash, with MoltenVK on Apple platforms, and windowing through winit. No Vulkan type appears in the rendering interface's public API, which is what keeps the backend replaceable.

Quality gates

Every commit on main clears all of these. The test suite runs on all three desktop platforms; the rest run once, on Linux:

GateEnforced by
Format and lints, zero warningsrustfmt and clippy with a strict deny-set
Testscargo test --workspace on Windows, Linux and macOS, plus a release build
Line coverageEvery line of engine code, or an exemption naming its reason. The gate fails in both directions
No panicking shortcutsunwrap, expect and panic denied outside tests; todo, unimplemented and dbg! denied everywhere
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
DeterminismFive targets emit their digests and are compared against each other
Sanitizers, Miri, fuzzingScheduled runs against the parsers and the threaded code

Built to be operated

Most engines are built around an editor, and everything else reaches the engine through whatever the editor happens to expose. renew is built the other way around. The machine-operable surface is the primary one: 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.

That is what AI-first means here. A developer at a terminal, a build script, a continuous integration job, and an autonomous agent all drive the engine through exactly the same commands and read exactly the same output, because there is only one surface to drive. An editor will arrive in time, and it will be a client of these APIs like everything else, never a privileged one.