How Procedural Platforms Work
Procedural platforms are platforms that a game creates with code while you play, instead of a designer placing each one by hand. A generator picks positions, types and spacing from a set of rules and a stream of random numbers, and it checks that each new platform can actually be reached. That is how an endless climb can keep going without ever running out of level, and how a daily course can be different every day yet identical for every player on the same date.
Hand-built levels versus generated levels
In a hand-built level, every ledge, gap and hazard is placed once and saved. You can memorize it, and a designer can polish every jump. The trade-off is that the level ends. Classic side-scrolling platformers usually take this route because they tell a fixed story from start to finish.
A generated level is described by rules rather than coordinates. The designer decides things like "the next platform appears between this and that height above the last one" or "a crumbling platform can appear once the player has climbed a certain distance," and the program fills in the details as the screen scrolls. The result has no end point, which suits arcade games built around a score rather than a finish line.
Many games mix the two. Spike Jumper, for example, runs through generated sections of static spikes and moving spike blocks, with checkpoint flags between them so a mistake sends you back to the last flag instead of the very beginning.
The basic generation loop
Most platform generators follow the same small loop. The game keeps track of the highest (or furthest) platform it has created. Whenever the camera gets close to that point, it creates a few more and throws away the ones that have scrolled out of view.
- While the highest platform is less than a screen above the camera:
gap = randomBetween(minGap, maxGap(height)) - Pick a horizontal position:
x = randomBetween(leftEdge, rightEdge - width) - Pick what kind of platform it is:
type = pickType(height) - Create it and remember the new top:
spawnPlatform(x, topY - gap, type); topY -= gap
This is pseudo-code, not the source of any specific game, but the shape is typical. Notice two details. First, maxGap and pickType take the current height as input, which is how difficulty rises as you climb. Second, the generator only works a little way ahead of the camera, so memory use stays flat no matter how long a run lasts.
Recycling platforms that leave the screen
Platforms that drop below the bottom of the view are removed or reused. In a vertical climber like Endless Jumper, falling below the screen ends the run anyway, so there is no reason to keep anything down there.
Keeping every jump possible
Randomness alone produces unfair layouts: a gap too wide to cross, or two platforms stacked so closely you cannot fit between them. Good generators add reachability constraints built from the player's own movement limits.
- Maximum vertical gap. The distance between platforms must stay below the height of a normal jump, with a safety margin.
- Maximum horizontal offset. The next platform must be within the distance you can steer sideways during one jump. In games where leaving one side of the screen wraps you to the other, the generator can measure that distance around the edge too.
- A guaranteed safe path. If a platform type is risky, such as one that crumbles after a single bounce, the generator can make sure a stable option is also within reach.
The simplest way to find the maximum jump height is basic projectile math. With launch speed v and gravity g, the peak is v * v / (2 * g). Our guide to jumping game physics walks through where that number comes from.
Tip for players: because generators leave a safety margin, a gap that looks impossible is usually reachable with a full-strength jump and early steering. If a climb feels unfair, try committing to the sideways input sooner rather than jumping harder.
How difficulty ramps up
A generator is also the place where difficulty lives. Instead of designing harder levels, the designer changes the rule inputs as height or distance grows. Common levers include:
| Lever | What changes | Example on Jumping Arcade |
|---|---|---|
| Spacing | Gaps between platforms widen | Endless Jumper widens gaps as you climb |
| Platform mix | Special platforms appear more often | Moving, crumbling and spring platforms become more common in Endless Jumper |
| Density | Fewer landing spots per screen | Trampoline pads get sparser with height in Bounce Up |
| Motion | Platforms drift or move | Cloud platforms drift sideways in Sky Jump |
The important design choice is that these values change gradually. A smooth curve means the first minute teaches the basics and later sections test them, without a sudden wall that feels arbitrary.
Weighted platform types
Picking a platform type is usually a weighted random choice. Early on, a normal platform might have most of the weight; higher up, the weight shifts toward moving, crumbling or spring types. The function looks something like pickType(height) returning a type based on a table of weights that is interpolated by height.
Seeded random numbers and daily courses
Computers generate "random" numbers with algorithms called pseudo-random number generators. Given the same starting value, called a seed, they produce the exact same sequence every time. That property is what makes shared courses possible.
seed = dateToNumber(todayInUTC)gives the same number to everyone on the same date.rng = createGenerator(seed)starts a repeatable sequence from that number.gap = minGap + rng() * (maxGap - minGap)then produces identical gaps for every player.
Daily Jump Challenge uses this idea. Its vertical course is generated from the date in UTC, so every player gets the same layout on the same day, and the layout changes when the date changes. You have 60 seconds to climb as high as possible, and your best score for the day is saved locally in your browser.
Why use UTC rather than local time? Because players in different time zones would otherwise see a new course at different moments. A single reference clock keeps the day's layout consistent.
An endless game can use an unseeded generator, such as the browser's built-in Math.random(), because nobody needs to reproduce a specific run. A daily or shareable course needs a seeded one, since the built-in function cannot be given a seed.
What this means when you play
Knowing how the generator thinks gives you practical advantages:
- Look ahead, not just down. New platforms appear just beyond the top of the screen. Keeping your character a little below the top edge gives you more time to see what is coming.
- Expect the mix to shift. In Sky Jump, drifting clouds and wind gusts are part of the pattern, so treat the WIND indicator as information about your next landing.
- Replay the daily layout. Because the daily course is fixed for the date, each attempt teaches you something about that exact layout. Repeating a known route is where improvement comes from.
- Do not hunt for secret patterns in endless mode. Unseeded runs will not repeat, so learn the rules (gap sizes, platform behaviors) rather than specific layouts.
For a broader look at climbing games, see vertical platform games explained, or browse all endless jumping games.
Key takeaways
- Procedural platforms are created by rules and random numbers as you play, so the level never runs out.
- Reachability limits based on jump height and sideways reach keep generated gaps fair.
- Difficulty rises by adjusting spacing, platform mix, density and motion as height or distance grows.
- A seeded generator produces the same layout from the same seed, which is how a date-based daily course matches for everyone.
- As a player, learn the rules of an endless generator and the route of a seeded daily course.
If you are curious how these rules fit into the bigger picture of making a game feel fair and fun, continue with arcade jumping game design basics.