Pseudo Rooms

by Ron Gilbert
Jan 05, 2016

Welcome to 2016. It sounds so futuristic. The other day and was joking around with Clayton and I said "Yeah, maybe in the year 2016!", just picking some random date that seemed like the far future, but ironically, it wasn't. As a kid who grew up in the 70's, the year 2000 was a future filled with marvels and space travel. It was the year we picked to say "a long time from now in a world we can't even imagine."

OK, in all honesty, I don't think I could have imagined the Internet, Twitter or the iPhone, so maybe it wasn't that far off. I write this on a computer that runs billions of times faster than what sent the astronauts to the moon and has so much memory that I will never run out.

Back as Lucasfilm, Chip Morningstar used to joke that the perfect computer would have an infinite amount of memory and an expansion slot for more.

For Thimbleweed Park, I have that. Maybe it is the year 2016 after all.

We've been blogging about the game for a year now. It's been a lot of fun, but also a lot of work. Writing one or two blog posts a week, plus recording and editing a podcast takes an amazing amount of time. Oh, and I have a game to make.

"Yeah, yeah, cry me a river Mr. Gilbert! Get on with the blog post!"

The engine has remained pretty stable for the past few months, mostly bug fixes and small features here and there. David, Jenn and I are finally getting to the point where we understand the engine enough that we can code in it without a constant fight.

Last week I added a new feature to the engine called Pseudo Rooms and I thought I'd spend our time together this week telling you about them. Grab a stool and relax while I spin a tale of mystery and deceit. A tale of adversity overcome and triumph of the good. A tale of... oh who am I kidding, it's a bunch of source code.

We used Pseudo Rooms in the SCUMM system to construct a group of rooms that were based on a single template.  We used them mostly for evil maze, but not always.

In Thimbleweed Park, the Edmund Hotel is 13 floors tall, which means 11 floors of rooms once you eliminate the penthouse, the lobby and the mezzanine (ThimbleCon ‘87).  Each of those 11 floors has 10 hotel rooms, so for the math impaired, that is 110 hotel rooms. We could have defined 110 hotel rooms in art and code, but that would be grueling and inflexible.

So once again, I dip back into the SCUMM pool and pull out Pseudo Rooms. Pseudo Rooms allow us to define one hotel room and then use it as a template to construct as many other rooms - all at run-time - that we need.

It's important that they are truly separate rooms so any state changes that happen in the room (turning on the TV, the bathroom sink, etc) are remembered for each room. We could write special code to track that in a single room, but that's a lot of extra work. It's much better if they are truly separate rooms. The other issue is Ray standing in room 307 and Ransome standing in room 610. If it was a single room, you'd see them both, but we need them in separate rooms without a lot of hoop-jumping.

Pseudo Rooms to the rescue.

You define a Pseudo Rooms using the (spoiler) command...

definePseudoRoom("HotelRoom101", HotelRoom)

This create a new room called HotelRoom101 based on HotelRoom. You can put an actor in it and treat it like any other room.

cameraInRoom(HotelRoom101)

The code to build the entire hotel is as follows...

const HOTEL_ROOMS_PER_FLOOR = 8

for (local floor_id = 3; floor_id <= 12; floor_id++) {
    local floor = definePseudoRoom("HotelHall"+floor_id, HotelHall)
    floor.floor_number = floor_id
    for (local room_id = 1; room_id <= HOTEL_ROOMS_PER_FLOOR; room_id++) {
        local room = definePseudoRoom("HotelRoom"+((floor_id*100)+room_id), HotelRoom)
        local door = floor["hotelHallDoor"+room_id]
        door.name <- "Room "+((floor_id*100)+room_id)
        door.hotel_room <- room
        door.verbWalkTo <- function()  {
            enterRoomFromDoor(hotel_room.hotelRoomHallDoor)
        }
        room.hotelRoomHallDoor.hotel_floor_door <- door
        room.initRoom()
    }
}

And the template room code is...

HotelRoom <-
{
    background = "HotelRoom"
    enter = function()
    {
        setMapLocation(CountyMap.mapHotel)
        if (objectState(this.hotelRoomRadio) == ON) {
            startthread(playRadio, this.hotelRoomRadio)
        }
    }

    exit = function()
    {
        stopSound(soundThereminLoop)
        stopSound(soundRadioMusicLoop)
    }

    initRoom() {
        // Change the color of the bed.
        objectState(this.hotelRoomBed, random(1,3))
       // TODO - Change other things.
    }

    hotelRoomHallDoor =
    {
        name = "door"
        flags = DOOR_BACK
        hotel_floor_door = null        // Door on hotel floor to come out of
        verbWalkTo = function()
        {
            enterRoomFromDoor(hotel_floor_door)
        }
    }

    hotelRoomPhone =
    {
        name = "telephone"
        verbLookAt = function()
        {
            Phone.receiverOff = FALSE
            Phone.whichPhone = this
            cameraInRoom(Phone)
        }
        verbUse = function()
        {
            Phone.receiverOff = TRUE
            Phone.whichPhone = this
            cameraInRoom(Phone)
        }
        verbPickUp = function()
        {
            verbUse()
        }
    }

    hotelRoomRadio =
    {
        name = "radio"
        initState = OFF
        verbLookAt = function()
        {
            if (objectState(this) == OFF) {
                sayLine("It's turned off.")
            } else {
                sayLine("It's turned on, and tuned to 198.7 FM")
            }
        }
        verbUse = function()
        {
            if (objectState(this) == OFF) {
                objectState(thisON)
                startthread(playRadio, this)
            } else {
                objectState(thisOFF)
                stopSound(soundThereminLoop)
                stopSound(soundRadioMusicLoop)
            }
        }
    }

    hotelRoomBed =
    {
        name = "bed"
        verbLookAt = function()
        {
            sayLine("It's a bed.")
        }
        verbUse = function()
        {
            sayLine("Not sleepy.")
        }
    }
}

We'll probably use them for evil mazes as well.

- Ron



Norman - Jan 05, 2016 at 15:59
Does this handle the common hotel room scenario where adjacent rooms are mirror images of each other? Any randomization of room colors, artwork on the walls, etc? In otherwise, you clone a room from a template that either has that programmed in or such that you can customize it in code after you have a room instance?

Ron Gilbert - Jan 05, 2016 at 16:04
Currently we're using only one hotel room template, but we could use more to do room mirroring, or maybe three basic hotel rooms. We will have lots of variations for each of the rooms by changing object states. You can see that in changing the color of the bed.

Lennart - Jan 05, 2016 at 16:02
I wouldn't mind a Zak style maze. I recently replayed Zak and I enjoyed the sphinx and maya mazes. Only the big Mars maze was a little too much.
Maybe it can be a bonus thing, like, not relevant for progress but unlocking a special ending...

Markus - Jan 05, 2016 at 16:04
Wow thanks for the code insight! It always amazes me to See how a game works behind the scenes.

How long did it take to have this template for the room up and running?

Ron Gilbert - Jan 05, 2016 at 16:05
It took me about a day to added the feature to the engine and code up the room.

Zarbulonian - Jan 05, 2016 at 17:07
Is it built on top of the Squirrel `setdelegate()`? It looks like a good use case...

Prototypal inheritance FTW!

Ron Gilbert - Jan 05, 2016 at 17:15
No, it just dups the template room's table. The code won't get duplicated due to ref counting. I like to keep things simple.

Zarbulonian - Jan 05, 2016 at 17:33
Infinite memory :-)

Paulup - Jan 05, 2016 at 19:10
I thought you were about to ask, "Is it built on top of the ancient Squirrel burial ground?" and I was already nodding and saying "good question" to myself.

Jon - Jan 05, 2016 at 16:05
The head bone's connected to the leg bone...

CaffeinePwrdAl - Jan 05, 2016 at 20:20
.. the leg bone's connected to the hip bone ...

[half way through song]

Guybrush: "Hmm, maybe I should write this down."

At that point I paused the game, then panicked to find a pen and remember the order of the bones they'd already sung up to that point - I figured this was a cruel joke by the developers!

I didn't notice that Guybrush had written it on the 'spit-encrusted-paper' until my second play through, I guess I'd figured there was no writing implement in his inventory to write with, and it didn't occur to me to check regardless!

Thing is, looking back, I love the game all the more for it :)

Ralph Egas - Jan 05, 2016 at 17:00
Hi Ron,

Please allow me to offer a code-refactoring suggestion:

How about adding local room_postfix = ((floor_id*100)+room_id)
and then using "HotelRoom"+room_postfix and "Room "+room_postfix

Stuff like that is gonna avoid major headaches during QA ;)

Cheers,
Ralph

Julian Young - Jan 05, 2016 at 17:01
Sounds like potentially brutal puzzles incoming!

Thanks for the code insight, I live for that insight of elegent simplicity :)

Arto - Jan 05, 2016 at 17:57
Not that brutal. I suspect there will be a tool to find the correct room in hotel, and there will be a blog post to gather suggestions for room numbers. There will be some 3000 hilarious suggestions for room numbers, like 503, 613, 617, 863, 1097, 1361 and 4787*. And of course 1138. Oh the laughter we'll have.

* Go on, Google these.

Derrick Reisdorf - Jan 05, 2016 at 19:15
I only think one of those room numbers will exist.  Unless you're from somewhere where they use wacky numbering systems, the room numbers would follow normal room numbering convention:
One digit for the floor, and two digits for the room.
So you would have room 300 or 301 to room 309 or 310 on the 3rd floor, and so on.  I don't think you'd see rooms ending with "11" or higher.

Derrick Reisdorf - Jan 05, 2016 at 19:26
...and looking at the code used to "build" the hotel, that's exactly how the rooms will be numbered.

Arto - Jan 05, 2016 at 19:32
Yes, well, did you Google those numbers?

(I hate to explain a joke)

Derrick Reisdorf - Jan 05, 2016 at 20:39
No, but what if Room 404 could not be found. That's certainly a joke you may not understand in 1987.

Derrick Reisdorf - Jan 05, 2016 at 20:40
...and a bad one at that.

Ron Gilbert - Jan 05, 2016 at 20:54
That's funny. It's going in the game now.

stderr - Jan 06, 2016 at 02:42
If you ever decide to have more than 10 rooms per floor, you'll need to skip room 418 too, since it isn't a room at all according to RFC 2324. :-)

Derrick Reisdorf - Jan 06, 2016 at 10:49
Hmmm...Any hidden rooms in the hotel?  Maybe 404 can be a hidden room.  It could be obvious, where there's empty wallspace between 403 and 405 (or between 402 and 406 if even-numbered rooms are on the same side of the hall); there's a hint of wallpaper patchwork (or whatever) where room 404 should be.  There would be a secret way to get into room 404 from either one of the adjacent rooms (or, perhaps the elevator shaft).

That's another thing, how are you planning to do the halls of the hotel?  I at first pictured a long hall, from left to right, where all the doors to the room will be along that one side of the hall.  That would surely be the easiest to do, but might seem a little weird within the game space and exterior design of the hotel.  I like the aesthetics of the exterior of the hotel; will the layout of the rooms change a bit to match the exterior?

I hope there's a housekeeper with cart who seems to always talk about weird ways to remove stains from things:
http://www.hospitalitynet.org/news/4026910.html

Weird that I found the first one on the National Center on Domestic and Sexual Violence, but these inspection checklists are kind of neat reference material:
http://www.ncdsv.org/images/HOTELINSPECTIONCHECKLIST.pdf
http://www.houstontx.gov/fire/business/hotelmotelinspectionguide.pdf

Plans:
http://www.simpsonsoverseasproperty.co.uk/downloads/Dickinson%20Hotel%20Floor%20Plan.jpg
https://upload.wikimedia.org/wikipedia/commons/8/87/Floor_plan_of_hotel_rooms..jpg

Steffen - Jan 06, 2016 at 04:45
I am wondering what to find in room 666?   ;-)

Lennart - Jan 05, 2016 at 17:01
Were the airports in Zak room templates too?

David Fox - Jan 09, 2016 at 12:52
Yes! All the airports in Zak were pseudo-rooms, as were all the mazes. For the airports, I had a few different planes I could turn on/off in the background, different terrain, different signs... But we used the same music for all, part of the joke about airports seeming to be all the same..

jck - Jan 05, 2016 at 17:19
so you're re-inventing class ?

Ron Gilbert - Jan 05, 2016 at 17:27
If it was only that simple.

Gaizka - Jan 05, 2016 at 17:19
Nice touch with the band the radio is tuned to ;-)

Mattias Cedervall - Jan 05, 2016 at 17:28
Ron, will there be a puzzle in Thimbleweed Park involving snow considering your love for skiing? It would be cool if you had one mysterious location a with a totally different climate.

I don't think I could have imagined the Internet either.

Big Red Button - Jan 05, 2016 at 17:34
It's amazing that every single room will seemingly be accessible!

Are you also going to vary the exterior view of the hotel depending on in which rooms the light is on?

I assume that several rooms will be occupied. I'm curious about if the agents are going to disturb some hotel guests.

Mattias Cedervall - Jan 05, 2016 at 18:16
You recommended the movie "It's a wonderful life" starring James Stewart. I've now seen it and I think it's a good movie.

Big Red Button - Jan 06, 2016 at 04:21
I'm pleased about that you like it! There are people who don't like such old movies at all, but I think some of those movies are still worth seeing, such as this one.

Alex - Jan 05, 2016 at 17:36
So when I first started reading this blog I thought "Dude... I can't wait until this game is finished and it's gonna feel sooo long...", so I imagined myself in 2016 thinking "Hah! I made it this long, now it's 2016 it won't be long now anymore!". But it's totally 2016 and not like that at all! I'm still like "I can't wait and it's gonna feel so long...".  Just so you know how much I look forward to playing it. :D

Christopher Griffin - Jan 05, 2016 at 17:50
So... I guess since all of the hotel rooms are generic, we don't need to explore them... XD

Lennart - Jan 05, 2016 at 18:03
There is nothing a steam archievement can't make you do :-)

Ron Gilbert - Jan 05, 2016 at 20:01
There is a single pixel object that randomly appears in one of the room that you have to find.

Derrick Reisdorf - Jan 05, 2016 at 20:26
Oh goody!  I CANNOT WAIT!!!

Derrick Reisdorf - Jan 05, 2016 at 20:34
Seriously.  That would be ridiculously hilarious.  A gumdrop or pill that is nearly the exact shade of the carpet.  Nothing integral to the game, just an Easter egg/achievement.  An homage to pixel-hunting.

Derrick Reisdorf - Jan 05, 2016 at 22:42
And you randomize the room it's in and its location in that room for each game instance. So, it won't be the same for everybody, making it a true pixel hunt.

longuist - Jan 06, 2016 at 08:11
Far too easy! Make it transparent please!

Big Red Button - Jan 07, 2016 at 16:14
Okay, but don't forget to add a Head of the Navigator, who is going to support us.

Julian Young - Jan 09, 2016 at 04:06
Delphine Software did that at a disturbingly high frequency. I remember spending a week looking for those little guys.

Steve - Jan 05, 2016 at 18:58
How much magic (code) is done in the method definePseudoRoom?

Ron Gilbert - Jan 05, 2016 at 20:00
1.97 crap-tons.

Derrick Reisdorf - Jan 05, 2016 at 19:55
So, are we setting HOTEL_ROOMS_PER_FLOOR to 8?  I thought you said 10?
Or are you including the Hotel Hall as one of those rooms?  Stairwell?

So, you could also use a loop to call all the DefinePsuedoRoom constructors, too..."HotelRoom"&floor_id*100+room_id?

Are you planning on putting something special in a random room?  I'm sorry if you mentioned this...but it's this hotel going to be mostly vacant?  Because of Thimblecon?  Wait.  Is this a convention of thimble collectors?

So many questions now for the next Q&A podcast.

Ron Gilbert - Jan 05, 2016 at 19:59
It's 8 becasue the hall wireframe art has 8 doors. When we do the final art, there will be 10 doors and we'll change the code.

Zombocast - Jan 05, 2016 at 20:05
I Love the old Hotel!
Just don't add random scarey stuff like twins on bikes, blood out of elevators, and little boys screaming Redrum!

Derrick Reisdorf - Jan 05, 2016 at 20:24
I find this code interesting:
local door = floor["hotelHallDoor"+room_id]

Is this essentially some kind of pointer?  We've already defined a local "floor".  Now we're assigning some derivative value of floor to door. When I see brackets I usually think arrays, but it's weird seeing a string value in there.

I'd also like to see the HotelHall constructor (or whatever you want to call it). You'll have 8 doors (9 including stairwell doors) and an elevator. How do you put the room numbers on the rooms?

Ron Gilbert - Jan 05, 2016 at 20:30
floor is a table, it's also the new room that was just created.

floor["foo"] is the same thing as floor.foo

There is no constructor for rooms.

Derrick Reisdorf - Jan 05, 2016 at 20:37
I knew it had to be some funky syntax thing.

Thanks, Ron!

Derrick Reisdorf - Jan 06, 2016 at 09:35
Yeah, I guess I mean HotelHall template.

drumsetz - Jan 06, 2016 at 16:31
I read that table as the kind you would find in the kitchen and got a little chuckle out of it. :)

Amb - Jan 05, 2016 at 20:46
So if you turn the lights off in some rooms, etc - can you go outside and see a pixel painting in the windows?  Because, if so, I'm writing an S on the left side of the building, and X on the right, and a giantic E on the main tower, and print screening straight to Reddit.

Ron Gilbert - Jan 05, 2016 at 21:24
I hadn't thought of making the outside lights reflect the state of the lights in the rooms.  We'll add that to the "if there is time" task list.

Jonny - Jan 05, 2016 at 23:11
That could be a puzzle. If you "write" banana, the banana truck will stop outside kind of thing.

Or just Easter eggs.

Malc - Jan 06, 2016 at 01:44
Achievement Unlocked : Made a rude image with the hotel lights

Christian - Jan 06, 2016 at 04:17
I would totally love this. I don't know how many player feel like me about this, but whenever I see developers take care of such "unimportant" (in an MBA kind of view) things and adding these little details, I enjoy them very much. If the light work, I think it will leave a very good feeling when one figures out that it works. It will make the world feel more real and immersive.

Also David was surprised in his elevator-post about how many people enjoyed the Zak bus logic. Too bad he stated that the elevator logic has been made simpler, but maybe it's for the best because if there is no puzzle where one has to switch while one is riding it to open some door etc., it might be a red herring.

Ema - Jan 10, 2016 at 07:01
These things are very nice, but distractive. It is important that the player has clear in mind what he's supposed to do: it is disappointing when you don't understand your objective, and it could be worse: what if, while you are trying to get it, you find a useless easter egg like this? It is funny if you immediately recognise it as what it is, but if you spend three days trying to understand "what to do with that darn light pattern" it is just frustrating

Mattias Cedervall - Jan 07, 2016 at 17:18
I hope you'll have time for it!

Lennart - Jan 07, 2016 at 17:42
That would be an awesome gimmick! I hope there is time.

Amb - Jan 06, 2016 at 12:33
Actually, if this happens, then im drawing a chainsaw and spending days trying to work out how to turn it on, including pouring gas on the ground around the hotel... That won't look suspicious at all...

Cattie - Jan 05, 2016 at 23:13
Will the fourth floor be skipped for the Chinese localization?

stderr - Jan 06, 2016 at 02:23
Like a true programmer, Rons code doesn't match his comments:

"Each of those 11 floors has 10 hotel rooms" vs. "const HOTEL_ROOMS_PER_FLOOR = 8".

:-)

Ron Gilbert - Jan 06, 2016 at 09:25
As I mentioned above, the wireframe art only had 8 doors, the final art will have 10.

Fref - Jan 06, 2016 at 03:45
Will the engine be open-sourced once the game gets out?

Zombocast - Jan 06, 2016 at 14:20
The source code will not be released unfortunealty. Ron has mentioned that recently in the last few blog post

Simon Simon - Jan 06, 2016 at 14:50
Just a note that this is adressed a little bit in the FAQ. (a clear no for the game code, but no clear answer for the engine code).

Roman - Jan 06, 2016 at 03:46
...and don't forget a lot of hotels skip floor 13...and room 13...

Steffen - Jan 06, 2016 at 07:02
Above the 6th floor the hotel is much smaller. Why/How does every floor has the same number of rooms? Is that another puzzle to solve??   ;-)

Uli Kusterer - Jan 17, 2016 at 01:26
It's bigger on the inside. ;-)

Zombocast - Jan 06, 2016 at 14:29
Oh god Ron, do you realize what you've created?
You've created the blueprints to the 1997 movie Cube.
Each room has a different way to die, and only by reading the markers can you tell if its safe, odd or even!
You have doomed us all!

Christopher Griffin - Jan 07, 2016 at 14:20
I thought the rooms were safe if the numbers were prime.  Although, they did originally speculate that even and odd had something to do with it.

spiffy - Jan 06, 2016 at 14:42
There will be theremin music in TP? Awesome!

Diego - Jan 06, 2016 at 14:51
Hi everyone! Greetings from Argentina....
There is something I´ve always wanted to know... what happened with SCUMM program files? Did George keep the originals? or it´s just lost?
Do you have images of how it was? any screenshot?

Happy 2016 Ron.... and keep going on! I´m learning a lot of things from your code.

EdoBvd - Jan 06, 2016 at 15:20
<%Pseudo-comment template%>
<%Humourous Cynicism%>
$ExplainHowAmazeYouAre
if ($Mood <= AVERAGE) {
$AddAnHintOfCritisism
}
<%End of Humourous Cynicism%>
<%End of Pseudo-comment template%>

Diego - Jan 06, 2016 at 15:59
Hey Ron.... what about localization? spanish, italian, french? do you need some help in translating the game?

Christopher Griffin - Jan 07, 2016 at 14:18
According to the FAQ (http://blog.thimbleweedpark.com/faq), the plans to translate include French, Spanish, Italian, and German.

Also, it has been said a few times that free help often doesn't work out, because without incentive there is no accountability (or maybe reliability is a better word).  To make sure that deadlines get met and that the project is a priority, it's better for all involved that they be paid for their time.  Of course, nobody was suggesting that free help CAN'T work.

Carlo Valenti - Jan 06, 2016 at 17:35
Wouldn't it be better to iterate new instances of pseudo-Winnicks, pseudo-Foxes, pseudo-Gilberts for developement; pseudo-dollars for cashflow; pseudo-playtesters for torture; and so on?

Think of the opportunities, Mr.Gilbert. Think.

RedPhantom - Jan 06, 2016 at 23:10
Were pseudo rooms used for the Nazi Castle in Indiana Jones and the Last Crusade?

Big Red Button - Jan 07, 2016 at 15:55
At least they seem to be used in The Secret of Monkey Island for the forest on Melee Island and for LeChuck's hideout. Both mazes were amazing, both technically and visually!

Grafekovic - Jan 08, 2016 at 01:39
The forest is always the same when you start a new game, so I doubt that it's generic. And for LeChuks hideout, I also think that it is designed. But maybe the lyrics with which you get through this maze change randomly with each new start of the game.

Big Red Button - Jan 09, 2016 at 06:03
You might be right: It's not what Ron called Pseudo Rooms. The connections between the rooms in both mazes varied, but the rooms themselves didn't change.

Grafekovic - Jan 08, 2016 at 01:34
I don't think so, since they all are indiviually designed and fullfill a purpose in solving a puzzle. None of them are generic.

David Fox - Jan 10, 2016 at 15:13
I don't remember using pseudo-rooms in Last Crusade... that doesn't mean we didn't, though. It's been a while...

Necrosis Thanatos - Jan 07, 2016 at 10:31
Off topic:  The February 2016 issue of MaximumPC magazine briefly mentions Thimbleweed Park as a game coming out in 2016.  It lists both the developer and the publisher as Gary Winnick.  Is that correct?  Not to stir the pot or anything....

Christopher Griffin - Jan 07, 2016 at 13:53
(Ron, in Desi Arnaz's voice, as if to Lucy): GAAAAAAAAAAAAAARY!

Dizarrow - Jan 08, 2016 at 14:04
You know, leave it to the die-hard nerds to pick apart such a great concept. Why don't you people just shut-up, and enjoy the game once it comes out. My God in heaven, get a life.

Necrosis Thanatos - Jan 12, 2016 at 10:13
Someone got out of bed on the wrong side this morning.

LEL - Jan 14, 2016 at 00:17
Actually, it sounds like they got out of the womb the wrong side.

Mister T - Jan 09, 2016 at 12:13
That is my nightmare version of Ingmar Bergman's The Silence: me as a kid lost in a hotel and chocolate mints on the pillows in every room. I mark my path by eating the mints, but soon I get lost because the maid replaces them and I end up hating them, but at the same time I have to eat them if I don't want to be lost forever.