Procedural generation has a bad reputation among players, usually because of games where it produced something unfair. Done properly it is the opposite: a set of constraints strict enough that unfairness is not expressible.
Here is how the spawners in these games work, and what they are forbidden from doing.
The spawner's job
At any moment the spawner is asked one question: given the current speed and what was placed last, what goes next and how far ahead?
Getting this right means satisfying four requirements at once:
- Variety — the sequence must not become predictable.
- Solvability — every obstacle must be clearable from the player's current state.
- Readability — the player must be able to identify the response in the time available.
- Pacing — bursts and lulls, not a metronome.
Most of the interesting work is in requirement 2.
Rule 1: spacing scales with speed
Fixed pixel spacing is the classic mistake. At 360 px/s, 400 pixels of gap is 1.1 seconds of thinking time; at 620 px/s the same gap is 0.65 seconds. The game would become impossible without anything visibly changing.
Ninja Dash derives spacing from speed instead:
spacing = speed * 0.82 + 120
At 360 px/s that gives 415 pixels (1.15 s). At 620 px/s it gives 628 pixels (1.01 s). The physical distance grows so the time barely shrinks, which is why the game stays playable at its cap.
Rule 2: some sequences are forbidden
Certain pairs are unfair regardless of spacing, because they require two actions inside one animation.
A slide beam followed by a gap is the canonical example: the slide takes half a second and cannot be cancelled, so the jump cannot happen until it finishes. Ninja Dash's spawner explicitly refuses to place a gap immediately after a beam.
Most runners carry a short list like this. It is unglamorous work and it is the difference between a game players trust and one they abandon.
Rule 3: gap width comes from the jump arc
The most important constraint in the genre. Before generating a gap, the game computes what the character can actually do:
var airTime = (2 * -JUMP_V) / GRAVITY; // 0.73 s in Ninja Dash
var reach = speed * airTime; // e.g. 350 px at 480 px/s
var width = rand(90, Math.min(200, reach * 0.62));
Two details matter.
The 0.62 factor is the safety margin. A gap is never more than 62% of what the character can clear, so a slightly mistimed jump still survives.
JUMP_V is the un-boosted velocity. The calculation deliberately excludes the extra lift from holding the jump key, because a mobile swipe cannot express "hold". The gap must be clearable by the weakest input the game accepts.
That is why, in a well-built runner, falling into a gap always means you jumped late — never that you jumped too weakly.
Rule 4: guaranteed-safe options in lane games
Lane runners replace arcs with choices, so the constraint changes shape. Shuriken Sprint shuffles the three lanes and fills at most two at any depth, which guarantees a free lane exists no matter how fast the game gets.
Ninja Coin Rush applies the same idea vertically: every barrier pair leaves at least 150 pixels of clearance, positioned randomly within the corridor.
Random spawning versus designed blocks
There are two philosophies, and they produce noticeably different games.
Random spawning
Each obstacle is chosen independently, subject to the rules above. Ninja Dash and Shadow Escape work this way.
- Strengths: genuinely unpredictable, endlessly varied, cheap to implement.
- Weaknesses: no sense of authored rhythm. Sequences are fair but rarely interesting in themselves.
Designed blocks
A library of hand-authored multi-obstacle patterns, selected and concatenated. Ninja Obstacle Master uses eight blocks: crate hops, slide beams, pits, disc gates, wall towers, moving-platform crossings, a gauntlet and a double tower.
- Strengths: each block is a designed timing puzzle with an intended solution. Players can learn and recognise them, which creates real mastery.
- Weaknesses: finite. Once you know all eight, only their order is a surprise.
The hybrid — random order, designed content — is where most modern runners land, and it is what Ninja Obstacle Master does.
Difficulty tiers in the spawner
Designed-block systems can gate their library by progress:
| Distance | Blocks in the pool |
|---|---|
| 0 | Crates, beams |
| 3,200 px | + pits, disc gates |
| 6,400 px | + wall towers, moving platforms |
| 9,600 px | + gauntlet, double tower |
The reason is pedagogical: a wall tower needs a wall jump, and a wall jump needs the player to have already learnt jumping and timing. Showing it in the first ten seconds teaches a new player that the game is unfair.
Collectible placement
Collectibles are placed after obstacles, not before, and their job is to mark the intended route.
In Ninja Dash, coin arcs are laid over an obstacle in a shape that mirrors the jump needed to clear it — a rising and falling arc over a crate, a flat line on clear ground. In Ninja Obstacle Master, stars sit on the line through each block.
This is quiet teaching. A player following the coins is executing the designer's intended solution without ever being told what it was.
Key takeaways
- Spacing must scale with speed, or the game becomes impossible as it accelerates.
- Some obstacle pairs are structurally unfair and must be forbidden outright.
- Gap widths are derived from the actual jump arc, using the un-boosted jump so touch input always works.
- Lane and corridor games guarantee a safe option at every depth.
- Random spawning gives variety; designed blocks give learnable mastery. The hybrid gives both.
- Collectibles mark the intended route, which teaches the solution without a tutorial.
Frequently asked questions
Is the obstacle sequence in a runner truly random?
The choice of obstacle usually is, but spacing, width and legal sequences are all constrained. The result feels unpredictable while remaining always solvable.
Can a runner generate an impossible situation?
Not if it checks generated distances against the character's real movement limits, which every game here does. Unfair generation is a bug, not an inherent property of procedural content.
Why do the coins follow the obstacles so neatly?
Because they mark the intended route. Following a coin arc usually means executing the jump the designer had in mind.
What is the difference between random spawning and designed blocks?
Random spawning picks each obstacle independently; designed blocks stitch together hand-authored multi-obstacle patterns. Blocks are learnable and rhythmic; random spawning is more varied.
Why do new obstacle types appear later in a run?
Difficulty tiering. Blocks that require a technique are held back until you have travelled far enough to have had a chance to learn it.
Ready to put this into practice?
Everything above is easier to feel than to read about. Open the game and try one run with just one of these ideas in mind.