From noise to a floor plan
WFC hands us a legal field of floor blobs. A real dungeon needs more: a clean outer wall, no marooned islands, and enough resolution to walk around in. Four small steps get us there.
Step 1 — Coarse WFC, with a border and seeds
We run the solver on a small coarse grid — think of each coarse cell as a future room-sized chunk. Two hard constraints are bolted on before solving:
- The outer ring is forced to void, so the dungeon always has a solid wall around it.
- A handful of interior cells are seeded as floor. These guarantee some open space and double as room nuclei for the next chapter.
Step 2 — Connect the islands
WFC can leave the floor in several disconnected blobs. We find the connected components, then repeatedly carve an L-shaped corridor between the two nearest cells of the biggest blob and the next, until everything is one walkable space. Carved cells are tagged as corridor, not room — that distinction matters later.
Step 3 — Upsample
Each coarse cell is blown up into a K×K block of fine cells. A 2× or 3× upsample
turns chunky blobs into rooms with room to move, while preserving the exact shape the solver
chose.
Step 4 — Derive the walls
Finally we run the marching-squares deriveMasks() from Chapter 1 over the fine
grid: every floor cell facing void grows a wall. The floor plan is done.
Step through the whole pipeline below — same seed, same code as the generator.
We now have a connected floor with a clean perimeter — but it’s still one big undivided space with corridors. Next we carve it into named rooms joined by doors: Rooms & Doors.