Birdoggydog's Builds

Generating eight new room kinds and keys carried by bodies

The floor generator now draws caves, shrines, sumps and five other kinds of room, and hides some door keys on dead bodies you have to search.

The dungeon generator makes two new things on every floor it builds. Some door keys are now carried by a dead body in another room, which you search to get the key. And it can draw eight new kinds of room: machine, sump, cave, burrow, collapse, shrine, freezer and pipe gallery. Both are from the dungeon features plan I approved on 20 October.

How does a generated floor put a key on a body?

On a generated floor the door to the lift hall is locked. The key is on a dead body in another room, reached without going through that door. E opens the body’s container, the key is taken, and the door opens.

On 10 October I wrote: “A few should require keys from relevant bodies scattered around the level”. The Breakout Site had one body like that, built by hand. Now the generator does it on every floor it makes.

I didn’t add a new kind of thing to the sheet. The key thing gets a flag, body: true. The generator still puts the key in the room it was kept in, which the party can reach without going through that door or through a door whose key is behind it. The same walk check that keeps a loose key from ending up behind its own door covers a carried key.

The first key door of a floor always has a carried key, so every floor with a key door has at least one body. The others get one at a share of 0.5, which is a placeholder. The share is drawn from its own random generator, seeded from the floor’s seed, so every other part of every seed’s layout is drawn as it was:

BODY_SHARE = 0.5   # a placeholder

def carried_keys(params, n):
    rng = random.Random(int(params.get("seed", 0)) * 7919 + 511)
    return [i == 0 or rng.random() < BODY_SHARE for i in range(n)]

In the game, the pickup that already builds a key on a crate builds a dead body instead when the flag is set. The body is one of three stock figures, picked by the hash of the key’s id, wearing a shirt, trousers and a shoe, with the key in its contents. You search it like any dead body. When you close its container with nothing left on it the key counts as taken, and that’s what the save keeps, so a loaded body whose key was taken is empty again. The body’s name is just “Body” for now, and the words for it still have to be written.

The generator’s test runs seven seeds and checks every key can be reached with every locked door shut, and that every floor with a key door has a carried key. The game’s test searches the body on a generated floor, takes the key, and checks the door refuses without it and opens with it.

What do the eight new rooms look like?

A grid of eight first-person screenshots of dungeon rooms. Some are dark and purple with few objects, one has red organic growths on the ceiling, one has green benches, and one has workbenches and a control panel. Each has a caption with the room's name, how many pieces of furniture it has and its lamp level.

One room of each new kind. Top row: a cave and a burrow, then a shrine and a pipe gallery. Below: a sump and a freezer, then a machine room and a collapse.

The sheet shows the rooms are dressed with something, but many don’t look like what they are called yet. A cave and a pipe gallery are dark walls with a few crates and canisters. I only used props that already exist, so where a kind needs something that isn’t modeled, like an altar slab or stalagmites, I filed it on the work list and the room is dressed with the closest thing. A shrine has benches and an armchair.

Each kind is a row in a content file with the words on a sheet note that name it, the furniture rule it uses, and shares for monsters, chests, traps, light and meat. A sump gets the most monsters at 3.0 and a shrine the best loot. A sump’s floor is sunk and a pipe gallery’s is raised. A freezer is called that because cold_store is already the name of a kind of dungeon.

The generator draws them through weights per dungeon kind:

MIX["quarters"].update({"burrow": 8, "collapse": 5})
MIX["lab_wing"].update({"machine": 12, "pipe_gallery": 8, "freezer": 6, "sump": 8})
MIX["offices"].update({"shrine": 8, "collapse": 6})

The cold store dungeon draws all eight, with freezers the most at 18. The plant floor draws none, so its seeds come out as they did. Each kind has a size range in squares, four placeholder names, and some kinds it won’t sit beside: a shrine doesn’t sit next to a cutting room or a bathroom, and a cave doesn’t sit next to an office or a kitchen.

Anything the generator writes changes the game’s test fixtures, so the fill fixtures for the lab wing, offices, quarters and cold store were made again. After the body keys landed I made them once more, since both changes alter what the generator writes. The tour dungeons were generated before any of this and lay none of the new rooms, so the test tells me about that without failing. Rebuilding them is still on the work list.