A low-poly 3D island with cliffs, water and scattered conifers

Personal

Island Generator

A procedural island built tile by tile with wave function collapse. No map is authored and no layout is stored: the entire input is a set of hand-modelled pieces and the rules about which may sit next to which.

RoleEverything
StackReact, Three.js,
WFC solver
Year2024
NoteIf you would like the detail, please get in touch
Context

Reading about an algorithm is not knowing it

I had read the wave function collapse write-ups and could have described the idea accurately at a whiteboard. Then I tried to implement it and found I understood the idea and none of the engineering, which is a gap that only appears when you build the thing.

The collapse step is easy. Propagation is not: when a cell settles, every neighbour's option set narrows, and theirs after that. Getting that to terminate, stay correct, and run fast enough to watch is the actual problem, and no description had made that clear.

How it works

Adjacency is the whole ruleset

The solver takes no map. Its entire input is a set of tiles and, for each, what is allowed on each of its edges. Everything the output looks like is emergent from those constraints.

That is what makes it worth building rather than reading about. The design surface is not the picture, it is the ruleset, and the relationship between the two is not obvious in either direction. Tightening one edge rule changes the character of the whole island, and wanting a particular look means reasoning backwards to the constraints that would produce it.

01Lowest entropy firstAlways collapse the most constrained cell. Pick randomly instead and the solver spends its time backtracking out of contradictions it walked into with its eyes open.
02Propagate, then stopA settled cell narrows its neighbours, and theirs. The queue has to drain to a fixed point before the next collapse.
03Backtrack cheaplyWhen a cell runs out of options, rewind to the last one that still had a choice. Most of the work is choosing where to look next.
What it taught me

Constraint propagation, everywhere after

The thing I did not expect is how often this shape turns up once you have built it once. A design system's token layers are a constraint propagation problem wearing different clothes: change a primitive, and the change has to reach every component that depends on it, exactly once, without cycling.

I recognised that faster at work for having written a solver first.