Skip to content

dylanebert/tumble.js

Repository files navigation

tumble

ci upstream parity vs box3d

Web physics engine. A from-scratch TypeScript port of Box3D by Erin Catto, bit-exact against the C reference. Multithreaded by default. Zero dependencies, tree-shakeable, ESM only.

0.x: the API tracks Box3D until its 1.0. Pinned to box3d 29bf523 (v0.1.0 + fixes).

Install

npm install tumble.js
import { init, World, BodyType, makeBoxHull } from "tumble.js";

await init(); // compiles the inlined wasm kernel + resolves threading

const world = new World();
const ground = world.createBody({ position: { x: 0, y: -1, z: 0 } });
ground.createHull({}, makeBoxHull(50, 1, 50));

const box = world.createBody({ type: BodyType.Dynamic, position: { x: 0, y: 10, z: 0 } });
box.createHull({ density: 1 }, makeBoxHull(0.5, 0.5, 0.5));

for (let i = 0; i < 120; i++) world.step(1 / 60, 4);
console.log(box.getPosition()); // rests at y ≈ 1.5

Shapes (sphere, capsule, convex hull, mesh, heightfield, compound), eight joint types, continuous collision, ray/shape/overlap queries, contact + sensor events, kinematic character mover. Live samples on real WebGPU: dylanebert.github.io/tumble.js.

Threading

init() resolves threading per host. Results are bit-identical at any thread count.

host kernel
bun / node multithreaded, 4 threads
browser, cross-origin isolated multithreaded, 4 threads
browser without COOP/COEP single-threaded, one console note
init({ threads: 0 | n }) force single-thread / set count

Browser multithreading needs two headers: Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp. Hosts without them run single-threaded. threads() reports what resolved; no shutdown() is needed.

Performance

tumble vs box3d, ms/step, lower is better

Regenerated each release by bun run bench on one runner. The vs box3d badge is the chart's default group: tumble on bun against the C original, same scene, same machine, both at 4 threads.

That baseline is native clang with -march=native. The chart also plots box3d compiled to wasm via emscripten, the fastest box3d a browser can actually run: tumble trails that deployable ceiling but buys a readable, tree-shakeable, TS-native surface in return.

Verification

gate scope status
bun test box3d's unit suite, ported ci badge
fixture gate every scene fixture, per-step world-state hash equality vs C maintainer-run
MT fixture gate same fixtures through the pool, bit-exact at any thread count maintainer-run
upstream parity in-scope upstream tests covered parity badge

Equality is exact, not tolerance-banded: every f32 op mirrors the C expression tree (per-op Math.fround, no FMA, portable trig, scalar min/max). Every upstream test carries a disposition in upstream/parity.json, cross-checked in CI.

License

MIT. Port © Dylan Ebert; Box3D © Erin Catto. See LICENSE.

Issues and bug reports are welcome. The port isn't open to code contributions.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors