solveSpeedKmh + gearing) across a grade×power grid, five routes, a gear/cadence ladder and a standing-start acceleration table, then audits working points against independent cycling calculators. Every number is reproducible. Tweak the equipment, air, wind and surface and watch it react, or copy the whole audit out. The competitive targets are built on this too: each leaderboard's par time (Time-Trial medals + the OutRide Arcade Rating) is this same solveSpeedKmh model run for a reference rider of your W/kg class, so a flat sprint and a mountain climb are compared on honest physics, not a lookup table.EQUIPMENT: our values
ENVIRONMENT: air, wind & surface
ρ is computed from altitude + temperature (barometric formula); Crr comes from the surface. Thinner air up high = faster on the flat; a headwind or gravel = slower. Wind feeds the grade×power matrix and the routes; the audit + acceleration stay at the windless calibration.
GAME ROAD SURFACES: the story-ride consequence · docs/fable/48
Each story-ride road surface carries a REAL rolling-resistance cost, not just a texture. The speed multiplier below is derived from THIS page's own solver at a reference operating point (200 W, flat, reference rider) — the same watts cover this fraction of the ground on that surface vs. smooth asphalt, so a muddy or cobbled sector is felt as lost distance, never a faked watt. Soft ground (dirt/snow/mud/sand) bites harder on climbs (the tyre sinks — a term the steady-state balance alone misses); the last column shows the total at an 8% climb.
| Surface | Rolling Crr | Flat speed × | At 8% climb × |
|---|---|---|---|
| asphalt | 0.0050 | 1.000 | 1.000 |
| dirt | 0.0100 | 0.928 | 0.905 |
| cobbles | 0.0110 | 0.913 | 0.913 |
| snow | 0.0140 | 0.871 | 0.829 |
| mud | 0.0160 | 0.843 | 0.783 |
| desert | 0.0170 | 0.830 | 0.776 |
| regolith | 0.0060 | 0.985 | 0.985 |
| marsdust | 0.0070 | 0.971 | 0.971 |
| racetrack | 0.0040 | 1.015 | 1.015 |
| chocolate | 0.0050 | 1.000 | 1.000 |
| rainbow | 0.0050 | 1.000 | 1.000 |
SAME ROAD, DIFFERENT GROUND: what a surface costs in time
Ten kilometres, the same watts, one surface at a time, solved with this page's own solver and the single ground table every part of the game reads (lib/surfaceCost): the ride, the medal budget, the bots, the story engine and Cross Land. Nothing here is an illustration of something else; it is the same race. The tyre is the other half of the pair and is still to come. These are a reference tyre on each ground.
Crr and the grip factor sit in the same row of the same table. Grip does not show here, because a straight line never asks for it. It decides the corner, and on soft ground it decides whether the rear wheel turns at all (tractionLimitW): on 16 % mud at 8 km/h that ceiling is about 420 W.
VALIDATION AUDIT: against independent calculators · reference rider, sea level / 15 °C
| Working point | Power | Grade | Expected | Ours | At their rider | Δ | Δ% | Reference implies | |
|---|---|---|---|---|---|---|---|---|---|
| Endurance, flat physics.ts / bikecalculator | 200 W | 0% | 30.0 ±2.5 | 32.1 | 30.8+2.6 % | +2.1 | +7% | CdA 0.450 ours 0.36 | PASS |
| Easy spin, flat bikecalculator | 100 W | 0% | 24.0 ±3 | 24.4 | 23.4-2.6 % | +0.4 | +2% | CdA 0.382 ours 0.36 | RUNDUNG |
| Threshold, flat bikecalculator | 300 W | 0% | 35.5 ±3 | 37.4 | 35.8+1.0 % | +1.9 | +5% | CdA 0.426 ours 0.36 | PASS |
| Sprint power, flat bikecalculator | 450 W | 0% | 41.5 ±3.5 | 43.4 | 41.6+0.1 % | +1.9 | +5% | CdA 0.414 ours 0.36 | PASS |
| Endurance, 5 % climb physics.ts / bikecalculator | 200 W | 5% | 14.0 ±1.5 | 14.3 | 13.6-2.7 % | +0.3 | +2% | 86.4 kg ours 84.5 kg | RUNDUNG |
| Threshold, 8 % climb Gribble | 300 W | 8% | 13.5 ±1.8 | 14.2 | 13.6+0.6 % | +0.7 | +5% | 89.6 kg ours 84.5 kg | PASS |
| Steady, 10 % wall Gribble | 250 W | 10% | 9.2 ±1.5 | 9.9 | 9.4+2.7 % | +0.7 | +7% | 91.2 kg ours 84.5 kg | PASS |
| Coasting, −5 % descent terminal velocity (Gribble) | 0 W | -5% | 44.0 ±5 | 46.8 | 44.9+2.0 % | +2.8 | +6% | CdA 0.407 ours 0.36 | PASS |
Run at the reference rider — 84.5 kg · CdA 0.36 · Crr 0.005 · ρ 1.225 · η 0.97, sea level / 15 °C. Fixed on purpose: the sliders above move every other table on this page, but they must not be able to paint this one green. The two flat/5 %-climb anchors are the ones already cited in lib/physics.ts.
We sit high on all 8 of them — 8/8 fast, mean +5.0 %. That is an offset, not scatter, so here is where it comes from rather than an average that hides it. The references were not all taken at one setup: hold everything else and ask what single value would make our own solver land exactly on each published speed — the last column. Where air resistance sets the speed they imply CdA 0.38–0.45 m²; where gravity does, 86–91 kg total. Ours is a 0.36 m² hoods/tops position at 84.5 kg, more aero and lighter than what those numbers describe, which is the whole gap. So the offset is a difference in who is riding, not in the physics: 6/8 land inside a tolerance band that was set before any of this was measured.
The last column is that same table run at CdA 0.41 / 88.5 kg — the single rider that comes closest to all 8 published speeds at once. The worst miss falls from 7.5 % to 2.7 %, and — this is the part that matters — the misses land on both sides of zero instead of all above it. One-sided is an offset; two-sided is scatter.
Read that number as what it is. Those rider values are not published anywhere: we searched for them with our own solver, then checked them against it. A rider picked to fit eight numbers fits them partly by construction, so the 2.7 % is not a seal of approval. It is the remainder that even the best imaginable rider does not explain. What the calculators do document (Gribble: 2 % drivetrain loss, Crr 0.005, CdA 0.32, 82.6 kg) does not reproduce their own published speeds either. It misses by more, not less. Which rider the author of these numbers actually dialled in is unknown, and it stays unknown.
This page said something different until 27 Sep 2026. It reported the spread as a 2–7 % offset of our model and counted all 8 anchors as evidence for it. Two of them sit closer to us than their own rounding allows — a reference written as “24 km/h” cannot carry a 2 % claim — so they were never evidence either way, and they now read rounding rather than pass. We are leaving the correction visible: a page you are invited to re-check is worth more with its own errata than without them.
Results only. The model itself runs in SI — CdA in m², air density in kg/m³, forces in newtons — and is not converted, because that is the form anyone checking the physics expects. The acceleration benchmark switches with the units rather than being converted: 0 → 30 km/h metric, 0 → 20 mph imperial, the customary test in each. Everything below is the same calculation, read out in your units.
SPEED MATRIX: km/h (grade × power)
| grade \ W | 100 | 150 | 200 | 250 | 300 | 350 | 400 |
|---|---|---|---|---|---|---|---|
| -8% | 63.0 | 64.2 | 65.3 | 66.4 | 67.5 | 68.5 | 69.5 |
| -4% | 46.3 | 48.4 | 50.2 | 51.9 | 53.4 | 54.9 | 56.2 |
| -2% | 36.1 | 39.0 | 41.5 | 43.7 | 45.6 | 47.4 | 49.0 |
| 0% | 24.4 | 28.8 | 32.1 | 35.0 | 37.4 | 39.6 | 41.6 |
| +2% | 14.4 | 19.3 | 23.3 | 26.6 | 29.5 | 32.0 | 34.3 |
| +4% | 9.0 | 13.0 | 16.6 | 19.9 | 22.7 | 25.4 | 27.7 |
| +6% | 6.4 | 9.5 | 12.4 | 15.1 | 17.7 | 20.1 | 22.4 |
| +8% | 4.9 | 7.4 | 9.7 | 12.0 | 14.2 | 16.3 | 18.4 |
| +10% | 4.0 | 6.0 | 8.0 | 9.9 | 11.8 | 13.6 | 15.4 |
| +12% | 3.4 | 5.1 | 6.7 | 8.4 | 10.0 | 11.6 | 13.2 |
| +15% | 2.7 | 4.1 | 5.5 | 6.8 | 8.2 | 9.5 | 10.8 |
Each cell is solveSpeedKmh(power, grade, rider) — the exact value the ride uses. Read down a column and you can see the balance tip: At 250 W the flat is aero-dominated, the 8 % climb is gravity-dominated.
ROUTE SIMULATIONS
| Route | Dist | Time | Avg | Min | Max | Ascent | Descent | Gear @avg | rpm | Climb gear |
|---|---|---|---|---|---|---|---|---|---|---|
| Pancake Flat 10 km dead flat — the aero/rolling baseline. | 10 km | 17:03 | 35.2 | 35.2 | 35.2 | 0 m | 0 m | 54/17 | 88 | — |
| Rolling Hills 12 km of ±3 % rollers — punchy, never steep. | 12 km | 23:00 | 31.3 | 23.2 | 48.0 | 180 m | 180 m | 39/14 | 89 | 141 rpm @ 3% |
| Alpine Climb 8 km at a steady 7 % — a real mountain pass. | 8 km | 35:16 | 13.6 | 13.6 | 13.6 | 560 m | 0 m | 39/30 | 83 | 83 rpm @ 7% |
| Fast Descent 6 km at −6 % — coasting / pedalling downhill. | 6 km | 6:03 | 59.6 | 59.6 | 59.6 | 0 m | 360 m | 54/11 | 96 | — |
| Mixed Classic 4 km @ 5 % up · 4 km @ −5 % down · 4 km flat. | 12 km | 24:51 | 29.0 | 17.5 | 55.9 | 200 m | 200 m | 54/21 | 89 | 106 rpm @ 5% |
Each route integrates the steady-state speed segment-by-segment at a constant 3.0 W/kg. “rpm” is the cadence in the gear closest to 90. Yellow means no gear in the All-round (54/39 × 11-30) drivetrain keeps you in the 80–100 band at that speed.
LEADERBOARD PAR: the target you race
The OutRide Arcade Rating + Time-Trial medals rank you against a par time, not raw speed, so a flat sprint and a mountain climb compare fairly. The par is your silver pace: stageTargetSec = this same solveSpeedKmh model run for you at 88% of your own FTP, the same budget the silver medal is judged against. The table shows it for a 75 kg rider at each class's reference W/kg, so you can see the shape: steep climbs cost a weak (E) rider far more than a lookup table would ever guess. That's gravity, done honestly.
| Stage | A 4.3 W/kg | B 3.6 W/kg | C 2.9 W/kg | D 2.1 W/kg | E 1.5 W/kg |
|---|---|---|---|---|---|
| 1 km · flat | 1:39 | 1:46 | 1:56 | 2:10 | 2:31 |
| 1 km · rolling +2.5% | 2:15 | 2:31 | 2:57 | 3:37 | 4:48 |
| 1 km · hilly +4.5% | 2:57 | 3:23 | 4:07 | 5:18 | 7:22 |
| 1 km · climb +7% | 3:59 | 4:41 | 5:50 | 7:39 | 10:48 |
| 1 km · descent −3% | 1:14 | 1:16 | 1:20 | 1:23 | 1:28 |
| 5 km · flat | 8:15 | 8:50 | 9:41 | 10:53 | 12:41 |
Ride under your class's par → positive Arcade Rating (1000 = par). Because it's par-relative, no single fork line is a “farm”. Every route rewards the same relative effort equally.
ROLLING PENALTY: same average, not the same time
A 10 km course that averages 2.0% is not one time. How the climb is distributed changes it a lot. profileTimeSec integrates the same solveSpeedKmhfoot-by-foot over the real elevation profile, the honest way to time a course, and the model behind profile-aware ghost + par times. Rolling terrain is genuinely slower: the time lost grinding steep pitches dwarfs the time won on the descents (drag caps downhill speed), so a “Rollers” course with 30% descent is the slowest of all, not the fastest. All at 3.0 W/kg.
| Profile | Grade range | Descent | Time (10 km) | vs constant |
|---|---|---|---|---|
| Constant | 2.0…2.0% | 0% | 22:20 | — |
| Front-load | 0.0…4.0% | 0% | 22:43 | +23s (+1.7%) |
| Back-load | 0.0…4.0% | 0% | 22:43 | +23s (+1.7%) |
| Wave | 0.0…4.0% | 0% | 22:54 | +34s (+2.6%) |
| Plateau | 0.8…3.2% | 0% | 23:34 | +75s (+5.6%) |
| Rollers | -1.6…5.6% | 31% | 24:04 | +104s (+7.8%) |
| Valley | -1.4…5.4% | 30% | 23:53 | +94s (+7.0%) |
At 0% average every shape is identical (nothing to distribute). The penalty grows with the average grade and the “peakiness” of the profile, which is exactly why a naive average-grade lookup would hand out unfair targets on a hilly course. Same physics, done honestly.
ACCELERATION: standing start (real F = m·a)
| Scenario | Power | Grade | Terminal | 0 → 30 km/h | → 90 % terminal | Distance |
|---|---|---|---|---|---|---|
| Easy roll-out | 150 W | 0% | 28.8 km/h | — | 29.2 s | 149 m |
| Endurance flat | 250 W | 0% | 35.0 km/h | 20.2 s | 24.5 s | 154 m |
| Sprint jump | 600 W | 0% | 48.1 km/h | 6.3 s | 18.2 s | 160 m |
| Tempo, 4 % climb | 250 W | 4% | 19.9 km/h | — | 14.6 s | 50 m |
| Attack, 8 % climb | 350 W | 8% | 16.3 km/h | — | 8.7 s | 23 m |
Driven by the actual ride integrator step() from a standstill. The terminal speed is identical to the solver. Only the wind-up is now Newtonian, so a 84.5 kg rider on this equipment shows real launch lag and a sprint has punch. Heavier mass or less power = slower to wind up.
GEAR / CADENCE LADDER — All-round (54/39 × 11-30)
| Speed | Easiest gear rpm | Hardest gear rpm | 80–100 band reachable? |
|---|---|---|---|
| 12.0 km/h | 73 | 19 | no gear in band |
| 18.0 km/h | 110 | 29 | yes |
| 24.0 km/h | 146 | 39 | yes |
| 30.0 km/h | 183 | 48 | yes |
| 36.0 km/h | 219 | 58 | yes |
| 42.0 km/h | 256 | 68 | yes |
| 48.0 km/h | 292 | 77 | yes |
| 54.0 km/h | 329 | 87 | yes |
A row marked has a gear that holds the target cadence band at that speed; at the top and bottom of the range you’d spin out or grind, exactly what a real drivetrain does.