The number that decides whether a track is fair
Redline builds its tunnel a few metres ahead of your front wheel. Most of the work in that generator isn't making interesting terrain — it's stopping the generator from killing you in ways you couldn't have prevented.
Redline is a motorbike run through a collapsing mine. You never steer; the only thing you control is the throttle, and the tunnel is generated continuously as you ride. That makes every hazard placement a small promise: this is survivable if you ride well. Break that promise once and the player stops believing the game, which is much worse than the game being hard.
Two constants do most of the work of keeping that promise, and we found both the same way — by being killed by our own game and being unable to say what we should have done differently.
Sixteen cells
A flat-out jump in Redline covers about 100 pixels of ground. It isn't symmetrical: the bike leaves the ground roughly 42 pixels before the obstacle and comes down about 58 pixels past it. That asymmetry is the whole problem.
If the generator places two must-jump hazards close together, the landing arc from the first one puts you down on top of the second. Not near it — on it. And there is nothing the player can do about that, because the decision that killed them was made while they were still airborne from a jump they cleared correctly.
So the generator enforces a minimum spacing:
var MIN_GAP = 16; // cells — 128 px
Sixteen cells is 128 pixels, comfortably more than the 100-pixel jump arc. Hazards are never generated closer together than that, no matter how deep into the run you are or how hard the difficulty curve is pushing. The rest of the difficulty ramp — hazards arriving more often, the gaps between features shrinking from around 24 cells down toward the minimum — all operates above that floor.
It's one line, and it's the difference between a game that's hard and a game that's unfair. Everything else in the generator can be tuned by feel. This one is arithmetic, and it isn't negotiable.
Four hundred and eighty pixels
The second constant is about what happens after you die, and it's the more interesting mistake because the obvious implementation is actively broken.
When you crash, you restart from a standing start — speed zero. The obvious thing to do is put the player back at the last safe spot before the hazard that killed them. We did that, and created a loop nobody could escape.
Here's why. Redline's widest pit is tuned so that clearing it requires top gear. If you respawn just before that pit, you have a few metres of road to accelerate in, you arrive in second or third, you drop straight into it — and respawn in exactly the same place, at exactly the same speed, to fail in exactly the same way. Forever. The player's remaining lives drain away with no decision available to them at any point.
var RESPAWN_RUNUP = 480;
480 pixels is how much road full throttle needs to reach top gear. So the respawn logic walks backwards through the recorded safe positions until it finds one at least that far back. You restart further from where you died than feels natural, and that's the point: you restart somewhere the hazard is actually beatable from.
The bat, and the arithmetic of a fair decision
The hazard we're happiest with is the bat, because it's the one you solve by slowing down — in a game otherwise entirely about going fast. It sweeps up and down across the tunnel, so for part of its cycle the way past is simply shut. The correct play is to hang back, watch it rise, then go.
That only works if the player can actually read it in time, and the numbers here are tight:
| Quantity | Value |
|---|---|
| How far ahead you can see | 184 px |
| Full-speed stopping distance | 116 px |
| Bike height the bat must clear | 16 px |
| Bat sweep period | 2–6 s |
You see the bat 184 pixels out and need 116 of those to stop, which leaves a real but narrow margin to decide. If the bat blocked the tunnel most of the time, that margin would make it a coin toss — you'd arrive, it'd be down, you'd die, and the "decision" would have been made by the random phase of its sweep.
So the bat's amplitude and resting height are set so it only intrudes into the bike's 16 pixels of clearance for roughly a third of its cycle, and the sweep is slow enough that you can read its phase from across the screen and know whether it's rising or falling. It's a decision, not a dice roll — but only because of numbers that look arbitrary until you know what they're protecting.
Generate freely, then check
The pattern underneath all of this is one we now use everywhere: let the generator do whatever it likes, then verify the output is actually playable, rather than trying to write a generator careful enough to never need checking.
Redline does this structurally — features are emitted whole and never straddle a section boundary, the last 22 columns of every section are reserved for a flat run up to the checkpoint gate, and no single feature is longer than 14 columns, so there's always spare. The gate is clamped into that run no matter how it falls, because a section that ended without its gate would silently cost the player the whole section bonus.
The same idea shows up in Castaway, where the island generator places everything freely and then we compute the shortest possible tour of the three engine parts and reject maps that demand more than a fixed maximum. The turn budget sits just above that maximum, which is what makes the storm a real deadline on every map rather than only the unlucky ones.
Constraining a generator during generation is hard, tangles the code, and tends to make everything it produces feel the same. Checking its output afterwards is easy, keeps the variety, and turns "is this fair?" from a matter of taste into something you can assert.