Birdoggydog's Builds

Furnishing every kind of generated room in five themes

The dungeon generator now makes five dungeon kinds covering all 19 room kinds, an audit counts what stands in each, and the fantasy props are installed.

The dungeon generator used to make one kind of dungeon, a plant floor, so most of the 19 room kinds in the room table were never generated. It now makes five kinds, and all 19 come out of it, each furnished, lit and stocked. I also installed the fantasy props, so the fantasy dungeon in the tour is furnished in its own theme for the first time. I wanted props and monsters placed in every kind of room, and this is how far that got.

79 seconds through generated rooms, one of each kind. Each caption says the kind and what stands in it, like the canteen with 35 pieces. The chief’s suite frame is dark, and the vat hall is the clearest look at meat grown over the walls.

How do you get 19 room kinds out of one generator?

By giving it more mixes. The generator had a MIX table of room kind to weight. I added quarters, lab_wing, offices and cold_store, each with its own weights, room sizes and names, and a --kind option. A lab wing weights labs at 25, wards at 20, cells at 15 and security rooms at 10, with a few offices, stores, bathrooms and a vat hall. Between the five mixes every row of room_kinds.json gets used.

Two rooms in every dungeon are fixed: the far room, which was always a vat hall, and the room that holds the key. A ROLES table says what each becomes in another kind of dungeon. In quarters the far room is a canteen, and in offices it’s the director’s room. play_roles() renames the room everywhere its name is stored, including every link’s two ends, the start, the goal and any thing that mentions it. It draws no random numbers, so plant floors come out byte for byte as before. I checked that on seeds 1 to 6.

What does a generated room need besides walls?

Three things. First, furniture in the right theme. theme_for(plan) now picks a floor’s theme from its row in dressing.json, then from the dungeon’s own theme, then from the default, so a generated dungeon given a theme is furnished in it with no extra row. The vat hall also got a layout of its own: a console at the far wall, racks, a workbench, crates and trolleys, jars and terminals on the tops, and cameras. It only furnishes a room the content file names as a vat, so the hand-built vat chamber in the Breakout Site is left to its machines.

Second, light. A room’s light is a number from 0 to 1, the share of its lamps’ energy. A new function reads rooms.<x,y>.light from the content file for every dungeon and lets it win over the kind’s default. Third, meat. A population block now has a lay list of monsters, chests, traps, light and meat, and a generated dungeon asks for only light and meat because its packs and chests come from the sheet.

Kinds that were bare got pieces: shelves and a camera in bathrooms, cameras in cells, wards and the cutting room, a mattress and a bucket in the fitness room, baskets in offices and a canister in security rooms.

How do I know every room is furnished and walkable?

An audit test. tools/dungeon_fill.py writes 20 dungeons, five kinds with four shapes each: sunken with a rising stair, round, three floors, and plain. That’s 30 floors. The test counts, for every room kind in all five themes and both states, the furniture stood, strewn, on surfaces and on walls, plus packs, chests, traps, notes, lamps, dimmed rooms and meat. It also checks that no pack stands on a way between floors. Then a walker crosses every room of the three-floor dungeons, going around furniture. Each new kind has its own walk scene, and each takes about 5 minutes.

The walker found one thing. On the second floor of a cold store, the party couldn’t pass between a cutting room’s table and the wall, because the meat that room grows had lumped out into the gap. The dresser promises a way 0.8 m wide, measured to the wall’s face. For now the walker retries with 1.5 m, and I’ve filed the disagreement to fix properly.

How did the fantasy props get in?

I’d decided that only the props a place uses get installed. The tour’s fantasy dungeon, the Tallow Keep, is the first place that uses fantasy, so run.py install put in 302 variants, 2,416 files. The first install, on the main branch, made three tests fail, so I took it back out and had it redone in a worktree.

There the install gate wanted records for steps 16 to 18 of the pipeline, a test, a film and credits, marked on all 302. The tests needed two changes. The furniture_in_site test’s table of installed themes didn’t have fantasy, so every fantasy file read as idle. And the surface boxes in dressing.json that tell the dresser where clutter can sit on a prop had been written before the models existed. run.py surfaces rewrites them from the built models. The desk’s fantasy box was resized and moved forward by 0.177 m, so clutter lands on the trestle’s real top. The other themes’ boxes didn’t change. Step 19, my approval, stays mine, so they’re installed as trials like the other themes’ props.

29 seconds in the Tallow Keep. A kitchen of 11 pieces, a staging room of 20, then on floor 2 a storage room of 35 and a staging room of 19, with a vendor shown new and a shelf shown decayed.

The Tallow Keep now has 212 pieces on floor 1 and 229 on floor 2.

What’s still not done?

The generator’s own --content option writes none of the light, meat or theme, so dungeon_fill.py adds them, and lower floors still get the plain wall faces. A generated vat hall has props but no machines, because a machine only stands where a row names its floor and square. The meat theme’s surface boxes are stale, and I’ll refresh them once its props are installed.

How did the tests go?

The 20 fixtures and their walk scenes passed, 5 of 5, and the fantasy install’s 10 tests passed. The whole suite in the worktree ran 236 tests with 2 failures, an editor run that didn’t finish and one frame that took 760 ms. Neither looks related, but I haven’t re-run them on the main branch.