HomeMethodDinosaur game: the jump
Why the dinosaur game's jump feels right: 0.6, 12, and 35
The official REA site already published the speed rule of Chrome's offline runner — start at 6, add 0.001 per clean update, stop at 13. That is the horizontal axis. The vertical one is the better teaching target, because the two constants you can read are not enough to predict the arc. Layer: JavaScript. Steps follow the 6-step loop.
Independent guide. We document behaviour and rebuild rules in our own code. Not affiliated with the authors of morluto/rea; install only from them. This page quotes a Chromium-derived game under its BSD-style licence and links to the official lab rather than duplicating it.
Step 1 — the behaviour, stated so it can be wrong
"The jump feels good" cannot be tested. This can:
- Trigger: hold the jump key, then release it early versus late.
- Observable output: the peak height changes with the press, and does not fall below a floor.
- Constraint: the peak has to depend on the press, not on a random or per-run value — otherwise the game would not be fair at high speed.
Step 2–3 — fingerprint and layer
A browser page, one script, no engine, no native toolchain. The official lab used a local debugging connection to read the loaded script; DevTools gets you the same view. Nothing to install.
Findings
| Observation | Evidence | Confidence | What it does not prove |
|---|---|---|---|
GRAVITY: 0.6, INITIAL_JUMP_VELOCITY: 12, MIN_JUMP_HEIGHT: 35 | Runner.config, index.js @ 5455bfa | High | Per-frame units; no metre or second semantics implied |
var FPS = 60; with msPerFrame = 1000 / FPS | Top of index.js | High | The frame rate is not locked to reality — a real 120 Hz display changes the feel |
startJump(this.currentSpeed) | onKeyDown | High | That the speed argument dominates the arc; it could be used for a sub-case only |
endJump() on key release; setSpeedDrop() when DOWN is pressed mid-jump with SPEED_DROP_COEFFICIENT: 3 | onKeyUp, onKeyDown | High | The exact velocity rewrite inside those two methods |
updateJump(deltaTime) is called every frame while jumping | update() | High | Whether the integration is Euler-per-frame or delta-scaled — that changes the timing on a 120 Hz screen |
A MAX_JUMP_HEIGHT-style ceiling value | Not reached — the player object's own config sits past a 30 k-character read limit | None | Nothing. It is a gap, published as a gap |
Step 5 — the rule, as far as we can write it
// Our reconstruction. Names are ours; the constants are from the source.
on jump press:
vy = INITIAL_JUMP_VELOCITY // 12 px per frame, upward
hold = true
per frame while airborne:
vy -= GRAVITY // 0.6 px per frame^2
if hold released AND height >= MIN_JUMP_HEIGHT AND vy > 0:
vy = 0 // the floor: 35 px
height += vy
if height <= 0: land
on jump press, speed is passed in // so the arc may not be a constantWhat the readable numbers predict. With v = 12 and g = 0.6, treating the pair as continuous gives v² / 2g = 120 px, reached in v / g = 20 frames — about 0.33 s up, and a full round trip near 0.67 s — inside a 150 px stage with a 10 px bottom pad. Stepping the same constants and summing v + (v − g) + … down to the last positive term gives 126 px in the same 20 frames. Derived arithmetic, not a measured fact. The instrument that draws both, and lets you type a measurement from the real game, is the dinosaur jump lab. There is one copy of that harness, so this page does not keep a second one.
A full-length press is the disagreement between 120 and 126. Shortening the press is a third disagreement: once height has cleared MIN_JUMP_HEIGHT 35, the climb is cut off, and neither closed form includes that floor. A rebuild that ignores the floor will clear one obstacle and miss the next. The speed argument at the call site is still unread inside startJump, so a rebuild that ignores speed might diverge as distance grows — that is why the official speed lab and this page are two halves of one file. Read the official speed rule and lab for the horizontal axis. Do not re-derive it here.
Try it yourself
Use REA to inspect the loaded script of a browser dinosaur game
(JavaScript layer only, no native target).
Report, each with file and line evidence:
- the gravity and initial jump velocity values and their units
- what happens to the vertical velocity when the jump key is released
- whether the jump arc depends on the game's current speed
- any ceiling value you cannot locate, and why you cannot locate it
Do not propose a rebuild yet.Not wired up yet? REA + Claude Code setup. If your read stops early, that is why step 6 measures instead of trusting step 4.
What we could not confirm. The vertical-velocity rewrite inside endJump(), whether the ceiling is a constant or computed, and how deltaTime rescales the integration on a 120 Hz display. The gap stays a gap. On a per-frame reading, a faster display should change airtime and leave height alone; the lab is where that gets tested, not asserted.
Next
Night mode
Why dinosaur game night mode flips every 700 units, and why the score is an integral, not a counter.
Walkthrough →InstrumentMeasure the arc
Two models, one diff table. This is the harness for the numbers above.
Open the lab →MethodThe six steps
The loop this page ran, including the deliverable each step owes you.
Read the loop →