Procedural content generation is one of the most useful tools in a 2D game developer’s kit, and one of the easiest to misuse. The lure of “infinite content” sounds tidy on a slide deck. In practice, PCG gives you infinite variation, which is not the same thing as infinite quality. That distinction matters. It is what separates randomised content that feels deliberate from content that looks as if an algorithm had a busy afternoon and then called it a day.
At Relish Games, we’ve worked with procedural techniques in both game content and tooling contexts. This is the practical version: what holds up, what breaks down, and where the trade-offs sit.
Dungeon and Level Generation
This is the most common use of PCG in 2D games, and the area with the most established methods.
Binary Space Partition (BSP)
BSP recursively divides a rectangular space into smaller rooms, then connects them with corridors.
Start with the full map area. Split it vertically or horizontally at a random point. Recursively split each half until the rooms reach minimum size. Place rooms within each partition, then connect adjacent partitions with corridors.
The appeal is straightforward. BSP guarantees non-overlapping rooms, produces clean grid-friendly layouts, and makes it easy to keep the level connected. The cost is just as clear. Rooms tend to feel regular and boxy, and corridor placement can look mechanical. It is reliable, but not especially subtle.
Random Walk (Drunkard’s Walk)
A simpler approach starts with a point and walks randomly, carving floor tiles as it goes.
Place a walker at the map centre. Each step, move in a random direction and mark the tile as floor. Repeat for N steps or until a target percentage of the map is open.
This usually gives you organic, cave-like layouts, and it is easy to implement. The downside is equally plain: there is no room structure, the paths can get narrow and snaking, and it is hard to steer the result towards a particular layout property without extra rules layered on top.
Cellular Automata
Inspired by Conway’s Game of Life, this method is often used for natural cave systems.
Start with random noise, with each tile having a ~45% chance of being a wall. Apply smoothing rules: a tile becomes a wall if most of its neighbours are walls, and vice versa. Repeat for 4-6 iterations.
The result is often the most natural-looking cave environment of the lot. The parameters are easy to tune, and the method scales cleanly. The catch is connectivity. It can produce disconnected regions, so post-processing is usually needed to join things up. It also does not suit structured room-and-corridor layouts very well.
Hybrid Approaches
The better results often come from combining methods rather than treating any one of them as the answer.
- Use BSP to define room positions and sizes.
- Use cellular automata to shape room interiors organically.
- Use A* pathfinding to carve interesting corridors between rooms.
- Apply post-processing rules for gameplay-critical features such as spawn points, item placement and exits.
That layered approach gives you the structural reliability of BSP and the visual naturalness of cellular automata. It is also easier to debug than a single clever system that does everything badly.
Terrain Generation for Side-Scrollers
Side-scrolling terrain works differently from top-down dungeon layout, because the player reads the space horizontally and feels every awkward jump.
Height Map Approaches
Generate a one-dimensional height map using Perlin noise or similar functions. The height at each X position determines the ground level.
Key considerations matter here more than the noise function itself. Layer multiple frequencies for natural-looking terrain, using low frequency for hills and high frequency for surface detail. Clamp maximum height differences between adjacent columns so you still get platformable gaps. Place platforms, ledges and gaps according to difficulty curves rather than pure randomness. Randomness on its own tends to make poor decisions in a hurry.
Chunk-Based Generation
Another approach is to pre-design small terrain chunks, usually 16-32 tiles wide, and assemble them procedurally. Each chunk needs defined entry and exit points and a difficulty rating.
The upside is practical: each chunk is hand-tested for playability, assembly is fast and reliable, and difficulty can be controlled precisely. The trade-off is that players eventually recognise the chunks, and variety takes work. You need enough chunks to stop the seams from becoming obvious, which means designing dozens of them if the game is going to last.
Procedural Item and Loot Generation
Procedural items - weapons, armour, power-ups - add variety without asking you to design every single item by hand.
The Template Approach
Define templates with variable properties:
Sword Template:
Base damage: 10–25
Speed: Fast / Medium / Slow
Element: None / Fire / Ice / Lightning (weighted random)
Modifier: +damage / +speed / +critical (0–2 modifiers)
Rarity: Common (60%) / Uncommon (25%) / Rare (12%) / Epic (3%)
The template keeps the design space bounded so every generated item still does something sensible. Random rolls inside that frame create the variation. Without that frame, the system drifts into junk pretty fast.
Balance Through Constraints
The main risk with procedural items is power creep and nonsense combinations. Constraints keep the generator from wandering off.
Budget systems give each item a power budget, so more damage means less speed. Rarity gating opens up more modifier slots at higher rarity, but not more base power. Synergy rules block or force certain modifier combinations so the item still hangs together as a coherent piece of gear.
As we discussed in our piece on data-driven game design, analytics can show when procedural generation starts producing outliers that players actually encounter rather than the ones you imagined in planning.
Seed-Based Generation
Deterministic seeds make procedural systems much more useful than they would otherwise be.
A seed lets players share a run number and play the same generated content. QA can reproduce exact layouts by recording the seed. Daily challenges can use the same seed for everyone, which creates a shared competitive setup. Streamers get something practical too: viewers can try the same seed they just watched.
Implementation comes down to one thing: use a seeded pseudorandom number generator (PRNG), not system random. Every procedural decision should draw from that seeded PRNG in a deterministic order.
The critical requirement is simple and unforgiving. The generation process must be fully deterministic. Any non-deterministic input - system time, floating-point inconsistencies, unordered data structures - will break seed reproducibility.
Handcrafted Structure, Procedural Fill
The strongest procedurally generated games do not rely on PCG alone.
Tutorial areas are usually hand-designed for clarity. Boss arenas are too gameplay-critical for procedural layout. Story moments need precise environmental control. The opening minutes should be curated, because first impressions are not the place to improvise.
Procedural content does better in the spaces between those anchors. Exploration areas get variety in traversal. Side content and optional paths reward curiosity. Enemy placement and composition can vary inside hand-tuned difficulty curves. Loot and item distribution stay unpredictable without taking control away from the designer.
As we explored in building dynamic NPCs with AI, the same rule applies there too: handcrafted rules set the structure, and randomisation fills in the variation inside it.
Testing Procedural Content at Scale
You cannot manually play every possible generation. You can still test the system properly.
Automated Validation
Write tests that generate thousands of levels and check that all rooms are reachable from the start, at least one valid path exists from start to exit, no areas exceed maximum difficulty bounds, item distribution meets statistical targets, and no hard-lock states exist.
Statistical Analysis
Generate 10,000 levels and analyse the distributions. Look at the average and standard deviation of room count, path length and enemy density, the frequency of specific feature combinations, and outliers that produce unusually easy or impossible layouts.
Focused Playtesting
Test extreme seeds as well - very high numbers, very low numbers, prime numbers and zero. Edge cases in the random distribution often turn into edge cases in gameplay. That is usually where the awkward bugs hide.
What We’d Do in Practice
For a 2D roguelite or procedurally-augmented game:
- Start with BSP or chunk-based generation - it is reliable and testable.
- Add organic flavour with cellular automata or noise-based detail.
- Hand-design all critical encounters - bosses, shops, story beats.
- Use seed-based generation from day one - the debugging benefits alone are worth it.
- Build automated validators early - they pay for themselves immediately.
- Tune through analytics - track what players actually experience, not what the generator theoretically produces.
The aim is not to generate everything procedurally. It is to generate the right things procedurally, so the limited handcraft time goes where it matters most.
Explore how game systems work in practice through the HGE documentation, or discuss PCG strategies in our forum.