Phase 16 · part: Brakes
Physics and Small Games
Rapier in the browser: bodies, colliders, the fixed timestep, joints, keeping meshes in step, and a test ride with keys, buttons and brakes.
Until now the bike only pretended to ride: Phase 9 turned its wheels on the stand. This phase gives it weight. A physics engine decides where things are and how they move; three.js only draws what the engine says.
You use Rapier, a physics engine compiled to WebAssembly, and learn what every game developer learns the hard way: why physics steps at a fixed rate, why fast objects can pass through thin ones, how joints hold a wheel to a frame, how friction and bounce really combine, and who owns an object's position.
The build turns the showroom into a small game: a test ride along a track, with the keyboard or on-screen buttons, a follow camera, a reset when the bike falls over, and the brakes, this phase's part.
Phase 16 · the brief from Lumen
Tomás, Lumen Bikes' founder
“Customers ask how the bike rides, and a picture can't answer that.”
In the shop, Tomás lets customers ride a bike round the car park. Online, the best he can offer is a turning model. He asks Kofi for something closer: "Let them push it, brake, go over a bump."
Kofi knows that writing your own collisions is a trap, and that games use a physics engine. The question is how to bring one into a web page without slowing the showroom for everyone who never rides.
By the end of this phase the showroom has a Test ride button. The engine loads only when someone presses it, the ride works with keys, a mouse or a finger, and the brake pads glow red when you brake.
At this station
You will learn
- Set up a Rapier world with bodies and colliders, and step it
- Use a fixed timestep with an accumulator, and avoid objects passing through each other
- Add joints, friction and bounce, and know how two colliders' values combine
- Keep three.js meshes in step with physics, and build a small ride with keys and buttons
You write code in
In your lumen-3d project (npm run dev; add Rapier with npm install @dimforge/rapier3d-compat@0.21.0) and in the editor on this page
Files you touch
- src/systems/physics.js
- src/objects/bike.js
- src/ui/panel.js
- src/main.js
- index.html
- package.json
Work order · 6 steps
- 16.1Physics EnginesA physics engine keeps its own world of bodies (things with mass and motion) and colliders (their shapes), applies gravity and contacts, and moves everything forward one step at a time. Rapier runs as WebAssembly: you must
await RAPIER.init()before using it. 18 min 2 live scenes - 16.2The Fixed TimestepPhysics must step by the same amount of time every time, whatever the frame rate. An accumulator collects real time and runs as many fixed steps as fit. Steps are jumps, so fast objects can skip past thin ones; engines add tricks against that, and you still test it. 20 min 2 live scenes
- 16.3Colliders and JointsPick the simplest collider that fits: balls, cuboids, cylinders and convex hulls are fast and solid; a triangle mesh is exact but hollow. Friction and restitution are set per collider and combined per contact (averaged by default). Joints hold bodies together: a revolute joint is a hinge, and its motor drives a wheel. 19 min 2 live scenes
- 16.4Syncing Physics and RenderingThe physics world and the three.js scene are two separate copies of the world. After every step, copy each body's position and rotation into its mesh, and never move the mesh by hand: the body owns the transform. In React Three Fiber,
@react-three/rapierdoes this for you. 18 min 2 live scenes - 16.5A Test RideA small game is a loop of input, physics and camera: held keys or buttons set forces, the world steps at a fixed rate, the camera follows, and a watchdog resets the bike when it falls over. Script the input with fixed steps and the whole ride becomes testable. 31 min 2 live scenes
- 16.6Build: The Test RidebuildThe showroom gets a Test ride button. Rapier loads only when it is pressed; then the bike rides a track with a ramp, driven by held keys or on-screen buttons, followed by the camera, reset when it falls, with brake pads that glow while braking. The brakes are this phase's part. 96 min 2 live scenes
Quality control · 4 tests
Build it yourself, press Check, and the page tests the scene you made: what is in it, where it sits, what it costs the GPU.
createFixedStepper(step, onStep). Its tick(delta) adds delta, capped at 0.25 s, to an accumulator, calls onStep() once per whole step it holds, and returns alpha (what is left, divided by the step).AdvancedQC-03A bouncier ballThe ball's restitution is 0.9, but it bounces to only 0.18 m: the floor's 0 is averaged in. Make it bounce above 0.6 m without changing the floor.AdvancedQC-04Brake the rideA 20 kg ride body pedals with 30 N, but braking does nothing.Advanced