On the Construction of Mansions

So in my last post, I rhetorically asked when would be a better time to post game design thoughts than after working a twelve hour day on a weekend while feeling vaguely ill. Well, I have an answer for myself.

I’ve managed to get about two hours of sleep since then, as my brain just wouldn’t settle down to let me fall asleep (it was stuck in a little loop of trying to debug an issue that doesn’t actually exist; and no matter how much I told myself that the issue didn’t exist, my brain refused to stop obsessing over how to debug it). Plus, I’m quite definitely ill. So I’m trying to take it very easy for the next few days.

But even so, I’m also going to continue writing about procedurally generated murder mysteries (although it’d probably be better for all involved if I didn’t try to write any code right now). I want to start by stating that everything I’ve been writing thus far are guidelines; they’re intended as sign-posts and touchstones during the development of the game, which are returned to to help in making the hundreds of tiny decisions that need to be made during the construction of any game, in order to keep the game on track.

So with that caveat out of the way, I’d like to talk about my current thinking about how our randomly generated mansion will be generated.

The key thing that distinguishes the construction of a house or mansion from (for example) a network of caverns as seen in randomly generated games such as NetHack, is that its living areas are tightly packed together, with very little wasted space between rooms, so it’s important that our construction algorithm pack rooms very closely together.

As a starting point, we’ll assume that our mansion is a single story. Our mansion will be built on a grid; the precise dimensions of the grid don’t matter. There are two types of rooms that we can place on the grid. The first are regular “rooms”, which are a minimum of 3×3 in size, but may be anything up to about 5×6. The second type are “hallways”, which are always either two or three grid squares wide, and will be at least twice that in length (but can be longer than that).

When building the mansion, the first room placed is always at one of the edges of the grid, and is labelled as the Entrance Hall.

After placing the entrance hall, the mansion construction approach works this way: First, we search the grid for unused grid squares which border two used grid squares. If we find any, then we randomly select one of these to begin placing our next room or hall. If not, then we randomly select any unused grid square bordering one used grid square.

We then try to place a new room, starting from the selected grid square. If we can’t fit one (it’s conceivable that we could have a 2×2 dead space which can’t contain either a room or a hallway, for example), then we just select a new unused grid square and try again. Eventually we’ll reach the desired number of rooms, and will be able to stop.

This gives us our base floorplan. Once we have rooms and hallways placed, we start placing doors. The general rule of thumb is that every room that borders a hallway will get a doorway to the hall. Any room that touches another room has a 50% chance of having a door to that other room.

Once we’ve placed the doors, we’re almost done; just do one more pass over the map to make sure that every room is reachable from every other room (that is, that there are no little groups of rooms entirely cut off and inaccessible from the rest of the mansion) , and add extra doors as required until that condition is fulfilled.

Or at least, that’s my initial idea. I’m sure that once I eventually get around to implementing it, I’ll find problems with the approach. I’m particularly worried about whether in practice, the “select a random grid square that borders two used grid squares” heuristic will actually produce tightly packed floorplans the way that I hope it will, without moving to a more complicated and intelligent room selection mechanic.

I might actually have a go at implementing this, tonight. See whether I can get something working as a proof of concept, despite my fever. :)