The individual generators in compass (the arroyos and rivers, the caverns and meanders) are the fun part to show off, but they aren’t what makes the library usable. The part I’m actually proud of is the composition layer that sits on top, and it owes a lot to the runtime pipeline patterns I wrote about a while ago.
Shapes times features
Every room is described as a shape combined with a feature.
- There are 24 shapes: squares and circles, but also blobs, crystalline caverns, crescents, capsules, and a handful of hallway types.
- There are 18 features: pillars, islands, stepping stones, pools, moats, chasms, rubble, and four kinds of river.
Any shape can pair with any feature, which is 432 distinct room configurations before you’ve placed a single one. A feature is just two functions: an initialize step that works out the geometry (the meandering river feature, for example, generates a sine-wave centerline and expands around it), and a content step that decides the terrain type for each tile inside the shape. Keeping those two responsibilities separate is what lets the same river feature drop into a square room or an L-shaped hallway without caring which it landed in.
The scanning digger
Templates are the blueprints, and a single algorithm called the scanning digger reads them.
- Place a first room from the template, then process its exits through a priority queue.
- The queue’s ordering is the growth strategy: breadth (FIFO) sprawls evenly, depth (LIFO) tunnels, hub pulls toward the center, spoke pushes outward.
- Each exit gets a weighted-random room from the template’s pool, validated against a spatial index for collisions, then connected by knocking out the walls between floors.
- Post-processing facets run last: lakes, room interconnectors, erosion, and so on.
The template never names a specific generator. It says “give me a medium-to-large room, simple-to-moderate complexity” and lets the digger satisfy that. That’s the pipeline orchestrator idea again, where blueprints scale quickly while the actual machinery stays put. There are 75 templates today and they share one digger.

Prefabs that describe themselves
For the rooms I want to look hand-made, there’s a library of 1,163 prefab rooms. The trick to making that many usable is that nothing is tagged by hand. On load, each prefab is inspected and decorated with metadata: its size category, shape class, door configuration and density, whether it has water or special tiles, and rough complexity. A template can then ask for prefabs by filter rather than by name, and the digger rotates and mirrors them to fit the exit it’s connecting to.

The whole thing is the same lesson I keep relearning: the generators are interchangeable parts, and the value is in the boring layer that lets me recombine them without writing new code. A new dungeon style is usually just a new template, not a new algorithm.

