!\------------------------------------------------------------------------------------------------------------------
SCAVENGER HUNT - Version 0.2
Copyright (c) 2000-2002 by Gilles Duchesne
Written using Hugo v3.0
This document is part of my "Scavenger Hunt" tutorial. It should be distributed as a package,
along the following:
SCAVHUNT1.HTM - Core & rooms
SCAVHUNT2.HTM - Scenery objects (THIS FILE)
SCAVHUNT3.HTM - Inventory objects
SCAVHUNT4.HTM - NPCs
SCAVHUNT5.HTM - Time & score
SCAVHUNT6.HTM - Misc info, credits & hints
SCAVHUNT7.HTM - Sounds & pictures
The package, as a whole, can be redistributed freely. However, I'd appreciate it if the issues &
mistakes would be reported to me rather than directly edited. Please contact me at lonecleric@bigfoot.com.
If you think parts of this code could be reused for your own purposes, feel free to do so.
------------------------------------------------------------------------------------------------------------------\!
!\DESIGN COMMENT:
At this point, you might be wondering if the incremental process used by the tutorial actually represents
"the one way" do create an adventure game. Well, certainly not! The tutorial was layered to make the learning
curve less steep, not to advocate one approach to game design.
With that said, I should say that I STRONGLY BELIEVE that, no matter how you choose to write your game,
you should strive to have a "working prototype" as soon as possible, as it's never too early to have a couple
testers look at your stuff. What do I mean by "working prototype"? That's your call. Some people prefer to
create a bunch of rooms first, then gradually implementing scenery & details. Others want to implement fully
equipped rooms, even if the map expands at a slower rate. What I really do care about is being able to have the
testers explore whatever you've been implementing so far. They should be able to fully interact with the new
room, or travel across the empty scenery, or carry on a decent conversation with the NPCs. You can't test too
early.
As a last suggestion, I'd like to point out J. Robinson Wheeler's web article titled "Make IF Fast!" and
available (as I write this) at:
http://www.phy.duke.edu/~sgranade/about2/adventuregames.about.com/library/design/uciffast1.htm
\!
#set DEBUG ! include HugoFix library and grammar
#set VERBSTUBS ! include verb stub routines
#set NO_AUX_MATH ! don't need advanced math routines
#switches -ls ! print statistics to SAMPLE.LST
#ifset DEBUG
#switches -d
#endif
!Here's my first attempt at creating my own verb commands. Those must be defined before the "normal" grammar
!is included, because grammars are always checked from top to bottom. So you're not really overwriting the regular
!grammar, you're overriding it.
!----------------------------------------------------------------------------
! NEW GRAMMAR:
!This first case is pretty straightforward:
!- If the player types "READ" alone, he gets the standard "Be a little more specific..." response.
!- If he tries to read an object which has the "readable" attribute (which was already defined by the Hugolib),
! the DoRead routine is called.
!- If he tries to read an object which doesn't have the attribute, or tries a more complex phrasing (like
! "READ BOOK WITH GUN"), he'll get a standard failure response from the Hugolib.
verb "read", "peruse"
* DoVague
* readable DoRead
!This second definition is significantly more complex. However, I didn't write it all myself. In fact, I went
!and ripped the original definition of "put" found in "verblib.g" to apply only a few modifications.
!So, why am I doing these? It's a funky issue I'll discuss in length in a short while. For now, you only need to
!know that I'm treating "PUT X ON Y" differently than "PUT X IN Y", which is why I'm calling my homemade DoPutOn
!routine.
! I pasted this one from verblib.g, then modified it to differenciate "on" and "in"
verb "put", "place"
* DoVague
* multiheld "on"/"onto" "ground"/"floor" DoPutonGround
* multiheld "outside" xobject DoPutonGround
* "down" multiheld DoDrop
* multiheld "down" DoDrop
* multiheld "in"/"into"/"inside" container DoPutIn
* multiheld "on"/"onto" platform DoPutOn
* multiheld DoDrop
!And another simple one. See, in a few occasions in the game I mention the idea of "giving up" on the bet.
!Therefore, I thought some players might try "GIVE UP" as an action, and I wanted to support that.
!Notice that, this time, I'm not restating the whole existing grammar from verblib. I only put my little
!catch here, and let the regular grammar handle the rest.
! Allowing 'give up' as an action
verb "give"
* "up" DoGiveUp
#include "verblib.g" ! normal verb grammar
!----------------------------------------------------------------------------
#include "hugolib.h" ! standard library routines
routine init
{
counter = -1 ! 1 turn before turn 0
STATUSTYPE = 1 ! score/turns
TEXTCOLOR = DEF_FOREGROUND
BGCOLOR = DEF_BACKGROUND
SL_TEXTCOLOR = DEF_SL_FOREGROUND
SL_BGCOLOR = DEF_SL_BACKGROUND
color TEXTCOLOR, BGCOLOR
INDENT_SIZE = 0 ! no indents whatsoever (doesn't fit my writing style)
prompt = ">"
DEFAULT_FONT = PROP_ON
Font(DEFAULT_FONT)
display.title_caption = "Scavenger Hunt"
cls
"Here you are, visiting your best friend in his new house in Cheapsville. His nice, new, empty, tediously
boring house in a charmingly boring suburban town.\nYour friend, who always liked games of all kind and
doesn't say no to the occasional bet, has decided to set up a challenge for you...\n"
"A scavenger hunt.\n"
"Here's the idea: he gives you three hours to go around the neighborhood, trying to find all the
miscellaneous things he's listed. You're supposed to bring all these items back to his house.\n"
"\n\n"
"\BScavenger Hunt\b"
"A Small Visit in Cheapsville"
"Version 0.2"
print BANNER
player = you
location = friendshome
old_location = location
move player to location ! initialize player location
FindLight(location) ! whether the player can see
DescribePlace(location) ! the appropriate description
location is visited
}
routine main
{
counter = counter + 1
PrintStatusLine
run location.each_turn
RunEvents
RunScripts
if speaking not in location ! in case the character being spoken
speaking = 0 ! to leaves
}
player_character you "you"
{}
!----------------------------------------------------------------------------
! CL_ROOM CLASS
! Used to add generic answers to "up" and "down"
!----------------------------------------------------------------------------
room cl_room
{
u_to
{
"Well, there aren't any stairs, elevators, or ladders, around, nor any wings on your back. You won't
be able to go up."
}
d_to
{
"You can't go much lower than this."
}
}
!----------------------------------------------------------------------------
! GENERAL SCENERY
! Objects that are used as scenery in several rooms
!----------------------------------------------------------------------------
!As defined in objlib.h, object deriving from the "scenery" class will have the "hidden" and "static" attributes.
!In addition, they'll be excluded from actions like TAKE ALL, making them, well, perfectly adequate scenery. :-)
!Be careful, though, there is more to that. There's code within HugoLib which actually checks if the current
!object derives from scenery. I'll write more on that below.
scenery streetlight "streetlight"
{
!The found_in property, perfect for scenery which spreads onto several locations, allows you to create one
!single object which can be accessed from everywhere you need it, rather than making a new object every time.
!From a more technical standpoint, the One True instance of the object will remain at the root of the object
!tree (so its parent is the nothing object), but it can be accessed from any of the mentioned locations.
found_in oakstreet, intersection, schoolyard, outsidelibrary, outsidebowling
!As you might guess, stuff like this will make the parser accept weird commands like
!"LOOK AT THE STREET LAMP STREETLIGHT"
!but as far as I'm concerned this is much better than preventing that player from typing "X LAMP POST".
nouns "light", "lamp", "post", "streetlight"
adjectives "street", "lamp"
article "a"
long_desc
{
"It's a typical urban street light. You might guess that it's in working order, but it's off now
against the morning sky. A bunch of other lights, just like this one, run along the street."
}
}
!This scenery object was created to allow the player to do stuff like "X HOUSE" and "GO IN HOUSE" from the outside.
!You might wonder why I'm putting the "your" word in the object's name rather than making it an "article"
!for that object. Well, keep in mind that the "The" routine will prepend "the" to any object which has an
!article of any kind. I just wasn't too tempted by statements like "You can't do that to the friend's house.".
scenery friendshouse "your friend's house"
{
found_in oakstreet, backyard
nouns "house", "building", "home"
adjectives "friend's", "friend"
long_desc
{
"It's a nice house. Not impressive. Just nice. It's as nice as all the other houses around. Thankfully,
you think to yourself, they don't all look identical, like in some of those newer suburbs."
}
door_to
{
!Here I wanted to allow "ENTER HOUSE", but I needed to properly manage the doors. This little trick translates
!any attempt to "enter the house" as "enter the front/back door", based on current location.
select location
case oakstreet
return frontdoor.door_to
case backyard
return backyarddoor.door_to
}
!Setting the parse rank to a larger value (well, larger than the default 0) gives this house a priority over
!the numerous other "house" objects which abound in the game (the neighbor's house, the doghouse...)
parse_rank 1
}
!Here's another quick trick. I want to support both "car" & "cars" as valid scenery. However, I want to map them
!to the appropriate pronoun ("it" vs "them"). So I put all the common info in a class from which both objects
!(singular & plural) will derive.
scenery cl_car
{
found_in oakstreet, intersection, schoolyard, outsidelibrary, outsidebowling
article "the"
before
{
!Any attempt to use the car(s) as a noun will fail here
object
{
"The cars are passing by too fast - just forget it."
}
xobject
{
"The cars are passing by too fast - just forget it."
}
}
}
cl_car car "car"
{
nouns "car"
}
cl_car cars "cars"
{
nouns "cars"
is plural
}
scenery grass "grass"
{
found_in backyard, park
nouns "grass"
article "the"
long_desc
{
"The grass seems greener here than back home. But then again, doesn't it always?"
}
}
scenery sky "sky"
{
found_in backyard, park, oakstreet, intersection, schoolyard, outsidelibrary, outsidebowling
nouns "sky"
article "the"
long_desc
{
"The sky is a plain, uniform grey."
}
}
scenery houses "houses"
{
found_in oakstreet, intersection, schoolyard, outsidelibrary, outsidebowling
nouns "houses", "house"
article "the"
long_desc
{
"There are several houses in the area. They are all sort of bland and nice. They're each
significantly different, which relieves the suburban boredom a great deal."
}
is plural
}
scenery street "street"
{
found_in oakstreet, intersection, schoolyard, outsidelibrary, outsidebowling
nouns "street", "road"
adjectives "main", "oak"
article "the"
long_desc
{
"It's a long ribbon of asphalt - nothing out of the ordinary."
}
}
!----------------------------------------------------------------------------
! FRIEND'S HOME
!----------------------------------------------------------------------------
cl_room friendshome "At your friend's house"
{
long_desc
{
"Your good friend had just begun moving into this fine, empty house. The main center of attention is
still the desk, which tells a lot about how much still has to be moved. That won't be until the
afternoon, however. Because of that, a puerile game of scavenger hunt seems like a good idea.
\nThe main door leads to the east, but there's also a back door to the north, leading to the neighbor's
backyard.
\nA work desk has been placed in one corner. The immediate area also has a closet."
}
!Since I'm now implementing doors, I want to make sure they'll be used. Any attempt to go in a direction
!restricted by a door will be interpreted as "going through that door".
n_to {return backyarddoor.door_to}
e_to {return frontdoor.door_to}
out_to {return frontdoor.door_to}
cant_go
{
"Unless you smashed a hole in the wall (which wouldn't be very considerate) you can't go that way."
}
}
scenery workdesk "work desk"
{
in friendshome
nouns "desk"
adjectives "work"
article "the"
long_desc
{
"The desk is quite familiar - your friend has had it for ages. It looks great, sitting there with its
single drawer, but you wouldn't want to watch it all day."
!Players will appreciate it if examining a container also provides a list of its contents.
Perform( &DoLookIn, self )
}
!And there you have it, in all its horror - an object which is both a container and a platform, even though
!the Hugo manual explicitely tells against it. Now why is that? Internally, the "container" and "platform"
!code is *one and the same*. In essence, the standard library doesn't make a lick of a difference between
!"LOOK AT DESK" and "LOOK IN DESK". But fear not, I have a plan...
is openable, open, container, platform
capacity 30 ! That's for the top of the table, not the inside
holding 0
before
{
object DoMove, DoPush
{
"The desk might be small, but it's heavy. Since you almost threw out your back putting it there in
the first place, you're no inclined to shove it around any more. Besides, it looks great where it
is, and your friend agrees."
}
object DoOpen, DoClose
{
!Now for my first trick, I'm redirecting any attempt to open the desk itself as an attempt to open
!the "drawer" object instead.
return Perform( verbroutine, drawer )
}
object DoLookIn
{
!This second trick is even sneakier. I explicitely check what the third word of the whole command is,
!and once again redirect the command to the drawer if needed.
!Is this such a good idea? Probably not. Am I likely to encounter unexpected issues? Perhaps. I chose
!to keep this code around just because I wanted to show it to you. Oh, and because I'm lazy. :-)
if word[2] = "in", "inside", "into"
return Perform( &DoLookIn, drawer )
else
return false ! Means "look on" - continue normally
}
!Remember what I went through at the beginning of the file, redefining the use of "put" to differenciate
!between DoPutIn and DoPutOn? Well, there you are. I made it so that I could trap only one case here.
xobject DoPutIn ! Overrides "put in", not "put on"
{
return Perform( &DoPutIn, object, drawer )
}
}
}
!Slightly weird, isn't it? Well, I guess I should mention Kent created a class called SuperContainer, which is
!precisely meant to create objects that support both "put in" and "put on". I chose not to use it because I
!didn't feel the need to. <Bootlicking Mode ON> But of course, it must be working great, since Kent himself
!wrote it! <Bootlicking Mode OFF> You should be able to find it among the other Hugo add-on libraries.
scenery drawer "desk drawer"
{
!Since putting the drawer *in* the desk would be interpreted as putting it *on* the desk, I decided to make
!them siblings rather than parent & child. The player won't see the difference, anyway.
in friendshome
nouns "drawer"
adjectives "desk"
article "the"
long_desc
{
"The drawer, like the desk which contains it, is rather small."
Perform( &DoLookIn, self )
}
is openable, not open, container
capacity 10
!In case you're wondering why I specify the initial "holding" value to be 0, it's because the property needs
!to be mentioned in order to have memory allocated to it. Should I not give it an initial value (0 in this
!case), I wouldn't be able to set it to something else later.
holding 0
}
scenery closet "small closet"
{
in friendshome
nouns "closet"
adjectives "small", "tiny"
article "the"
long_desc
{
!I'm changing the description based on the closet's current state.
"This tiny closet will look much better once it's repainted, you bet. For
the moment, it's ";
if self is open
{
"open."
Perform( &DoLookIn, self )
}
else
"closed."
}
!Oh, and for those paying attention, I didn't have to specify "not open", since attributes are always
!"off" by default. I just felt better writing it. Yes, I've had counseling. No, I don't do it anymore. ;-P
is openable, not open, container
capacity 100
holding 0
}
!In the first betatesting releases, one of my testers, whose anonymity I shall preserve (let's just say he won a
!2000 XYZZY for a game with a latin name) started nagging me because the closet door wasn't implemented. Because
!I didn't want to allow things like PUT BANANA IN CLOSET DOOR, I decided to make the door a separate new object,
!while making it strongly dependant of the actual closet. (See how I keep using the closet as a reference.)
scenery closetdoor "closet door"
{
in friendshome
nouns "door"
adjectives "closet"
article "the"
long_desc
{
"The door to this tiny closet will look much better once it's repainted, you bet. For
the moment, it's ";
if closet is open
"open."
else
"closed."
}
is openable
before
{
object DoOpen, DoClose
{
return Perform( verbroutine, closet )
}
}
}
!Likewise, since I often referred to the NPCs in my descriptions, I decided to add them right away, but as
!"cardboard cut-outs". For instance, since this implementation of the friend doesn't have the "living" attribute,
!any attempt to talk to him will give you a standard error message.
scenery npc_friend "your friend"
{
in friendshome
nouns "friend", "man", "guy", "person"
long_desc
{
"You've known him for ages. Through thick and thin, good and bad, you two always managed to keep
in touch, and to support one another in time of need. You also share a strong interest in games
and challenges of all kind.
\nNoticing you staring at him, he turns toward you. \"Is there a problem?\" he asks. \"Or maybe
you're giving up on our bet already?\""
}
is hidden
}
!----------------------------------------------------------------------------
! NEIGHBOR'S YARD
!----------------------------------------------------------------------------
cl_room backyard "Some neighbor's back yard"
{
long_desc
{
"This back yard doesn't actually belong to your friend, even if there's a door leading to it. It's
owned by some neighbor he hasn't even met yet. Both houses stand side by side, one to the north, the
other to the south.
\nYou notice a doghouse standing alongside one of the fences which surround most of the area."
}
s_to {return backyarddoor.door_to}
in_to {return backyarddoor.door_to}
se_to oakstreet
n_to
{
"And just how do you plan to introduce yourself?
\n\I\"Oh, hi there, I'm a friend of that new neighbor you haven't met, please don't mind me while I
rummage through your belongings!\"\i
\nUnlikely."
}
cant_go
{
"Several fences, which you hear make good neighbors, surround this area. The only passage through
them is to the southeast."
}
}
!This is my first use of the "door" class. As defined in the lib, doors are openable objects that can be referred
!to in two different locations (set with the "between" property). Entering the door from location will move the
!player to the other. Simple as that.
door backyarddoor "back yard door"
{
between friendshome, backyard
nouns "door"
adjectives "back", "yard"
article "the"
is hidden
}
scenery cl_fence
{
article "the"
long_desc
{
"Several fences, which you hear make good neighbors, surround this area. The only passage through
them is to the southeast."
}
}
cl_fence fence "fence"
{
in backyard
nouns "fence"
}
cl_fence fences "fences"
{
in backyard
nouns "fences"
is plural
}
scenery neighboryard "yard"
{
in backyard
nouns "yard"
article "the"
long_desc
{
"It's nice-looking, with neatly-trimmed grass everywhere."
}
}
scenery doghouse "dog house"
{
in backyard
nouns "house", "doghouse"
adjectives "dog", "red"
article "the"
long_desc
{
"The cute lil' dog house is painted bright red."
}
is container
before
{
!Any attempt to interact with the inside of the dog house will result in CERTAIN DEATH! MWA HA HA!!
!Well, not an actual death per se, but an unsastifying endgame for the player, which is almost the same.
!Back in the days, "instant deaths" were quite fashionable in adventure games. Nowadays, however, they
!are usually frowned upon. But hey, what the heck, Hugo has a undo feature.
object DoEnter, DoLookIn
{
return DogDeath
}
xobject DoPutIn
{
return DogDeath
}
}
}
scenery neighborhouse "neighbor's house"
{
in backyard
nouns "house", "home", "building"
adjectives "neighbor", "neighbor's"
article "the"
long_desc
{
"It's hard to judge the house from its back side, but it seems to be a well-maintained
home, of roughly the same size and value as your friend's."
}
door_to { return backyard.n_to }
}
!----------------------------------------------------------------------------
! STREET, NEAR HOUSE
!----------------------------------------------------------------------------
cl_room oakstreet "Oak Street, near the house"
{
long_desc
{
"You're now standing on the sidewalk of Oak Street. It's a quiet little street, much like every quiet
little street you've seen in Cheapsville. Cars pass every few minutes, thrusting dust into the
air. There's no one around; only a streetlight and a garbage bin are here to keep you company.
\nThe street leads north toward a city park, and south to an intersection. You friend's new house
stands to the west."
}
w_to {return frontdoor.door_to}
in_to {return frontdoor.door_to}
nw_to backyard
n_to park
s_to intersection
cant_go
{
"You don't see anything worthwhile in that direction, and your time is precious."
}
before
{
location DoSmell
{
"The only thing which gets your nose's attention is the slight stench coming from the
garbage bin."
}
}
}
door frontdoor "front door"
{
between friendshome, oakstreet
nouns "door"
adjectives "front", "house", "main"
article "the"
is hidden
}
scenery dust "dust"
{
in oakstreet
nouns "dust"
article "the"
long_desc
{
"You're not likely to win that bet it you lose your precious time analyzing every individual spec
of dust."
}
}
scenery garbagebin "garbage bin"
{
in oakstreet
nouns "bin", "can"
adjectives "garbage", "trash"
article "the"
long_desc
{
"This typical garbage bin has used for its intended purpose, judging by the smell. Although you expect
to find a cheerful message along the lines of \"PLEASE KEEP OUR TOWN CLEAN\" or \"W.A.S.T.E.\", there's
nothing like that written on it.
\nYou notice some miscellaneous trash inside the bin."
}
is container
capacity 30
holding 0
!Now kids, time to see if you've been paying attention. Remember at the beginning of this file, when I told
!you some parts of HugoLib will behave differently if your object derives from scenery? Here's an example
!right here. Normally, a container only lists its contents when the player looks inside it. Scenery containers,
!however, will list their contents along with the room description.
!
!"But how does the room description code know the container's deriving from scenery?", you might wonder.
!
!Simple. It cheats.
!The "type" property is defined in hugolib.h, and is used by the library to identify which class an object
!derives from, by setting its value to the object ID of the parent class. Therefore, type = "scenery" for
!scenery, "door" for doors, "vehicle" for vehicles, and so on.
!
!Now why did I just take the time to explain all this? I didn't want the garbage bin to list its contents,
!even though I want it to behave like scenery otherwise. So I derive from scenery, but reset the value of type.
type nothing
before
{
object DoSearch
{
Perform( &DoSearch, trash )
}
}
}
object trash "trash"
{
in garbagebin
nouns "trash", "garbage"
article "some"
long_desc
{
"A more-or-less homogenous heap of miscellaneous garbage. It \Icould\i hide something
worthwhile, but you're not sure you if really want to go see for yourself."
}
before
{
object DoSearch
{
"You reach inside the trash, but fail to find anything. One can safely assume that,
since this version of the game doesn't contain portable objects, there couldn't be
anything in there."
}
object DoGet
{
"You are \Unot\u going to carry that trash around."
}
}
}
!----------------------------------------------------------------------------
! CITY PARK
!----------------------------------------------------------------------------
cl_room park "Cheapsville City Park"
{
long_desc
{
"The soft grass of what seems to be the only city park in Cheapsville welcome you. It seems nice
enough, with trees, benches, and the usual elements of a park. However, since the weather today
isn't that great (the sky is completely grey), the only human being around seems to be that poor
sap operating the hot dog stand.
\nTo the south, Oak Street reminds you that suburban civilization is only a few steps away."
}
s_to oakstreet
cant_go
{
"A stroll in the park could be nice, but you still intend to win that little bet."
}
before
{
location DoSmell
{
"Hmmm... Hot dogs..."
}
}
}
scenery cl_tree
{
article "the"
long_desc
{
"Trees of various kinds abound in this city park."
}
}
cl_tree tree "tree"
{
in park
nouns "tree"
}
cl_tree trees "trees"
{
in park
nouns "trees"
is plural
}
scenery cl_bench
{
article "the"
long_desc
{
"You can see benches distributed evenly among the park."
}
is enterable
}
cl_bench bench "bench"
{
in park
nouns "bench"
}
cl_bench benches "benches"
{
in park
nouns "benches"
is plural
before
{
!Just making sure the player won't ever be sitting "on the benches".
object DoEnter
{
return Perform( &DoEnter, bench )
}
}
}
scenery stand "hot dog stand"
{
in park
nouns "stand"
adjectives "hot", "dog", "hotdog"
article "the"
long_desc
{
"Neat! A hot dog stand! It's a little early to have lunch, but the strong
smell of the freshly cooked dogs tickles your nose."
}
}
scenery npc_hotdogvendor "hot dog vendor"
{
in park
nouns "man", "guy", "person", "vendor", "clerk", "salesman", "sap"
adjectives "hot", "dog", "hot-dog", "hotdog", "poor"
article "the"
long_desc
{
"Despite his greasy apron, this middle-aged man seems like a nice fellow. He
keeps working behind his stand, apparently to make sure everything's ready
for the potential customers."
}
is hidden
}
!----------------------------------------------------------------------------
! INTERSECTION
!----------------------------------------------------------------------------
cl_room intersection "Intersection of Oak & Main"
{
long_desc
{
"Oak Street ends here, reaching Cheapsville's Main Street. Even though it's Monday,
the whole place remains pretty calm. You can see why your friend picked this town -
you can't get any quieter without living on a farm.
\nThe most interesting building in the area is the Cheapsville City Bank, which stands
proudly on the opposite side of Oak.
\nMain Street runs east-west. You can also go north, back on Oak Street."
}
n_to oakstreet
s_to { return bankdoor.door_to }
in_to { return bankdoor.door_to }
w_to schoolyard
e_to outsidelibrary
cant_go
{
"There doesn't seem to be anything interesting in that direction."
}
}
door bankdoor "bank door"
{
between intersection, citybank
nouns "door"
adjectives "bank"
article "the"
is hidden
}
scenery bankbuilding "bank"
{
in intersection
nouns "bank", "building"
adjective "city", "bank"
article "the"
long_desc
{
"A brick building, roughly cubic in shape, with the words \"CHEAPSVILLE CITY BANK\" proudly
painted on it."
}
door_to { return bankdoor.door_to }
}
!----------------------------------------------------------------------------
! BANK
!----------------------------------------------------------------------------
cl_room citybank "Cheapsville City Bank"
{
long_desc
{
"Whoa! It's been ages since you saw an actual city bank. And apparently, today isn't
your lucky day to see one: at this hour, they're closed. The windows are, anyway. And by the time
they open, your little wager will be long over.
\nOn one side of the open area is an ATM. On the other is the receptionist's desk, complete with
receptionist."
}
n_to { return bankdoor.door_to }
out_to { return bankdoor.door_to }
cant_go
{
"Most of the bank is closed at this hour, and therefore you can't go there."
}
}
scenery cl_bankwindow
{
adjectives "teller", "bank", "clerk"
article "the"
long_desc
{
"There are a few - it looks like three - windows down there, meant to accomodate curmudgeonly
customers who won't use the ATM. Of course, they're all closed right now."
}
}
cl_bankwindow bankwindow "window"
{
in citybank
nouns "window"
}
cl_bankwindow bankwindows "windows"
{
in citybank
nouns "windows"
is plural
}
scenery atm "ATM"
{
in citybank
nouns "atm", "machine"
adjectives "atm", "cash"
article "the"
long_desc
{
"It seems the city bank managed to buy an ATM from some bigger bank, and then reprogram it
for their own use. It seems operational, but is of no use to you, since you're not a client."
}
}
scenery bankdesk "receptionist's desk"
{
in citybank
nouns "desk"
adjectives "receptionist", "receptionist's"
article "the"
long_desc
{
"The desk is quite large, and on the side you're facing, featureless. The receptionist
sits behind it."
}
}
scenery npc_receptionist "bank receptionist"
{
in citybank
nouns "woman", "girl", "person", "receptionist", "secretary", "lady"
adjectives "bank"
article "the"
long_desc
{
"A comely woman, probably in her late twenties. She'd look like a high profile
businesswoman if her suit didn't look so rumpled, as if worn for a long, frantic period.
\nShe looks deeply involved in her paperwork, although she looks up to you from time to
time, to see if you actually want something from her."
}
is hidden
}
!----------------------------------------------------------------------------
! SCHOOLYARD
!----------------------------------------------------------------------------
cl_room schoolyard "School yard"
{
long_desc
{
"Oh look, an elementary school! Isn't that nice? It means your friend has picked quite a good
location to raise a family.
\nBunches of kids are playing and laughing all around the school yard. Either it's
recess, or they're having some special \"go play outside\" morning.
\nThe school stands to the south, while Main Street extends both eastward & westward."
}
e_to intersection
w_to
{
"You take a quick peek in that direction. There doesn't seem to be a lot of buildings,
for a while at least. It might be better to stick to this part of town instead."
}
s_to
{
"Going inside the school? Well, you're a little too old to pass as a kid, even if you are playing a
childish game, and you don't really want to scare anyone."
}
in_to { return s_to }
cant_go
{
"There doesn't seem to be anything interesting in that direction."
}
}
scenery yardschool "yard"
{
in schoolyard
nouns "yard", "asphalt"
article "the"
long_desc
{
"A vast open space, covered with asphalt."
}
}
scenery school "school"
{
in schoolyard
nouns "school", "building"
article "the"
long_desc
{
"This school is bigger than the houses in the immediate area, but fits nicely into the neighborhood. It
may very well be the only elementary school in the whole town. Apparently, it's called the \"My Dear
Watson Elementary\"."
}
door_to { return schoolyard.s_to }
}
scenery npc_schoolkids "school kids"
{
in schoolyard
nouns "kids", "children", "boys", "girls"
adjective "school", "young"
article "the"
long_desc
{
"Countless young children are running everywhere, playing, laughing, screaming, and doing
the kind of things normal kids do on recess."
}
is hidden, plural
}
!----------------------------------------------------------------------------
! STREET, OUTSIDE LIBRARY
!----------------------------------------------------------------------------
cl_room outsidelibrary "Main Street, Outside Public Library"
{
long_desc
{
"Main Street extends east and west from here. Aside from a few houses, the only building
in the area is the public library, which lies on the north side of the street."
}
w_to intersection
e_to outsidebowling
n_to { return librarydoor.door_to }
in_to { return librarydoor.door_to }
cant_go
{
"There doesn't seem to be anything interesting in that direction."
}
}
door librarydoor "library door"
{
between outsidelibrary, publiclibrary
nouns "door"
adjectives "library"
article "the"
is hidden
}
scenery library "public library"
{
in outsidelibrary
nouns "library", "building"
adjectives "public", "library"
article "the"
long_desc
{
"It's a smallish, unassuming building. You almost missed it, since it didn't look all that different
from the other houses."
}
door_to { return librarydoor.door_to }
}
!----------------------------------------------------------------------------
! PUBLIC LIBRARY
!----------------------------------------------------------------------------
cl_room publiclibrary "Public Library"
{
long_desc
{
"This isn't the largest library you've seen, of course. But it seems well furnished enough:
novels, kids' books, biographies, dictionaries, encyclopedias, and other sorts of library materials.
\nThe door leading outside is to the south. Near it is the librarian, sitting at her desk."
}
s_to { return librarydoor.door_to }
out_to { return librarydoor.door_to }
cant_go
{
"There isn't a way out in that direction."
}
before
{
location DoSmell
{
"The sweet aroma of old paper fills the building."
}
}
}
scenery cl_book
{
adjectives "kids", "kids'"
article "the"
long_desc
{
"Lots of books of all types, on many different subjects. You'd love to look around in search of some rare
gem you haven't read, but this obviously isn't the right moment."
}
is readable, openable
before
{
object DoGet
{
"You don't have a need for any of these right now."
}
object DoRead, DoOpen
{
"Why yes, of \Ucourse\u! Read a few books. Heck, why not read \Uall\u of them! After all,
it's not like there was this bet we intended to win. We're not in a big hurry or anything,
\Uright\u?"
}
}
}
cl_book book "book"
{
in publiclibrary
nouns "book", "novel", "biography"
}
cl_book books "books"
{
in publiclibrary
nouns "books", "novels", "biographies"
is plural
}
scenery cl_dictionary
{
article "the"
long_desc
{
"Several dictionaries of all kind."
}
is readable, openable
before
{
object DoGet
{
"You don't have a need for any of these right now."
}
object DoRead, DoOpen
{
"Why yes, of \Ucourse\u! Read a few books. Heck, why not read \Uall\u of them! After all,
it's not like there was this bet we intended to win. We're not in a big hurry or anything,
\Uright\u?"
}
}
}
cl_dictionary dictionary "dictionary"
{
in publiclibrary
nouns "dictionary"
adjectives "other", "one"
}
cl_dictionary dictionaries "dictionaries"
{
in publiclibrary
nouns "dictionaries"
adjectives "numerous"
is plural
}
scenery cl_encyclopedia
{
article "the"
long_desc
{
"Lots of reference books, on every subject you can think of."
}
is readable, openable
before
{
object DoGet
{
"You don't have a need for any of these right now."
}
object DoRead, DoOpen
{
"Why yes, of \Ucourse\u! Read a few books. Heck, why not read \Uall\u of them! After all,
it's not like there was this bet we intended to win. We're not in a big hurry or anything,
\Uright\u?"
}
}
}
cl_encyclopedia encyclopedia "encyclopedia"
{
in publiclibrary
nouns "encyclopedia"
}
cl_encyclopedia encyclopedias "encyclopedias"
{
in publiclibrary
nouns "encyclopedias"
is plural
}
scenery librariandesk "librarian's desk"
{
in publiclibrary
nouns "desk"
adjectives "librarian", "librarian's", "library"
article "the"
long_desc
{
"An old wooden desk, worn by the years. It's currently occupied by the librarian herself."
}
}
scenery npc_librarian "librarian"
{
in publiclibrary
nouns "woman", "lady", "librarian", "clerk"
adjective "library", "librarian"
article "the"
long_desc
{
"Although she's probably in her mid-thirties, this librarian looks slightly older at first glance,
due to her \I(very)\i sharp dress, her \I(nice)\i horned-rimmed glasses, and her \I(long)\i brown hair up
tightly in a bun. When you look at her more closely, however, you can see a flash of youth in her
\I(gorgeous)\i blue eyes. Apparently, she just likes to dress based on the Ultimate Librarian
Archetype. Well, you're not the one who'll complain. No sir-ree... In fact, right now you're trying to
sneak a peek of her \I(long)\i legs lying \I(elegantly)\i along the desk. You can't help but wonder if
she circulates."
}
is hidden
}
!----------------------------------------------------------------------------
! STREET, OUTSIDE BOWLING ALLEY
!----------------------------------------------------------------------------
cl_room outsidebowling "Main Street, Outside Bowling Alley"
{
long_desc
{
"Ah, finally! After all the niceness and cozyness of this little town, you've found a clear sign
of modern corruption: the bowling alley. And it's already open, lucky you! The entrance
stands to your south. You can also escape this place by following Main Street."
}
s_to { return bowlingdoor.door_to }
in_to { return bowlingdoor.door_to }
w_to outsidelibrary
e_to
{
"You take a quick peek in that direction. There doesn't seem to be a lot of buildings,
for a while at least. It might be better to stick to this part of town instead."
}
cant_go
{
"There doesn't seem to be anything interesting in that direction."
}
}
door bowlingdoor "bowling alley door"
{
between outsidebowling, bowlingalley
nouns "door"
adjectives "bowling", "alley"
article "the"
is hidden
}
scenery bowlingbuilding "bowling alley"
{
in outsidebowling
nouns "bowling", "alley", "building"
adjectives "bowling"
article "the"
long_desc
{
"Although you're no fan of bowling alleys, at least you must commend this one for not using one
of those tacky animated neon signs you hate so much. Then again, maybe they just lacked the
budget."
}
door_to { return bowlingdoor.door_to }
}
!----------------------------------------------------------------------------
! BOWLING ALLEY
!----------------------------------------------------------------------------
cl_room bowlingalley "Bowling Alley"
{
long_desc
{
"This place might be open, but it's fairly empty at this time of the day. A few enthusiastic
bowlers are practicing for their next tournament, and that's about it.\n
Your sharp eyes do notice something interesting, though: a door marked \"STORAGE - EMPLOYEES
ONLY\"";
if storagedoor is open
", slightly ajar."
else
"."
}
n_to { return bowlingdoor.door_to }
out_to { return bowlingdoor.door_to }
in_to { return storagedoor.door_to }
cant_go
{
"There isn't a way out in that direction."
}
}
door storagedoor "storage room door"
{
between storageroom, bowlingalley
nouns "door"
adjectives "storage", "room", "employees"
article "the"
is hidden
}
!Here's a case of "miscellaneous scenery". I just wanted the game to recognize whatever the player could think
!of, while not implementing all of them separately.
scenery bowlingstuff "bowling equipment"
{
in bowlingalley
nouns "equipment", "lanes", "lane", "pins", "pin"
adjective "bowling"
article "the"
long_desc
{
"Typical bowling equipment. Nothing worth spending your time on."
}
}
scenery npc_bowlers "bowlers"
{
in bowlingalley
nouns "bowlers", "players", "bowler", "men"
adjective "bowling"
article "the"
long_desc
{
"You can see, all around the place, several bowlers practicing in different alleys. Most
of them seem to be over 40, which seems... apropriate."
}
is hidden, plural
}
!----------------------------------------------------------------------------
! STORAGE ROOM
!----------------------------------------------------------------------------
cl_room storageroom "Storage Room"
{
long_desc
{
"This storage room would be spacy, if it wasn't completely filled with boxes and boxes
of now-useless stuff. Only a few narrows paths allow you to walk across the room.\n
Something in the corner of the room catches your eye almost immediately: an old IBM XT,
sitting in all its glory on a dusty table."
}
out_to { return storagedoor.door_to }
cant_go
{
"The room isn't \Uthat\u big. If you want to exit, just say so."
}
}
scenery cl_box
{
article "the"
long_desc
{
"Those boxes might be filled with interesting stuff, but 1) they're tightly packed, and
2) they're not yours."
}
is openable, not open
before
{
object DoOpen
{
"Those boxes might be filled with interesting stuff, but 1) they're tightly packed, and
2) they're not yours."
}
}
}
cl_box box "box"
{
in storageroom
nouns "box", "stuff"
}
cl_box boxes "boxes"
{
in storageroom
nouns "boxes"
is plural
}
scenery computertable "table"
{
in storageroom
nouns "table"
adjectives "computer", "old", "dusty"
article "the"
long_desc
{
"It's an old dusty table whose sole purpose is now to support a (possibly older) computer."
}
}
scenery computer "IBM XT"
{
in storageroom
nouns "computer", "ibm", "xt", "beast", "pc"
adjectives "ibm", "xt", "old"
article "the"
long_desc
{
"It's been quite a while since you saw once. Well, since the last flea market you've been
to. A true antique.\n
Your keen eye is drawn to the 5 1/4\" floppy drive right in the middle of the beast."
}
is container, switchable, openable, open
before
{
object DoGet, DoMove
{
"No way! Those old computers were \Umassive\u!"
}
object DoSwitchOn
{
"Sorry pal, it looks toast."
}
object DoOpen, DoClose, DoLookIn
{
return Perform( verbroutine, floppydrive )
}
object DoPutIn
{
!Here I'm invoking the "put object in drive" behavior, even though that behavior only returns an error
!message. You might have noticed I do that often - invoking other code rather than printing text.
!I believe it's a safer way to proceed given that some of those behaviors might change along the way.
!What if I rewrote the "put X in drive" behavior but forgot to change this one here?
return Perform( &DoPutIn, object, floppydrive )
}
}
}
!I put the drive object in the computer object because... I could, and it made some sense on a conceptual level.
!I don't think it would make a difference to leave it inside the room instead.
scenery floppydrive "floppy drive"
{
in computer
nouns "drive", "lid"
adjectives "disk", "floppy", "drive"
article "the"
long_desc
{
"This storage unit - the only one this computer has, actually - is in front of the computer, the lid ";
if self is open
"open."
else
"closed."
}
is openable, not open, container
before
{
object DoPutIn
{
"There's no need to put anything in that drive."
}
}
}
!----------------------------------------------------------------------------
! NEW VERB ROUTINES
!----------------------------------------------------------------------------
!I implemented each readable object by putting a "before DoRead" statement inside them. Therefore, this verb
!routine shouldn't actually ever be called. (Only object with the "read" attribute can be succesfully used with
!the verb "read", as stated in the grammar.)
routine DoRead
{
! There is no 'default response' - Reading is handled by each readable object
return true
}
!This code is the final step in my intricate ploy to have a desk which is both a container and a platform.
!Back up, in the grammar description, I took great lengths to differenciate "put X in Y" from "put X on Y".
!But here, I just make the "put on" behavior reuse the "put in" code! Am I crazy? Well, yes, but that's not the
!point. The big difference is that this allows me to intercept DoPutIn with a "before" statement, while letting
!DoPutOn process as usual. (If you can't picture that whole idea properly, go back to check the grammar entries,
!and then the workdesk object definition.)
routine DoPutOn
{
! Because containers & platforms share the same core code, we can reuse DoPutIn
return DoPutIn
}
routine DoGiveUp
{
"And mow your friend's lawn for the whole summer? NEVER!"
}
!This is a general routine to handle the "mauled by a dog" endgame scenario.
routine DogDeath
{
"\n\n\nYou'll never be quite to remember the exact events that followed. You were told later on that
there was some crazed pitbull sleeping quietly in the doghouse. You startled him, so he decided to rip
one of your hands off. It didn't turn out to be a big deal -- the microsurgeon who was on call at
Cheapsville General Hospital was able to reattach it easily, and your friend managed, with the help of his
neighbor, to get the hand back before it had been gnawed on too severely. So much for the quiet \"small
town\" feeling. Well, it might not be as bad as losing a limb, but...
\n\n\B*** You have lost your bet ***\b"
!Setting the global variable endflag to something other than 0 tells the main loop that the game should end.
!By setting it to 3, I specify I don't want to get one of the standard endgame messages ("You have died" and
!"You have won"), since I already made my own.
endflag = 3
}