How We Tuned Space Canyon's Difficulty (A Postmortem)

When we launched Space Canyon — our one-button cave flyer where you hold to climb and release to dive — the very first feedback we received was blunt: "way too hard." Not hard in the fun, one-more-try way. Hard in the way that makes people close the tab after twenty seconds. This post is an honest breakdown of what was wrong with the original physics, exactly which numbers we changed, and how we used a simulated autopilot to prove the new tuning worked before shipping it. Every constant below is the real value from our source code.

The game in one paragraph

In Space Canyon your ship flies forward automatically through a procedurally generated canyon. You have exactly one input: press to fire the thruster and climb, release to fall. The canyon has ten levels; each one is narrower and scrolls faster than the last. It runs on a plain HTML canvas with about 17 KB of JavaScript, no libraries, and works with touch, mouse or keyboard. One input, one goal — which means the entire game is its physics. If the physics feel wrong, there is nothing else to hide behind.

The original physics — and why players hated it

Our first shipped build used a gravity of 900 px/s² and a thrust of 1400 px/s². Do the subtraction and the problem appears immediately: while holding the button, the net upward acceleration is 1400 − 900 = 500 px/s², but while released, the ship falls at the full 900 px/s². The ship dropped almost twice as fast as it climbed — a 1 : 1.8 asymmetry that we never consciously chose. It simply emerged from picking two numbers that each looked reasonable on their own.

Why does that asymmetry hurt so much? Because every player arrives with a mental model of a one-button flyer: tap to nudge up, let go to drift down, roughly balanced. With our numbers, recovering from a dive required nearly twice the anticipation of recovering from a climb. Players described the ship as "heavy" and said it "drops like a rock" — and they were right. On top of that, terminal fall speed (MAX_VY) was capped at 420 px/s. In a 230-pixel-tall passage, a ship at terminal velocity crosses more than half the corridor in a quarter of a second, which is close to average human reaction time. The game was literally outrunning its players' nervous systems.

The level progression compounded the pain. The passage gap shrank by the formula 230 − 12·(level−1), so level 10 was a 122-pixel slot. Scroll speed grew by 180 + 22·(level−1), reaching 378 px/s at level 10. Both curves were steep, and they multiplied each other: narrower corridors arrived exactly when there was less time to react to them.

The fix: exact numbers, before and after

ConstantBeforeAfterEffect
Gravity900 px/s²760 px/s²Slower, softer falls
Thrust1400 px/s²1520 px/s²Net climb 500 → 760: perfectly symmetric ±760
Max fall/climb speed420 px/s360 px/sMore time to correct mistakes
Passage gap230 − 12·(lv−1)260 − 9·(lv−1)Level 10 gap: 122 px → 179 px
Scroll speed180 + 22·(lv−1)155 + 15·(lv−1)Level 10 speed: 378 → 290 px/s

The single most important change is the second row. Raising thrust to 1520 while lowering gravity to 760 makes the net acceleration exactly ±760 px/s² in both directions. Holding the button now climbs precisely as fast as releasing it falls. The ship stopped feeling heavy overnight, without slowing the game down: we did not add floatiness, we removed unfairness. Lowering the velocity cap from 420 to 360 px/s bought players roughly 17% more reaction time at full speed, and the gentler gap and speed ramps mean level 10 is still the hardest thing on the site — but it is now a skill test, not a coin flip.

Proving it with an autopilot

Here is the trap with difficulty tuning: after two hundred test flights, the developer is the best Space Canyon player on Earth, and their hands are worthless as a measuring instrument. We needed a fixed-skill reference player. So we wrote a headless autopilot: a small script that runs the exact game logic without rendering and flies with a deliberately simple policy — thrust when the ship is below the center line of the next gap, release when above it, with its decisions constrained so it cannot react faster than a human plausibly would.

Then we ran batches of simulated runs against both tunings. Under the original physics, the autopilot died on average at level 2.9 — it usually could not even see the midpoint of the game. Under the new physics, the same unchanged pilot averaged level 7.5. That was exactly the band we were aiming for: deep enough that an ordinary run shows real progress, short of level 10 so that finishing the canyon still means something.

An autopilot is not a human, and we do not pretend the absolute numbers transfer. But for relative comparisons — same pilot, two rule sets — it is a wonderfully honest judge. It also caught degenerate cases for free: with the old gap formula, some generated sequences were flat-out impossible to fly cleanly, something our own practiced hands had learned to route around without noticing.

What we learned

  • One-button games live or die on symmetry. If climb and fall rates differ, players feel it within seconds, even if they cannot name it.
  • "Too hard" almost always means "unfair," not "challenging." Nobody complained about level 10 being brutal once levels 1–3 felt controllable.
  • Tune with data, not with developer hands. A fixed-skill bot is a few dozen lines of code and it never gets better at the game between test sessions.
  • Change the base feel first, the difficulty curve second. Symmetric physics fixed 80% of the complaints before we touched the level formulas at all.

If you want to feel the result of all this number-shuffling yourself, Space Canyon is right here — no install, no sign-up, and level 10 is waiting. If you make it through all ten levels, we would genuinely love to hear about it on the contact page.

Read next