Try one real physics body with Rapier
Drop a body onto a floor, pause and step, apply an impulse and dispose the world. A worked Rapier3D 0.21.0 browser example with original source.
Start with this small scene before connecting your controller. The canvas shows actual 3D positions from the side; it is an original diagram view, not a 3D renderer.
Check Rapier’s source, compatibility and licenceDrop. Step. Stop.
Choose Start to load the physics module (about 1.7 MB compressed). Pause enables one tick. Backgrounding pauses; Resume is deliberate.
Ready. Physics loads only when you choose Start / restart.
Inspect measured state
- STEP 1
Use one exact package
Keep your working game separate. Download the original example source into a new folder, then install the pinned dependency with Node 24. The source ZIP contains Forge code and notices; the upstream library is installed separately.
npm install --ignore-scripts --no-audit --no-fund npm run build npm run check python3 -m http.server 8080Check: npm run build verifies the exact module hash; npm run check passes six real WASM cases.
- STEP 2
Let physics own the fall
Open physics.mjs. Rapier owns a dynamic body and its cuboid collider; the ground is fixed. Units are metres and seconds. No visual animation decides whether the body is touching the floor.
const world = new RAPIER.World({x:0, y:-9.81, z:0}); world.timestep = 1/60; world.createCollider(RAPIER.ColliderDesc.cuboid(5,.1,5) .setTranslation(0,-.1,0));Check: After Start the height falls from 3 m and settles near 0.35 m; floor contact becomes visible in the text state.
- STEP 3
Use one fixed clock
Reuse your existing simulation loop. This example uses Forge’s bounded fixedStep helper: each update advances1/60 second, with at most0.1 second catch-up per rendered frame. The browser’s drawing rate does not own gravity. Pause and Step one tick make the distinction visible.
fixedStep(clock, elapsedSeconds, () => probe.step()); // Rendering reads probe.snapshot(); it does not step physics.Check: While paused the measured state stays still. One tick adds exactly one step. An explicit upward impulse lifts the body; it returns to the floor.
- STEP 4
Stop and release the world
Dispose world releases the event queue and physics world once. Restart releases the previous world before creating a fresh one. Connect only this proven loop to your existing project; character movement, vehicle handling, camera, multiplayer and target-device tests are separate work.
probe.dispose(); // idempotent; future step/impulse is rejected probe = createPhysicsProbe(RAPIER);Check: Dispose stops all steps; a new Start begins from 3 m with zero contacts. Failed library loading gives a useful error while this guide remains readable.
Download original example source Open the standalone example
Explain this with my AI