Deterministic 2D rigid-body physics for .NET, written from first principles: the same world state, bit for bit, on every platform, CPU, vector width and thread count. Package RecursiveAI.OnePhysics, built on onemath for its deterministic math.
Status: preview. The 2D engine is the supported surface: circles, capsules, rounded polygons, segments and chains; revolute, prismatic, weld, wheel, distance, motor and mouse joints; bullets and continuous collision; a character mover; layers, filters, sensors, events and queries; byte-exact snapshot and restore; per-step world hashes; debug geometry. The 3D engine (RecursiveAI.OnePhysics.Physics3D) ships as a preview marked [Experimental("OPHYS0002")]: it works and is deterministic, but its API and its results may change between previews. The raw tier (RecursiveAI.OnePhysics.LowLevel) is [Experimental("OPHYS0001")]. Previews are not bit-compatible with each other: a snapshot or replay from one preview does not carry to the next.
Install
dotnet add package RecursiveAI.OnePhysics --prereleaseTargets net10.0; works under NativeAOT, trimming and browser WebAssembly. Its only dependency is RecursiveAI.OneMath.
2D in a minute
using System; using RecursiveAI.OneMath; // Vector2F, Vector2D using RecursiveAI.OnePhysics; // BodyType, events, exceptions using RecursiveAI.OnePhysics.Physics2D; // PhysicsWorld2D, Body, Character var world = new PhysicsWorld2D(); world.AddBox(new Vector2F(20, 1), at: new Vector2D(0, -1), type: BodyType.Static); var ball = world.AddCircle(0.5f, at: new Vector2D(0, 5)); ball.OnCollisionEnter += c => Console.WriteLine($"hit {c.Other} along {c.Normal}"); var player = world.AddCharacter(at: new Vector2D(3, 1)); for (int i = 0; i < 600; i++) { player.Move(new Vector2F(0.05f, -0.1f), 1f / 60); world.Step(1f / 60); // fixed dt; events fire after the step, in a deterministic order } if (world.Raycast(new Vector2D(0, 10), new Vector2F(0, -1), out var hit)) Console.WriteLine(hit.Point); byte[] saved = world.Snapshot(); // byte-exact; Restore(saved) continues bit for bit ulong hash = world.ComputeHash(); // the same on every platform
3D, a preview
The 3D world has the same members with 3D math types. Using it raises the experimental diagnostic OPHYS0002 until you acknowledge it:
#pragma warning disable OPHYS0002 // the 3D engine is a preview using System; using RecursiveAI.OneMath; // Vector3F, Vector3D using RecursiveAI.OnePhysics; // BodyType, events, exceptions using RecursiveAI.OnePhysics.Physics3D; // PhysicsWorld3D, Body, Character var world = new PhysicsWorld3D(); world.AddBox(new Vector3F(20, 1, 20), at: new Vector3D(0, -1, 0), type: BodyType.Static); var ball = world.AddSphere(0.5f, at: new Vector3D(0, 5, 0)); ball.OnCollisionEnter += c => Console.WriteLine($"hit {c.Other} along {c.Normal}"); for (int i = 0; i < 300; i++) world.Step(1f / 60); if (world.Raycast(new Vector3D(0, 10, 0), new Vector3F(0, -1, 0), out var hit)) Console.WriteLine(hit.Point); byte[] saved = world.Snapshot(); ulong hash = world.ComputeHash();
What you get
- Deterministic. Only IEEE-exact
+ - * /andsqrtand our own transcendental functions; fixed-order reductions and constraint coloring. The world hash after N steps is the same on x64, arm64 and WebAssembly, scalar or SIMD, one thread or all cores. - Three tiers, one engine. One-liners (
world.AddBox(...),body.OnCollisionEnter), definitions and polled events, and a raw tier, each built on the one below. - Rollback-ready. Byte-exact
Snapshot/TrySnapshotandRestore,ComputeHashper step,SuppressCallbacksfor resimulation, allocation-free steady state afterWarmup. - Handles you can hold.
Body,ShapeandJointare small structs; a destroyed one throws aStaleHandleExceptionnaming it. - Hostile input is refused, with typed errors that name the value and the limit.
Guide
- Install and quick start
- The three tiers
- Events
- Queries, layers and filters
- Rollback and lockstep
- Determinism guarantees
- Units and sizes, names and conventions, input limits
- Coming from Unity
- Port specifications: the normative, language-neutral description of every choice that affects the bits.
- Changelog and contributing
Licence
MIT OR Apache-2.0, at your option. Copyright (c) Recursive AI, LLC. See LICENSE-MIT and LICENSE-APACHE.