A 3D physics world that replays exactly.
si-rpg-engine steps physics at a fixed 64 steps per second, records a fingerprint of the world after every step, and can rebuild any run from its starting seed and the inputs it accepted, bit for bit. The physics is Rust compiled to WebAssembly, and the same build gives the same answer in the JavaScript engines behind Chrome, Firefox, and Safari, and on both x64 and ARM processors.
Check it
npm ci && npm run verify
Replay a run
npx play proposals.json --log out.json && npx replay out.json
Load a world
npx load world worlds/crate-and-door.json
What it guarantees
Each of these is checked by the test suite on every commit.
The same answer everywhere
One build of the physics produces the same fingerprint in V8, SpiderMonkey, and JavaScriptCore, and on x64 and ARM64. The build fails if any of them disagrees.
Exact replay
A run is its starting seed plus the inputs that were accepted. Replaying them rebuilds every step, and when two runs differ, the tools name the first step, body, and value where they part. A failing check saves one file that reproduces the failure with a single command.
Save and restore
Restore a world by replaying its inputs, by copying the physics module's memory, or from the tick's own save of its whole state. Each is tested to continue exactly as the original run did.
Real 3D physics
Boxes fall, slide, stack, tip, and tumble; a character climbs steps and slopes and walks over terrain. The physics is the Rapier engine in its deterministic mode, compiled to one WebAssembly file with a pinned checksum.
Physics fixed where it was wrong
The suite found four ways the physics went wrong: a walker losing its stride, a push landing at another body's contact points, a push that left out how a body turns, and a step that sank into the floor. Each is fixed in the engine's own copy of the routine, and a test shows the copy without its fix moves exactly as Rapier does.
Worlds explored before they run
Before a world is admitted, the engine explores every state its characters can reach with the actions it allows. A zone nothing can reach, or a body pushed out of the world, is refused with a recording that reproduces it.
A change measured against its parent
The bench runs a change and the build before it side by side, each in a process of its own, and reports which inputs reach the change, where the two runs first part, and what fails only on the change. Every verdict comes from the engine, none from a model, and its tests plant changes with known effects to check that it reports each one.
Content checked before it runs
World files and new character actions are validated when they load. A file that fails is rejected with the reason, and the running world does not change.
AI suggests, rules decide
A language model can suggest what a character does or comes to believe, only through a role the engine declares. Hand-written rules hold each suggestion to what its role allows and check it against the world as it is when it arrives, and every call to the model is recorded, so a run replays without it.
Try it
You need Node 20 or newer and the Rust toolchain. Every command explains itself with --help.
Build and check
git clone https://github.com/mcp-tool-shop-org/si-rpg-engine.git
cd si-rpg-engine
npm ci
npm run verifyRecord and replay a run
npx play proposals.json --seed 7 --log out.json
npx replay out.jsonLoad a world and watch it
npx load world worlds/crate-and-door.json
npx host --world worlds/crate-and-door.json
# then open http://127.0.0.1:4173