Maul3D

CI License: MIT Release OpenSSF Scorecard

A deterministic 3D physics engine for games. Written in C23, with a plain C API whose headers also compile as C17 and C++17, no dependencies and an MIT license.

Same inputs, same bits, on every supported platform and at every thread count. A snapshot restores a world exactly, and the command journal records a session and replays it byte for byte, verifying every id and backing out atomically when a tape does not fit. Rollback netcode, lockstep multiplayer, replays and server-side verification are a few calls away:

int64_t size = m3World_GetSnapshotSize(world);
int64_t written = 0;
m3World_Snapshot(world, buffer, size, &written);
/* ... mispredicted steps ... */
m3World_Restore(world, buffer, size); // resimulate from here, bit for bit

The Maul family

Maul3D has a 2D sibling, Maul2D. The two are one family: two engines, one set of rules.

Maul2D Maul3D
World 2D 3D
Built for platformers, puzzles, top-down games, machines, water destruction, vehicles, characters, lockstep multiplayer
Beyond rigid bodies particle fluids, one-way chain terrain, geometry tools voxel destruction, raycast vehicles, character controller, soft bodies, replay tools
Repository Rawframe-Project/maul2d this one

What the family shares:

Features

Getting started

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build

The library needs a C23 compiler: GCC 14, Clang 19 or newer, or clang-cl on Windows. Configuring with an older one stops with an error, so where the default compiler is older, as Ubuntu 24.04's GCC 13 is, name one in the first line with -DCMAKE_C_COMPILER=gcc-14 or -DCMAKE_C_COMPILER=clang-20. MSVC's cl cannot build the library, but a program built with it can include the public headers, which are C17 and C++17.

x64 builds use AVX2 and FMA (Haswell, 2013, and later); configure with -DMAUL3D_SIMD=scalar for a portable build that gives identical results. An AVX2 build started on a CPU without AVX2 refuses to create worlds instead of crashing.

cmake --install installs the library, the headers, a CMake package and a pkg-config file, so find_package(maul3d) and pkg-config maul3d both work. Build a shared library with -DMAUL3D_BUILD_SHARED=ON. Every tagged release carries prebuilt libraries for Linux (x64 and arm64), Windows and macOS.

Samples, the testbed and bindings

The samples are small complete programs: a falling stack that prints the same hash on every machine, the rollback loop, a car that turns into a tank, and a character on the stairs. samples/minimal is a standalone project that finds the installed package.

The interactive testbed builds with -DMAUL3D_BUILD_TESTBED=ON. Its fourteen scenes cover benchmarks, voxel destruction, three kinds of vehicle, a playable character, cloth in gusting wind and a heightfield, with a recording panel that seals the session into an M3RP replay and verifies it. Hold R and time runs backward.

bindings/ holds the C# binding (one P/Invoke file), which keeps the same 1.x promise as the C headers, and a Godot starter kit (a GDExtension node), which follows Godot's versions and is outside it. CI checks both against the C API: every function they call, and every struct the C# side mirrors, field by field. Bindings says how to build and use them.

Determinism

Benchmarks

The scenes in bench/ (a pyramid, hull and mesh fields, a voxel fort, a 5000-body city block with destruction and a 10,000-body smoke test) print their timings. Their final world hashes are pinned in test/hashes.txt and checked by the Release-only bench test, which the nightly CI run executes on every platform.

Status

From 1.0.0 the API is settled, and every 1.x release keeps it: a program that builds against 1.y builds against any later 1.z and means the same. A minor release adds functions, types, enum values and fields at the end of a struct, and never removes or renames one; a patch release only fixes. A change that gives existing inputs a different result ships as a feat in a minor release, or as a fix in a patch release when it corrects a result the documentation already promised, and the changelog says what changes. A program built against another minor version's headers is refused at m3CreateWorld with m3_errorVersion. Defs carry a cookie, so a def that was not set up with its m3Default...Def function is refused. A snapshot, a journal tape and a replay file are read only within the minor version that wrote them, and a snapshot only by a release with the same results; any other release refuses them with m3_errorVersion, so a host keeps assets, not state, across an upgrade.

Documentation

Contributing

Issues are welcome. Pull requests are accepted for issues a maintainer has approved; see CONTRIBUTING.md. The project is developed with AI coding agents, directed and reviewed by its maintainers; outside contributions follow the AI policy.

Acknowledgments

The engine's algorithms follow published work: the soft step schedule and soft constraints, the collision, distance and hull methods, the mass properties and the particle model. docs/internals/references.md lists every source. The library itself uses no outside code. The testbed, which is not part of the library, is built on raylib (zlib/libpng license), fetched when the testbed is configured.

License

MIT. See LICENSE.