Course outline
A Test Ride
In one line
A 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.
Think of it like this
A driving lesson on an empty car park. The learner presses pedals (input), the car obeys physics, the instructor watches from the passenger seat (the follow camera), and if the car ends up on the kerb, everyone gets out and puts it back on the start line (the reset).
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- input state
- What the player is doing right now (pedal held, brake held), kept in an object the physics step reads.
- linear damping
- A force against motion proportional to speed, the engine's stand-in for rolling resistance and air.
- follow camera
- A camera that moves with the player's object each step, keeping it in view.
- watchdog
- Code that notices a stuck or broken state (on its side, off the track) and recovers from it.
- scripted input
- Input set by code at known step counts, so a test sees the same ride every time.
Step by step
01Read the scripted ride
The first example sets ride.input.pedal, ride.input.brake, and calls ride.step() a fixed number of times. No clock is involved, so the numbers repeat exactly.
02Check the physics with arithmetic
Top speed 30 / (20 × 0.3) = 5 m/s, approached as 5 × (1 − e^(−0.3 t)). After the brake the last 8 s start from almost a standstill: the formula gives 4.55 m/s, a run with no ramp prints 4.50 m/s, and the ramp costs a little more (4.31 m/s). The camera's movement equals the bike's.
03Flip it on purpose
The second example gives the body an angular velocity of 14 rad/s round z, watches the watchdog, then calls end(), which removes the track and restores Phase 9's showroom speed.
04Add the controls
In the build (Topic 16.6), held keys and held buttons write the same input object: W or the up arrow, S, the down arrow or Space; Pedal and Brake buttons use pointer events, so mouse, touch and pen all work.
Try it yourself
- 1
Pedal harder
In the first example, set
PEDAL_FORCEto60. Top speed doubles to 10 m/s: after 2 s it is at 4.45 m/s, and by the end it has ridden off the end of the 40 m track (measured: x 51.41, falling, tilted −100°). The watchdog puts it back one second later. - 2
Softer brakes
Set
BRAKE_DAMPINGto1. After 1 s of braking the bike still rolls at 0.83 m/s (it was 0.05 with 4). Damping removes a share of the speed each step, so it never quite reaches 0 on its own;damping 4gets close enough within a second.
Code & diagrams
The real `physics.js` of the build, inlined, with a stand-in bike. Fixed step counts, so the numbers are the same every run.
Console
Run the scene to see its console.Expected console output
settled on the track x -0.00 | speed 0.00 m/s | y -0.00 | tilt -0.0°
2 s pedalling x 2.46 | speed 2.23 m/s | y -0.00 | tilt -0.0°
1 s braking x 3.04 | speed 0.05 m/s | y -0.00 | tilt -0.0°
8 s more pedalling x 25.28 | speed 4.31 m/s | y -0.00 | tilt -0.0°
highest point over the ramp: 0.12 m | the camera followed: 25.28 mConsole
Run the scene to see its console.Expected console output
rolling x 2.46 | speed 2.23 m/s | y -0.00 | tilt -0.0°
0.67 s after the kick x 4.31 | speed 1.82 m/s | y 0.86 | tilt 83.3°
1.5 s later x -0.00 | speed 0.00 m/s | y -0.00 | tilt -0.0°
after end(): track in the scene: false | wheel speed back to 1.667 m/sBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Leave the friction rule at its default
In the first example, remove .setFrictionCombineRule(RAPIER.CoefficientCombineRule.Min) from the wheels.
Myth vs fact
Myth
A game loop reads the keyboard and moves the object.
Fact
Input sets forces or targets; the physics step moves the object. Moving it directly skips collisions and makes it teleport (Topic 16.4).
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Scripted input at fixed steps turns a game into a unit test: the same inputs give the same positions, so you can assert "after 2 s of pedalling, speed is 2.23 m/s" in CI.
- ▸
Pointer events on hold-buttons need
touch-action: none(no scrolling or zooming starts on the button) andpointerleaveandpointercancelas well aspointerup, or a finger that slides off the button leaves the pedal stuck down.
Remember this
- 1
The problem this solves: Tomás wants customers to feel the bike: push, roll, brake, go over a bump. That needs input that works with a keyboard, a mouse and a finger, a camera that keeps the bike in view, and a way back when things go wrong, because in physics things do go wrong.
- 2
One body, honest shapes. The ride's bike is one rigid body: a box for the frame (about 15.6 kg) and two balls for the wheels (about 2.3 kg each), about 20 kg in all. It may pitch (rotate round z, over the ramp) but not roll sideways or steer:
enabledRotations(false, false, true). Its wheels have friction 0 with theMincombine rule, so they slide like perfectly rolling wheels; without that rule the floor's 0.5 averages to 0.25 and holds the bike still. - 3
Forces, not positions. Pedalling adds a 30 N force each step. Rolling resistance is linear damping 0.3, so the top speed is force / (mass × damping) = 30 / (20 × 0.3) = 5 m/s (18 km/h), reached gradually. Braking raises the damping to 4. The first example scripts a ride with fixed step counts: 2 s of pedalling reaches 2.23 m/s, 1 s of braking stops it, and 8 s more takes it over the ramp (12 cm up) to 4.31 m/s.
- 4
The follow camera. After each step, the camera and its orbit target move by exactly the bike's movement, so the view angle stays the same and the visitor can still orbit round the bike. The example's camera travelled the same 25.28 m as the bike.
- 5
The watchdog. If the bike's up direction tips below 0.3 (about 73° from upright) or it falls below y = −2, a timer counts; after one second the bike is reset to the start, with zero velocity. The second example kicks it into a flip: 0.67 s later it is at 83° and 0.86 m up, and 1.5 s later it is back at the start.
Explain it without notes
Walk through one frame of the test ride: from a held key to a moved camera.
Why does the ride use forces and damping instead of setting the bike's velocity directly?
Practice
Add a boost key (B) that doubles the pedal force while held.
Make the watchdog reset a fallen bike after half a second instead of one.
Done when you can
You drive a body with forces and damping from an input object
You can compute the top speed from force, mass and damping
You follow the body with the camera and orbit target together
You reset a fallen body with a watchdog, and test the ride with scripted steps