Procedural world, level and map generation for 2D/pixel games

Scope: algorithms at every scale (continent to tile detail) for deterministic, seeded generation in plain JavaScript on a phone. The target is small worlds, pixel tile grids, and one game on an isometric 2:1 grid: Elsewhere on Tycho, 320x180, with ctx.rng(name) / Tycho.seed.Rng / Tycho.seed.hashString already in js/shell.js. Researched 2026-11-02. Where a fetch failed or only secondary sources existed, it says so.

Noise-based terrain: noise, fBm, ridged noise, domain warping, biomes, multi-noise, erosion, rivers, coastlines, Red Blob polygon maps and mapgen4

Takeaway

For a small pixel world, the full terrain pipeline is cheap and well documented:

Minecraft-style multi-noise (nearest point in a 5-6 dimensional climate space) is the general form of the same lookup. Mapgen4-style Voronoi meshes help for hand-drawn-looking overworld maps, not for tile grids.

Cited Findings

Noise and fBm (Red Blob Games, “Making maps with noise functions”)

Shaping elevation

Biomes from elevation and moisture

Domain warping (Inigo Quilez)

Minecraft’s multi-noise biomes (since 1.18)

Hydraulic erosion (droplet method)

Dwarf Fortress world generation (simulation-flavored terrain)

Red Blob mapgen4 and the 2010 polygon maps

Inferences

Gaps

Constraint and rule-based generation: WFC, model synthesis, Townscaper/Bad North, constraint solvers, answer set programming

Takeaway

WFC is model synthesis (Merrell, 2007) reinvented for 2D bitmaps (Gumin, 2016). It runs in three steps: pick the lowest-entropy cell, collapse it weighted by frequency, propagate (AC-4).

On a phone, use WFC in small regions (building facades, a room’s furniture, a village block), not on whole worlds.

Cited Findings

WFC (Maxim Gumin, mxgmn/WaveFunctionCollapse)

Model synthesis and the constraint-solving view

Townscaper (Oskar Stålberg)

Inferences

Gaps

Dungeons and levels: BSP, rooms and corridors, CA caves, drunkard’s walk, Spelunky, Brogue, Isaac, Unexplored cycles, lock-and-key, Dead Cells, metroidvanias, pacing

Takeaway

The best-documented shipped generators are all hybrids: hand-made pieces placed by a simple, constrained structure.

Each step is small, deterministic, and easy to run in JS. The way to get “authored” structure is the graph-first approach (cycles, lock-and-key) followed by tiles.

Cited Findings

Spelunky

Brogue (Brian Walker). Community wiki flagged “needs verification”; numbers conflict slightly with another wiki.

  1. Profile: cave 33%, cross-room 100%, corridor 80%, doors 60%. Caps: 99 rooms, 30 loops. Rooms 4-20 x 3-7 — brogue.wiki, Level generation
  2. Accretion: up to 600 attempts. Each attempt builds a room (with a corridor 80% of the time) and slides it against a wall of the existing map until it fits. Each wall gets 15 tries; the last 225 attempts build rooms only — brogue.wiki
  3. Loops: up to 500 attempts or 30 loops. Open a wall into a doorway only if the floors on both sides are more than about 2 rooms apart by shortest path — brogue.wiki
  4. Lakes: 55% fill, then 5 iterations of B5678/S45678 CA. Keep the largest blob that fits, starting at 30x15 and shrinking to 20x10 over 10 lakes. Reject any lake that breaks passability. Each lake gets a shallow “wreath” — brogue.wiki
  5. Then: machines and treasure rooms (at depths 3, 7, 11…, each with a key holder), diagonal cleanup, bridges, orphan-door removal, and secret doors with chance (depth−1)×67/25 % — brogue.wiki; compare brogue.fandom.com

Cellular automata caves (RogueBasin)

Binding of Isaac

  1. 9x8 grid, start at cell 35. Room target = random(2) + 5 + level*2.6 — Boris the Brave, Dungeon Generation in Binding of Isaac (2020-09-12)
  2. BFS queue. Skip a neighbor if it is occupied, already has more than one filled neighbor, the target is reached, or a 50% roll fails. Cells that add nothing are dead ends — Boris the Brave
  3. Restart if the count is wrong or the boss would sit next to the start. The boss goes in the farthest dead end; special rooms go in other dead ends — Boris the Brave
  4. The secret room goes in an empty cell touching 3 or more rooms and no dead ends, with the criteria relaxed after 300 and again after 600 tries, so it always succeeds — Boris the Brave

Unexplored (Joris Dormans): cyclic generation

Dead Cells (Sébastien Bénard, Motion Twin; 2020-02-15, originally on Gamasutra)

  1. The island framework (biome connections, key locations) is handmade and fixed across seeds.
  2. Handmade room tiles are made for each biome and each purpose (combat, treasure, merchant), defined by their entrances and exits.
  3. Each biome has a concept graph: entrance and exit first, then special rooms, then combat and exploration tiles. The graph controls level length, how labyrinthine the level is, and the entrance-to-exit distance.
  4. The generator picks random rooms from the biome pool until each node’s requirements are met.
  5. Monster count comes from combat-tile length, for example one monster per 5 combat tiles. A dangerous monster costs about 10 tiles.
  6. Pacing follows dramatic peaks and breaks, borrowed from Left 4 Dead’s AI Director.

General references

Inferences

Gaps

Settlements and structures: Watabou, building and house generators, interiors, road networks, fields

Takeaway

Settlement generators in practice are geometric:

For a small pixel town on a tile grid, simpler versions work: a few roads by noise-weighted A* or a grown street tree, lots by recursive bisection, buildings by footprint rules, and interiors by WFC or template rules.

Cited Findings

Watabou’s generators

Roads and cities (Parish & Müller, 2001)

Caves of Qud’s split between fixed and generated places

Inferences

Gaps

History and simulation-driven worlds: Dwarf Fortress, Caves of Qud, Ultima Ratio Regum, Wildermyth; places with people

Takeaway

For Elsewhere, whose people are Tyrell minds, the transferable idea is Qud-style: a short generated backstory whose events point at concrete places and objects the player can find. Do not simulate centuries.

Cited Findings

Inferences

Gaps

Tile presentation: autotiling, Godot terrain sets, LDtk auto-layers, Tiled terrains, transitions, Poisson-disk decoration, chunks and per-chunk seeding

Takeaway

Store terrain on cell corners (a dual grid) and draw tiles chosen by the 4-bit corner mask (marching squares).

Decoration comes from Bridson Poisson-disk sampling (k=30, O(n)), with density from noise or biome. Chunked worlds seed each chunk as hash(worldSeed, cx, cy) so any chunk can be regenerated independently.

Cited Findings

Tileset classification (Boris the Brave)

Dual grid and quarter tiles

Engines and editors

Decoration scattering

Inferences

Gaps

Libraries and research in JS and PCG as of 2026: rot.js, simplex-noise, WFC ports, ndwfc, delaunator, PRNGs, books, procjam, the PCG workshop

Takeaway

Elsewhere installs nothing for the game, so the key libraries are short enough to vendor or reimplement in about 100 lines each:

The PCG book (Springer 2016) is free online. The PCG Workshop reached its 17th edition in 2026, and PROCJAM 2025 ran Nov 21 - Dec 1, 2025.

Cited Findings

simplex-noise.js

PRNGs

Other libraries

Research and community

Inferences

Gaps

Evaluation: making generated worlds feel authored (designer constraints, curated pieces, checked seeds, generate-and-test, expressive range)

Takeaway

Every shipped generator studied here gets its “authored” feel the same way:

Expressive range analysis (Smith & Whitehead) checks the generator as a whole. It plots many seeds on two metrics as a heatmap.

Cited Findings

Inferences

Gaps