The safe zone
The very first chunks must be hazard-free so the player can learn to run and jump before dying. The game marks chunks whose worldX < 700 as safe:
const inSafeZone = worldX < 700;
const gapChance = inSafeZone ? 0 : Math.min(0.28, difficulty * 0.6);
const hazardRate = inSafeZone ? 0 : difficulty * 0.7 + 0.05;
In the safe zone, gapChance and hazardRate are forced to 0. The player spawns on solid ground with no pits and no spikes. Once past x = 700, the real difficulty curve takes over.
This is a fairness rule too: no death should happen before the player has had a chance to learn the controls. The first few seconds are always safe.
Coins without risk
Coins must never sit on top of a hazard or in a pit, you don't want to force "grab the coin or die." The generator keeps a forbidden list of x-intervals (where pits and hazards live) and checks every coin placement against it:
function clearOfHazards(coinX, coinW, forbidden, clearance = 48) {
for (const f of forbidden) {
const gapLeft = coinX - f.x - f.w; // coin is left of the forbidden zone
const gapRight = f.x - (coinX + coinW); // coin is right of the forbidden zone
if (gapLeft < clearance && gapRight < clearance) return false;
}
return true;
}
clearance = 48 px is the minimum buffer between a coin and any danger. If placing a coin would violate it, skip that spot. The generator tries several positions until it finds a clean one, or places a fallback coin somewhere safe so the player is always rewarded.
Notice CONFIG.COIN_CLEARANCE = 48 in the real config, the same constant, now enforcing fairness at generation time.