Perception Rooms
Tutorial by Chris Hunt – nospam@cwhunt.com
in collaboration with Ron Broglio – ron.broglio@lcc.gatech.edu
1. Purpose
This tutorial shows MOO programmers how to create rooms that adjust their contents to the player and her circumstances.
We include two examples with our sample room: the first will change the background color to match the sky at the time of day—gray, yellow, and orange respectively; the second example will search all players’ inventories for notes, then display their contents in the room description.
2. Background
One of the most powerful—and effective—tools for creating an interactive MOO is an interactive room that responds to situations by changing its appearance. For example, users carrying different items (identification cards, identities, costumes, etc.) can see different items, exits, or descriptions
Creating these dynamic rooms is comparatively simple. It only requires one verb and no special privileges (other than owning the room). But writing this verb assumes a basic knowledge of HTML and some MOO programming.
3. Implementation
3.1 Creating a Sample Perception Room
We will begin by installing a sample dynamic room with some simple features. Then we will examine this room.
Open the object editor. Press ‘Create New Object’. Choose ‘generic room’ and name it ‘Perception Room’. Feel free to connect the room to another room in your space, although this is not necessary. After pressing ‘Create’, you screen should look like this:

Figure 3.1
Now open the program editor and select your new room for editing. Create a new verb; it must be called ‘_html’. Check the ‘read’, ‘execute’, and ‘debug’ permissions. Set the arguments to ‘this’, ‘none’, and ‘this’. The body of the verb should be the following code:
"** THIS SECTION FOR BACKGROUND COLOR CHANGING **";
"save the original color so it can be restored";
backupColor = this.web_bgcolor;
"extract the hour (in 24 hour format) to an integer";
hour = tonum(ctime()[12] + ctime()[13]);
if (hour < 7)
this.web_bgcolor = "Gray";
elseif (hour > 7 && hour < 18)
this.web_bgcolor = "Yellow";
elseif (hour > 18 && hour < 21)
this.web_bgcolor = "Orange";
else
this.web_bgcolor = "Gray";
endif
"** THIS SECTION FOR NOTE READING **";
header = "";
"get the items in the room";
for player in (this.contents)
"pick out just the players";
if (is_player(player))
"look through all the items in each player's inventory";
for n in (player.contents)
"pull out the notes";
if (parent(n) == $note)
"examine only the notes with content";
if (typeof(n.text) == STR)
header = header + " <table align=\"center\" width=300>";
header = header + "<tr><td>";
header = header + player.name + " is carrying a note!";
header = header + "<p>\"" + n.text + "\"";
header = header + "</td></tr></table>";
endif
endif
endfor
endif
endfor
footer = "";
"set a one second timer (fork) to restore the original color";
fork (1)
this.web_bgcolor = backupColor;
endfork
"prepend the header we've constructed to the standard content";
return {header, @pass(@args), footer};
"Code and tutorial by Chris Hunt -- nospam@cwhunt.com";
"Maintained and published by Dr. Ron Broglio, Georgia Tech";
" ron.broglio@lcc.gatech.edu";
Press ‘compile’. Now you screen should look something like this:

Figure 3.2
Create a new generic note in the objects editor (it is under ‘Basic Objects’). The new note will be added to your inventory. Enter some sample text and save it:

Figure 3.3
Visit the room—the background color should vaguely match the sky at your time of day and the note’s text should be in the room description. For example, your screen could look like this during the night:

Figure 3.4
3.2 Dynamic Properties
We chose our examples to demonstrate two primary methods of changing the appearance of a room. The first—dynamically adjusting the background color—works by temporarily changing a property of the object until the information has been sent to the player. Examine the following excerpts from the room’s code:
"** THIS SECTION FOR BACKGROUND COLOR CHANGING **";
"save the original color so it can be restored";
backupColor = this.web_bgcolor;
[...]
if (hour < 7)
this.web_bgcolor = "Gray";
[...]
"set a one second timer (fork) to restore the original color";
fork (1)
this.web_bgcolor = backupColor;
endfork
[...]
We are modifying a property of the current room called ‘web_bgcolor’. The list of properties is in the lower right hand side of the program editor. Here is the property list for our Perception Room.

Figure 3.5
Any properties can be modified on the fly. We simply change the background color, but you could also change the ‘entrances’ and ‘exits’ variables to show change the paths available to players when their situations change. You could also change the ‘description’ or the address of the audio content (‘audio_url’). As in our example, each of these properties has to be referenced with a ‘this’ followed by a period (e.g. ‘this.audio_url’).
You will only be changing these variables long enough to give the player a personally formatted page. Therefore, you must back-up the former contents of that property by storing it in a temporary variable. Restore this contents at the end of your ‘_html’ code. We use a timer—a ‘fork’—in our example, but some tasks may not need it.
3.3 Modifying a Room’s HTML Content
Our second example actually appends new content to the page’s HTML. Our example is intentionally complicated to illustrate much of the functionality you may want to include—a simpler example is included at the end.
"** THIS SECTION FOR NOTE READING **";
header = "";
"get the items in the room";
for player in (this.contents)
[...]
"look through all the items in each player's inventory";
for n in (player.contents)
[...]
"pull out the notes";
if (parent(n) == $note)
"examine only the notes with content";
if (typeof(n.text) == STR)
header = header + " <table align=\"center\" width=300>";
header = header + "<tr><td>";
header = header + player.name + " is carrying a note!";
header = header + "<p>\"" + n.text + "\"";
header = header + "</td></tr></table>";
[...]
footer = "";
"prepend the header we've constructed to the standard content";
return {header, @pass(@args), footer};
Note how we begun with an empty string variable (‘header’) and added more strings to it. Literal content—content to be written verbatim to the page—is enclosed in double quotes; interpreted content—variables like ‘n.text’ or ‘header’—is kept out of quotes and appended to the literals with a plus sign. Each line must end with a semi-colon, and double quotes within a literal (e.g. ‘align=\”center\”’) must be preceded with a forward slash—this prevents the quotes within the literal from being interpreted as the end.
(These details are easier than they may seem, just play with the text we have included and you will figure it out.)
Whatever content you add to the header or footer will be included at the beginning or end of the page. Make the content dynamic by including your string construction (‘header = header + ...’) within an ‘if’ statement.
As we have said, our example is intentionally complicated. A simpler ‘_html’ verb could simply greet the player at the top of the page:

Figure 3.6
"in this verb, args[1] is the variable for the player calling it";
header = "Hello " + args[1].name + "!";
return {header, @pass(@args)};
Our verb could even be further simplified:
return {"Hello " + args[1].name + "!", @pass(@args)};
If we wrote our new ‘_html’ for another room called ‘Greet Room’, it would look like this:

Figure 3.7