v0.3.0 — Multi-engine demo and solver profiler
Superseded by v0.4.0. These assets are kept for anyone pinned to this tag; the demo in them predates the mobile browser fixes, the Godot Physics / Jolt parity fixes and the Ball Flood sample. For the current binaries and the playable browser demo, start at v0.4.0.
Two claims in these notes were wrong and are corrected below. Current iOS Safari runs the threaded build on itch perfectly well, and the GitHub Pages deployment they pointed at is retired — it is stale and receives no updates. itch.io is the only browser demo that is kept current.
Run the demo's own samples on Box3D, Godot Physics or Jolt Physics, and read a per-phase solver profiler while they run.
Physics engine selector
The bottom of the demo's Settings sidebar now picks the solver. Same menu, same camera, same shoot/grab/bomb tools, same reset — only the engine underneath changes. Godot reads physics/3d/physics_engine once at startup and offers no runtime switch, so selecting one relaunches the demo on the same sample.
The sample scenes are untouched. They are read into a backend-neutral description and rebuilt with native bodies, which keeps the Box3D path exactly as it was and means every sample stays authored once.
Differences that would otherwise make the comparison dishonest are corrected: mass from density and volume, explicit inertia and centre of mass (Godot Physics uses an AABB approximation for capsule, cylinder, hull and concave shapes), explicit friction and restitution, cylinders and cones as N-gon hulls to match how Box3D builds them, and Box3D's AND collision filtering re-expressed in Godot's OR model. What cannot be matched — combine rules, substeps versus iterations, joints Godot has no equivalent for — is reported on screen per sample.
Six samples are Box3D-only and say so: gyro_torque (needs the gyroscopic term), car (wheel joint), explosion (projected-area impulse), ragdoll (joint springs), gyro_precession (fast-rotation bypass), huge_pyramid (multimesh renderer, and Jolt's 10240 body cap).
Solver profiler
A bottom drawer with Profile, Counters and Frame Time tabs, cloned from the upstream sample app's Metrics panel — same rows, same labels, same statistics, so a number here means what it means there.
Box3D reports all 22 phases through new Box3DWorld.get_profile() and get_counters() bindings over b3World_GetProfile / b3World_GetCounters.
Godot Physics and Jolt report a total only. Both compute per-phase timings and emit them to the "servers" debugger profiler, but EngineDebugger.profiler_enable() is a no-op outside a debug session, so a running game receives nothing. The panel says so rather than showing a flat bar. Jolt additionally returns 0 for every PHYSICS_3D_* counter.
Draggable, resizable, and it remembers its geometry, expanded rows and visibility across launches.
Also
- Upstream synced through
Fixes 09 (#104). godot/tools/compare.shruns a standalone side-by-side harness for recording.- The live engine is identified behaviourally rather than from the project setting, because an unregistered engine name is not an error in Godot — it falls back silently. A mismatch paints a banner instead of mislabelling a recording.
Assets
| file | use |
|---|---|
box3d-demo-android.apk |
the demo, debug-signed, arm64 + x86_64 |
libbox3d_godot.linux.template_{debug,release}.x86_64.so |
Linux |
libbox3d_godot.android.template_{debug,release}.{arm64,x86_64}.so |
Android |
libbox3d_godot.windows.template_{debug,release}.x86_64.dll |
Windows (MinGW cross-built, untested) |
libbox3d_godot.web.template_release.wasm32{,.nothreads}.wasm |
Web, threaded and single-threaded |
box3d-demo-web-threaded.zip |
the browser demo for itch.io, or any host sending real COOP/COEP headers |
box3d-demo-web.zip |
the browser demo for a plain static host, no special headers needed |
Drop the libraries into godot/demo/bin/ alongside box3d.gdextension.
Browser build
Play it on itch.io — multi-threaded solver, full-size scenes, no download. Desktop, Android and iOS all run that threaded build there.
Both builds are attached if you want to host your own:
box3d-demo-web-threaded.zip— the itch build. Needs cross-origin isolation: either a host that sends real COOP/COEP headers or itch's SharedArrayBuffer option. A visitor without isolation gets a readable notice explaining why, not a black screen.box3d-demo-web.zip— the single-threaded fallback. Works on any static host with no special headers, in every browser. The heaviest scene is halved to keep one thread comfortable.
Determinism on wasm is unverified — upstream's Emscripten CI is build-only — so the browser builds are not a reference for behaviour.
Windows
Windows DLLs are attached to this release, cross-compiled from Linux with MinGW-w64 (GCC 16.1.1). They are self-contained: the only imports are KERNEL32.dll and msvcrt.dll, with libgcc and libstdc++ linked statically, and box3d_library_init is exported. -ffp-contract=off is applied on this path, so Box3D's deterministic-math build flag is preserved.
They have not been run on Windows. They are a different toolchain from MSVC, and this port's determinism guarantee is only verified across scalar/SSE2/NEON. Treat them as untested until someone confirms them on a real machine.
No more binaries in the repo
Prebuilt binaries are no longer committed. The Windows DLLs that used to be were four upstream core syncs stale and predated the get_profile() / get_counters() bindings, so a fresh clone got a degraded demo with nothing to say why. Every binary now ships here instead, versioned against the tag that produced it. Download what you need and drop it into godot/demo/bin/.
2026-07-27: assets refreshed at the current tag. The demo gained scroll-wheel reeling of a grabbed body and keyboard-focus fixes; the browser builds and their hosting solidified into a threaded primary (stinkysunstep.itch.io/box3d-godot) with a single-threaded zip for self-hosting on a plain static host. The native libraries are unchanged builds — no C++ changed.