Roguelike: Cellular Automata
Smooth random noise into natural cave chambers using the cellular automata 4-5 rule — fill the grid, count neighbors, snapshot state, and iterate.
No login required.
Random Noise
Cellular automata starts with random noise -- each cell has a chance of being wall or floor. You'll fill the grid randomly, then learn to count neighboring walls.
Random initialization creates the raw material that smoothing will sculpt into natural-looking caves.
Loading game...
Click the game window to interact with it
What You'll Build
You will implement cellular automata to generate smooth cave chambers from random noise. First, each cell gets a coin flip — roughly 45% start as walls, the rest as floors. Then you run the 4-5 rule: count each cell's eight neighbors, and if five or more are walls, it becomes wall too. Walls cluster together and floors cluster together, so after four passes, random static sharpens into wide-open chambers connected by natural passages. The key programming challenge is double-buffering — you read from a snapshot while writing to the live grid, or neighbor counts get corrupted mid-pass. Unlike the drunkard's walk, cellular automata can leave disconnected chambers, so this algorithm pairs with flood fill in real projects.
How it works
- 1
Fill the grid with random noise
Each cell gets a random roll: if randf() is below the wall probability (0.45), it becomes a wall. The rest become floors. At this stage the grid looks like TV static — no structure at all.
- 2
Count each cell's neighbors
For every cell, count how many of its 8 surrounding cells (the Moore neighborhood) are walls. Use a nested loop from -1 to 1 on both axes, skipping the center cell. Out-of-bounds cells count as walls, which naturally creates solid borders.
- 3
Snapshot the grid before writing
Copy the entire grid state with duplicate(true) before applying rules. This is double-buffering — you read neighbor values from the frozen snapshot while writing changes to the live grid. Without this, changing one cell would corrupt the neighbor count of the next cell in the same pass.
- 4
Apply the 4-5 rule
If a cell has 5 or more wall neighbors, it becomes (or stays) a wall. Otherwise it becomes floor. This simple rule causes walls to cluster together and floors to cluster together — isolated walls get eaten, wall groups grow, and open chambers form.
- 5
Repeat for several passes
Run the snapshot-then-apply cycle 4-5 times. Each pass smooths further: small holes fill in, isolated walls vanish, and the boundary between wall clusters and floor chambers gets cleaner. After the final pass, random noise has become recognizable cave chambers.
- 6
Run flood fill to remove disconnected chambers
Cellular automata can leave isolated pockets of floor tiles that the player can't reach. Pick a starting floor tile, flood fill to find everything connected to it, then turn all unreachable floor tiles back into walls.
Learning Goals
- ✓Random grid initialization where each cell rolls against a probability threshold (randf() < 0.45)
- ✓Neighbor counting across all 8 directions using the Moore neighborhood (nested -1 to 1 loop)
- ✓Double-buffering with duplicate(true) — reading from a frozen snapshot while writing to the live grid
- ✓Running the automaton for a fixed number of smoothing passes to refine chamber shape
GDScript Concepts in This Part
Tips
- ✨Always read from a snapshot copy of the grid and write to the original — modifying cells in place while counting neighbors produces incorrect results. This is the most common bug.
- ✨Four to five iterations is usually enough. More passes over-smooth the map into a single blob; fewer passes leave too much noise.
- ✨The initial wall probability (0.45) controls the balance. Lower values create more open space with thin walls. Higher values create narrow tunnels through thick rock. Try 0.40 and 0.55 to see the difference.