I’ve found discussions on random room names and one for random room descriptions in Inform 6, but is there any way to randomize rooms entirely? The idea here is that I want the player to be in something like a big spooky house, and whether the door that goes west from the foyer leads to the kitchen or the billiards room or whatever is randomly determined every time they play, but doesn’t change within a single game. And the kitchen always contains a knife you can pick up, regardless of whether it’s on the west or east side of the foyer in this iteration. Is this possible? Or am I just gonna have to pick a single configuration and live with it?
Were you looking for Inform 6 code? Because I know Inform 7 has an example “All Roads Lead to Mars” (Writing with Inform 6.14, example 78) where it places a new unvisited room any time the player tries to move in a direction where there isn’t a room.
Oh, snap, I forgot to specify Inform 7. My efforts at searching the documentation didn’t turn that example up. I don’t know if it’s quite what I’m looking for, though. This one controls the specific order that rooms appear even when random directions are taken. I want to have a specific layout of rooms, like, doors leading east and west and stairs leading up from the foyer, but then the exact room that’s east and west and up is randomized. Would something like All Roads Lead to Mars work for that, too?
Nah, you tagged it Inform 6/7, I just wanted to check because you mentioned 6.
Ah, so you have a fixed layout? You know what shape you want the house to be, you just want to swap (most of) the rooms around so random rooms are in random spots? That’s a bit more complicated and I don’t know Inform well. I’m sure I could come up with something, but there are people here who could probably give you a better answer.
I think this does what you’re trying to do.
First I define a bunch of real rooms. Then I define an equal number of room-variables:
"Random House" Conservatory is a room. Kitchen is a room. Closet is a room. Den is a room. Garage is a room. Room1 is a room that varies. Room2 is a room that varies. Room3 is a room that varies. Room4 is a room that varies. Room5 is a room that varies.
When I draw my map of the set layout of rooms, I’ll mark each room as “1” or “2” or whatever—These are the designations that will be constant in terms of how rooms are connected.
Next I distinguish “picked” rooms from “unpicked” rooms. “Picked” means that a room has been uniquely matched up with one of the room-variables.
When play begins, I start out by matching each real room to a room-variable and then marking it as “picked” (to ensure that the next step of the rule doesn’t pick the same room):
A room can be picked or unpicked. A room is usually unpicked. When play begins: now Room1 is a random unpicked room; now Room1 is picked; now Room2 is a random unpicked room; now Room2 is picked; now Room3 is a random unpicked room; now Room3 is picked; now Room4 is a random unpicked room; now Room4 is picked; now Room5 is a random unpicked room; now Room5 is picked; now Room2 is mapped east of Room1; now Room1 is mapped west of Room2; now Room3 is mapped east of Room2; now Room2 is mapped west of Room3; now Room4 is mapped east of Room3; now Room3 is mapped west of Room4; now Room5 is mapped east of Room4; now Room4 is mapped west of Room5.
After that, I set up the room connections. In this example, all I’m doing is making the rooms into a line, 1-2-3-4-5, but obviously you can set them up however you want. BUT, you have to do the apparently redundant work of saying 2 is east of 1 and 1 is west of 2. This is because each “Now ROOM is DIRECTION of ROOM” line only establishes a one-way connection!
Kind of a long when-play-begins rule, doing every single step by hand, right? There might be a more elegant, less tedious way of doing it. But I don’t know what it is!
Eh. I couldn’t resist trying. This works for me:
"Spooky House" The Foyer is a room. The Front Porch is a room. The Front Porch is south of the foyer. An unstable room is a kind of room. An unstable room can be chosen. The Kitchen is an unstable room. The Bedroom is an unstable room. The Parlor is an unstable room. The Billiards Rooms is an unstable room. The Bathroom is an unstable room. To place an unstable room (way - a direction) from (R - a room): Let S be a random unstable room which is not chosen; Now S is chosen; Change the way exit of R to S; Let reverse be the opposite of the way; Change the reverse exit of S to R. When play begins: Place an unstable room up from the foyer; Place an unstable room east from the foyer; Place an unstable room west from the foyer; Let E1 be the room east from the foyer; Place an unstable room east from E1; Place an unstable room east from the room up from the foyer.
Edit: Ha! Ryan beat me to it. At least I know I wasn’t way off base though.
This is the less tedious version I was talking about! I don’t think I’ve seen the “change the exit of…” syntax before. It looks like it has the same effect as “now this room is mapped this way from that room”?
I dunno. It was in the documentation (that All Roads Lead to Mars example I mentioned before). I didn’t realize you could say “mapped way from room”, so I have no idea if there’s any difference. The Bee Chambers example uses
now a random Bee Chamber is mapped north of place, so I suspect they’re both fine?
With Josh’s version in mind I’ve come up with a solution that is a little nicer than my original version in some ways—a little less nice in other ways—and WAY CUTER. Look at this:
"Random House" A room can be fake, unpicked, or picked. Conservatory is an unpicked room. Kitchen is an unpicked room. Closet is an unpicked room. Den is an unpicked room. Garage is an unpicked room. Room1 is a fake room. Room2 is a fake room. Room2 is north of Room1. Room3 is a fake room. Room3 is east of Room2. Room4 is a fake room. Room4 is east of Room1 and south of Room3. Room5 is a fake room. Room5 is north of Room3.
Here, “Room1” is not a variable, but a room—a room that won’t contain anything, and exists only as a “model” for one of the “real” rooms. With “Room1” et al, I’ve defined all the room connections I want for my house. This is a lot more convenient than my first attempt, because I get to write those connections in normal Inform 7 syntax.
Next, I’ll assign each “fake” room a “real” room—one of the “unpicked” rooms, which I change to “picked” when it gets picked, as before:
A room has a room called the instantiation. When play begins: Repeat with X running through fake rooms: let pickedroom be a random unpicked room; now the instantiation of X is pickedroom; now pickedroom is picked; repeat with Y running through fake rooms: let Yinst be the instantiation of Y; repeat with way running through directions: let M be the room way from Y; if M is a room: let Minst be the instantiation of M; change the way exit of Yinst to Minst;
The back half of this rule (“repeat with Y running through fake rooms”) looks at all the connections from each fake room and re-maps them onto the corresponding real room. It’s not necessary to add the “change the reverse exit of Minst to Yinst” part here, because you cover the other direction when you get to the other room!
For some reason, the “now Minst is mapped way from Yinst” syntax doesn’t work here, so I guess that’s one difference between that and “change the X exit…”
Having a “fake” version of each room is probably not ideal memory-efficiency-wise. But for a normal-sized game it should be no problem.
I tried Josh’s Spooky House and it worked, but I can’t figure out how to get a static room in a certain direction from a random one. Like, if the cellar is always down from the random room west of the foyer, for example. Trying “let W1 be the room west of the foyer; now the cellar is mapped down from E1” didn’t work. I tried Ryan’s second Random House instead, but the rooms don’t seem to instantiate properly. They’re still just “Room1” and “Room2” and stuff.
EDIT 1: Further experimentation has verified that I can place other random rooms a certain direction from a random room, just not static ones.
EDIT 2: Further further experimentation has revealed that adding a second room placement rule to cover static rooms is successful:
To relocate (R1 - a room) to (way - a direction) from (R2 - a room): Change the way exit of R2 to R1; Let reverse be the opposite of the way; Change the reverse exit of R1 to R2.
Thank you both for your help! Everything is working now!
EDIT 3: Oh. A new challenge has appeared. How do I describe which directions are valid exits?
There’s a couple different ways to do this, probably, but you can just check whether there’s any room (or door) in that direction. Here’s something I had from an old code sample:
Egress relates a room (called the place) to a direction (called the way) when the room-or-door the way from the place is not nothing. [Which will be true whenever you can go that way on the map. Putting doors in place randomly is pretty much impossible, but you could have a set pair of rooms with a door between them if you wrote appropriate routines for them.] The verb to open to (it opens to, they open to, it opened to, it is opened to, it is opening to) implies the egress relation. ["Open to" and its conjugations will be getting all the work in the source code.] After looking: say "You can go [list of directions opened to by the location]." [If we have procedurally generated exits, we'll need a procedural way of telling the player about them. If you had more detailed room descriptions you could fit something like this in the room description if you wanted, though it might be wise to include a default that did this if you hadn't written any other description of the exits.]
This is from a couple Inform versions ago but I think it should still work!
The whole thing might conceivably be of interest–it was for generating a random dungeon that made sense in a Euclidean way (so you couldn’t go north three times and wind up in the same place). But it seems like you’ve got a good handle on how to do your house room placement already!
I copy/pasted the code and it just worked immediately, no edits required. The best kind! Thank you very much!