Physics Backends¶
3D physics in SimVX runs behind a backend seam: every PhysicsRoot builds an
isolated PhysicsWorld, and which implementation it uses is chosen by a single
selection rule. Two backends ship today:
Backend |
Package |
Notes |
|---|---|---|
BuiltinPhysics |
|
Pure-Python rigid-body solver. The default. No dependency, runs everywhere including the browser. “Basic tier”: approximates some collision/character cases. |
JoltPhysics |
|
Native Jolt (cffi on desktop, JoltPhysics.js WASM on web). 3D only. Full rigid-body solver, oriented-box collision, characters that push/carry dynamic bodies, high body counts. |
BuiltinPhysics is the default and needs no setup. The rest of this page is
about opting into Jolt.
Selecting a backend¶
Selection is explicit. Installing simvx-physics-jolt makes Jolt
available but does not change the default — a solver swap changes gameplay
outcomes, so you opt in deliberately. Precedence (highest first):
An explicit
PhysicsRoot(backend=...)on the subtree.The project
physics_backendsetting (.simvx/config.json).Otherwise:
BuiltinPhysics.
Per-subtree¶
from simvx.core import PhysicsRoot
# Every body under this root simulates on Jolt; the rest of the scene is unaffected.
root = self.add_child(PhysicsRoot(backend="jolt"))
root.add_child(my_dynamic_body)
A scene can hold several PhysicsRoots with different backends at once — see
examples/demos/physics_backend_compare.py, which runs Builtin and Jolt side by
side.
Project-wide¶
Create .simvx/config.json at the project root:
{ "general": { "physics_backend": "jolt" } }
Now any body with no explicit PhysicsRoot(backend=...) uses Jolt. If the
package is not installed, selection falls back to Builtin with a console
warning (it never hard-fails).
What Jolt adds over Builtin¶
A production rigid-body solver (warm-started contacts, stable stacking).
Oriented collision shapes — a rotating box collider actually sweeps, so a spinning paddle herds objects (Builtin’s basic tier treats some shapes as axis-aligned).
A character (
CharacterBody3D) that pushes and carries dynamic bodies and is not jammed by them; Builtin’s arcade character is one-way (dynamic bodies fall through it).Throughput for high body counts.
2D is unaffected — Jolt is 3D-only; 2D continues to use Builtin (or the optional
pymunk backend).
Installing the desktop backend¶
# editable / dev install (compiles the vendored Jolt + joltc locally)
uv pip install -e packages/physics-jolt --no-build-isolation
The package vendors pinned Jolt + joltc C++ sources and builds them via CMake at install time, so an sdist install always works provided a C++17 compiler and CMake are present (this is the first SimVX package that requires a compiler; the pure-Python default never does). Useful knobs:
SIMVX_SKIP_JOLT_BUILD=1— install the Python without compiling the native extension (Jolt then resolves to unavailable; selection falls back to Builtin).SIMVX_REQUIRE_JOLT_NATIVE=1— fail the install loudly if the native build cannot complete, instead of skipping.
A prebuilt Linux wheel may be available; it is built with a conservative SIMD baseline (no AVX2) so it runs on older CPUs, at some performance cost. There are no prebuilt macOS/Windows/musl wheels yet (the project runs no CI), so those platforms install from the sdist and need the toolchain above.
Web export¶
simvx export web automatically bundles the JoltPhysics.js (WASM) runtime when
the exported game opts into Jolt (it scans the sources for a backend="jolt" /
physics_backend selection). The same explicit-opt-in rule applies; the web
default stays BuiltinPhysics (pure Python under Pyodide).
uv run simvx export web examples/demos/waterfall.py -o waterfall.html
Web caveats:
Jolt and Pyodide live in separate WASM heaps, so transforms are copied across the boundary once per frame — practical body counts are lower than desktop (a few thousand, not tens of thousands).
No determinism on web (the JoltPhysics.js build has no state recorder).
It is a separate backend that mirrors only the
PhysicsWorldAPI, not the desktop build.
examples/demos/jolt_web_showcase.py is a minimal web Jolt scene; waterfall.py
and physics_backend_compare.py also export to web.
See also¶
Collision & Physics — the collision detection layer.
examples/demos/waterfall.py— flagship Jolt showcase (glass mill, spinning paddle, adaptive flow control, framerate tied to the physics tick).