Unreal 5 – Endless Runner


Building an endless runner inspired by Subway Surfers: procedural tile generation, lane switching, difficulty escalation, and the illusion of infinite movement.


This project is an endless runner prototype built entirely in Blueprints with Unreal Engine 5, inspired by Subway Surfers and developed following this Udemy course. The endless runner is a deceptively simple genre — the player runs forward automatically, avoids obstacles, and collects coins — but its implementation requires solving a specific technical problem that doesn’t appear in any other game type: how do you simulate an infinite world without actually having one?

You can watch the prototype in action here: YouTube


The Infinite World Illusion: Tile Streaming

An endless runner can’t pre-build its entire level — the game is designed to run indefinitely, and no finite amount of pre-placed geometry can represent an infinite distance. The solution is tile streaming: the world is divided into fixed-length tile segments, and the game continuously spawns new tiles ahead of the player while despawning old ones behind.

The tile pool works as follows: a set of tile actors — each representing a short section of track with obstacles, coins, and decoration baked in — is spawned at the player’s starting position. As the player moves forward and the rearmost tile falls far enough behind, it’s either destroyed and a new tile spawned at the front, or it’s repositioned to the front (object pooling). Object pooling — reusing existing tile actors rather than destroying and spawning — is the correct approach for performance: spawn operations are expensive in Unreal, and doing one every few seconds for an indefinitely long session produces frame spikes that accumulate over time.

The tiles themselves are selected randomly from a pool of tile variants with different obstacle and coin arrangements. The randomness produces the sense that the world is freshly generated ahead of the player rather than looping through a fixed sequence.


Lane Switching

The player character runs on a fixed forward axis but can switch between three lateral lanes — left, center, right — in response to player input. Lane switching is not free movement; it’s a discrete state change that lerps the character’s X position to the target lane’s X coordinate over a brief transition time.

The lerp produces a smooth visual transition while keeping the game’s logic simple: the player is always in one of three known positions, which makes obstacle collision detection and lane-based obstacle placement straightforward. Obstacles occupy one or more lanes; the player survives by being in a lane the obstacle doesn’t occupy.

The transition time — how long the lane switch takes — is one of the most important feel parameters in the game. Too slow and the player can’t react to obstacles that require switching two lanes quickly; too fast and the switch feels mechanical and cheap. A duration of around 0.15–0.25 seconds produces a responsive but visually legible transition.


Obstacle and Coin Placement

Obstacles and coins are placed within tiles in patterns designed to be readable and fair. A pattern is readable when the player can see what’s coming and has time to react; it’s fair when the correct response is always achievable within the reaction window. The key constraint is the player’s view distance — how far ahead they can see before the obstacle arrives — which determines the minimum reaction time available.

Obstacles vary in their lane coverage: some block a single lane, requiring a single switch; others block two lanes, requiring the player to be in the one open lane; some require jumping or sliding beneath. This variety prevents the game from reducing to a single repeated input and keeps the player actively reading the upcoming track.

Coins are arranged in curved paths through lanes — arcs that reward the player for making a specific sequence of lane switches. This pattern design, borrowed from mobile endless runners like Subway Surfers and Temple Run, makes coin collection feel purposeful rather than incidental.


Difficulty Escalation

The endless runner’s difficulty escalation is time-based: the longer the player survives, the faster the world moves. Speed is incremented on a configurable timer — every N seconds, the character’s forward speed increases by a fixed amount, up to a configured maximum. This produces a natural difficulty curve where the early game is accessible (slow speed, generous reaction time) and the late game is demanding (fast speed, tight reaction windows).

Beyond raw speed, later tiles can introduce more complex obstacle patterns — combinations that require multiple consecutive inputs to navigate — and reduce the gap between obstacles, increasing the density of decisions the player must make per second.

The score is distance-based or time-based, giving the player a concrete metric that improves as they survive longer. Displaying the score prominently in the HUD, along with the high score from previous runs, creates the retry motivation that drives the endless runner’s core loop.


Enemy AI: Pursuing Character

The enemy AI pursues the player from behind — a character running on the same track that catches up if the player slows down (by hesitating, taking damage, or failing to avoid obstacles that reduce speed). The enemy applies pressure without directly causing failure: the player fails by hitting obstacles, not by being caught. The enemy’s presence creates urgency — hesitation is punished not just by collision but by the approaching threat.

The enemy’s speed is slightly below the player’s base speed in the early game, creating a comfortable buffer. As the player’s speed increases with difficulty escalation, the enemy’s speed increases in parallel, keeping the threat consistent rather than becoming irrelevant at high speeds.


Third-Person Camera

The camera is positioned slightly above and behind the player, looking forward along the run direction. For an endless runner, this camera position serves a specific purpose: it shows enough of the upcoming track to give the player meaningful reaction time while keeping the character visible as a reference point for the lane the player is currently in.

The camera’s distance and height need to be tuned in relation to the tile length and obstacle size. If the camera is too close, the player can’t see far enough ahead to react. If it’s too far, obstacles become small and hard to read. The sweet spot is a camera that reveals roughly two tile lengths of upcoming track while keeping the player character legibly positioned in the center of the frame.


Reflection

The endless runner is one of the most efficient prototypes in this series in terms of the ratio between implementation complexity and gameplay depth. The tile streaming system, lane switching, and difficulty escalation together produce a game that’s immediately understandable, immediately playable, and endlessly replayable — the hallmarks of the genre’s mobile success.

The tile streaming pattern is the most transferable concept. It appears in any game that needs to simulate a world larger than what can be pre-loaded: open-world streaming, level streaming in narrative games, and procedural generation systems all use variants of the same idea — load what’s needed ahead, unload what’s left behind, recycle when possible. Understanding it in the context of an endless runner, where the pattern is explicit and unambiguous, builds the mental model that applies to its more complex variants.

Leave a comment

Create a website or blog at WordPress.com

Up ↑