How to Write a SAGML Adventure Game

by SagmlJohn

About 30 years ago, I played a computer game called Adventure. At that time, standard large and mini computers were not long out of the punched card and green-bar printout stage. Micro computers were just becoming a serious tool for businesses. That is when a very cool program was being distributed among the micro users. It was somewhat like a computerized Dungeons and Dragons interactive maze. Of course, it described the maze in text and read conversation-like input from the player. Most of the action that took place was going various compass directions, along with up and down, and exploring "rooms" in a cave. Room descriptions were written as concisely as possible to conserve space (an actual issue back then) and, mainly, because they knew players didn't like to spend a whole lot of time reading.

We only knew of it as "Adventure". It was long afterwards that I discovered that the official name is Colossal Cave Adventure. The history of this game (and other text-based games) and much, much more are covered at http://www.rickadams.org/adventure. This game is upgraded to be able to run on current Windows DOS command mode and, of course, Linux. The sources for all of these versions (even the original FORTRAN!) are also available.

Ever since I played it, I wanted to write a similar game. The bulk of the work (and the fun part) would be in the storyboard. Writing a game about navigating a bunch of rooms is extremely simple. The hard part was deciding which of the myriad of ways to use to create the game. Adventure was written in FORTRAN. The tools that became available to me became more and more plentiful.

We have come a long way with "standard" patterns, "standard" data modeling, and "standard" interfaces. In fact there have been wars of standards for quite some time. XML has very few rules in itself but it can be a vehicle for anyone to invent a very complex data model. Now the question of how this data is controlled: If it was an array of raw data, the controlling software would have to be application dependent. But, since the data can be complexly modeled via XML, the controlling program can be so generic that it can act like a language interpreter and the XML can be, as its name states, a language.

With it, you describe locations in a cave, a house, a maze, ancient ruins, --anywhere in the world or out of this world. No matter what that actual location, we will call each point a "room". There are objects that can be in a room. Objects are picked up, carried around, and dropped elsewhere. They can be manipulated, used to interact with other objects, and even hide other objects. Here is an example: The user of your game has wandered his character into a room that has a vanity with a locked drawer. The character tries to open the drawer to no avail. He needs a key that is somewhere else in the house (or virtual universe). With the key, he opens it and sees a golden ring inside. He can take it or leave it - his choice. Readers familiar with programming may be able to see the complexity of that interaction. It is tricky, but you will soon see a snippet of XML that will perform that interaction.

First, here is what XML is in a nutshell: XML stands for Extensible Markup Language. It is syntactically the same as HTML (Hypertext Markup Language) that you see as source for all web pages. The reason for the X is that XML provides a way for anyone to make up their own HTML commands. Actually, don't call them commands. Call them TAGS - that is the actual name for them. Look at it like this: HTML is a set of tags that is known, and acted on, by web browsers. XML is a set of tags known, and acted on, by anyone that wants to make up a control program - such as this game engine. HTML controls a web page and XML controls this game.

This is XML tag syntax: A tag is a name surrounded by <>. <adv> is a tag stating that an adventure begins. I made the "adv" up for the game. That is a "complex" tag because there are a few nested tags inside. A simple tag just has text data. Combining tag names with text data will provide story data that can be controlled! <intro> is a simple tag holding the introduction to the adventure. This whole article will describe every tag but there are very STRICT rules to using the tags. If the rules aren't followed, the web browser will, first, complain about it then lock up. EVERY TAG must have an end-tag. An end-tag is the same as a tag with a slash (/) in front of it. Here is an example:

<adv>
  <intro>
    Welcome to my Adventure!   </intro>
</adv>

Notice the end tags and the order that they are in (last-in-first-out in accounting terms). Keeping that order is called "nesting". There are only two more rules: Some tags can have attributes. In this application, I have only defined ID attributes to two tags: <room> and <object>. They look like this: <room id="n"> where n is a UNIQUE number for that room. That is the best way to reference an element like that. Oops, I forgot to mention that the stuff that the tags hold is called an "element". The only other tag that has an ID is <object id="n">.

First, we will look at the room tag. It contains a <longdesc> and a <shortdesc> tag. The reason for the two different descriptions is to make the game sound a little more intelligent. This is following the paradigm of the Colossal Cave Adventure. The first time you visit a room, the <longdesc> text will be displayed. Next time you enter, the <shortdesc> will display. Here is an example of a two room adventure:

<adv>
  <rooms>
    <room id="1">
      <longdesc>
You are now in the east room. There is a passage to the west.
      </longdesc>
      <shortdesc>You are back in the east room.</shortdesc>
      <w>2</w>
    </room>
    <room id="2">
      <longdesc>
You are now in the west room. There is a passage to the east.
      </longdesc>
      <shortdesc>You are back in the west room.</shortdesc>
      <e>1</e>
    </room>
  </rooms>
</adv>

Notice that I indented each "nested" tag (tag within a tag). The XML interpreter doesn't care but I do that to keep track of the nested tags. Also note the <w> and <e> tags that I haven't described yet. Those are direction tags. If you haven't guessed already, the <w> stands for "west" and <e> is "east". The numbers correspond to the room ID that the direction leads to. If this was displayed like the command-line game, it would look like this: You are now in the east room. There is a passage to the west. >go north You cannot go that direction. >go west You are now in the west room. There is a passage to the east. >go east You are back in the east room. >go west You are back in the west room.

Now, there is a game that you can play for hours! Actually, a pretty interesting world can be created with just the room elements. The user typed "west" which was interpreted to mean <w>. The user could have said "go w" or just "w" and the direction command would have been understood. Here are the directions that the user can use to traverse rooms: <n>, <s>, <e>, <w>, <ne>, <nw>, <se>, <sw>, <u>, <d>, <in>, <out>, <jump>, and <climb>. These are the eight compass points along with up and down to go up or down ladders, stairs, or just drop down holes. The "in" and "out" are handy when the direction is obvious. If you are standing outside a building, "in" makes sense to provide a direction to the room immediately inside the building. Jump and climb can be used creatively to climb ropes or down ladders or jumping across ditches.

Just to make it a little more interesting (and complex of course), you can invent a "transition" room. That is the description of going into another room. That is done with the <transition> tag. What that does is toss in a description prior to the description of the destination room. Here is an example:

<adv>
  <rooms>
    <room id="1">
      <longdesc>
You are now in the east room. There is a door in the west wall.       </longdesc>
      <shortdesc>You are back in the east room.</shortdesc>
      <w>2</w>
    </room>
    <room id="2">
      <longdesc>
You try the door and discover it is unlocked. You open the door and enter the west room, shutting it behind you.       </longdesc>
      <shortdesc>
You open the door and enter west room, again shutting it behind you.       </shortdesc>
      <transition>4</transition>
    </room>
    <room id="3">
      <longdesc>
You try the door to the east room and find it unlocked. You enter the east room and shut it behind you.       </longdesc>
      <shortdesc>
You open the door to the east room and enter, shutting the door behind you.       </shortdesc>
      <transition>1</transition>
    </room>
    <room id="4">
      <longdesc>
You are now in the west room. There is a door in the east wall.       </longdesc>
      <shortdesc>You are back in the west room.</shortdesc>
      <e>3</e>
    </room>
  </rooms>
</adv>

Here is how that one would be played out:

You are now in the east room. There is a door in the west wall.
>west
You try the door and discover it is unlocked. You open the door and enter the west room, shutting it behind you.
You are now in the west room. There is a door in the east wall.
>east
You try the door to the east room and find it unlocked. You enter the east room and shut it behind you.
You are back in the east room.
>w
You open the door and enter west room, again shutting it behind you.
You are back in the west room.
>e
You open the door to the east room and enter, shutting the door behind you.
You are back in the east room.

Okay, that is a really boring example. You can be a little more creative using transitions to describe falling down holes or sliding down ravines. You are probably getting an idea of how bulky this can get. We have now defined four rooms in order to create two. But all great productions have a lot of work behind them. There don't have to be a lot of transitions but they do spice the adventure up a bit.

The final tag defined for rooms is the <darkroom/> tag. Here is a bit of an exception to the rules of XML. I said that all tags need an end tag. This is a tag that is a combination start and end, therefore it stands by itself as a flag. If I add that tag to the first example, here is what the darkroom would act like. First, the XML (note that there is not an ending darkroom tag):

<adv>
  <rooms>
    <room id="1">
      <longdesc>
You are now in the east room. There is a passage to the west.       </longdesc>
      <shortdesc>You are back in the east room.</shortdesc>
      <w>2</w>
    </room>
    <room id="2">
      <darkroom/>
      <longdesc>
You are now in the west room. There is a passage to the east.       </longdesc>
      <shortdesc>You are back in the west room.</shortdesc>
      <e>1</e>
    </room>
  </rooms>
</adv>

The play:

You are now in the east room. There is a passage to the west.
>go west
It is completely dark here. Nothing can be seen.
>go north
You cannot go that direction.
>go east
You are back in the east room.
>go west
It is completely dark here. Nothing can be seen.

Why have that? Those familiar with the Colossal Cave Adventure know you need a lighted lamp in order to traverse anywhere that is not naturally lit. Of course, in the Colossal Cave Adventure, wondering in the dark for very long can be fatal. I decided not to add that complexity to it at this time. Also, there are a few statements that the game engine will produce that are not supplied by the XML author. "It is completely dark here. Nothing can be seen." is one of them. Others are: "You cannot go that direction.", "I don't see that here.", and "I don't understand that." The rest are from you, the author.

The need for that light (a lamp perhaps) is a good introduction for the object elements. Notice that, in the examples, the <room> elements are nested inside a single <rooms> element. The reason for that is to separate <room> elements from <object> elements. Thus, the complex tag grouping the <object> elements is, of course, <objects>. Like the rooms, each object has a unique number called an ID. Unlike the rooms, the objects can get pretty complicated. You can go into a room and look around, but you perform action on an object. The action could be anything the author wants. A <verb> is supplied that anticipates a verb that the user would type in. I will state, now, that the engine knows Verb-Object Pidgin English taking the first word as the verb and the LAST word as the object. That way, you can go crazy with adjectives and definite articles; none of that matters except the last word. The use of prepositions is unnecessary and confusing. "Break glass with hammer" would be interpreted as "break hammer". To break the glass, just say, "Break glass". If a hammer is needed, it will be used if you are carrying it. Remember that all that is an example. You are the author. You decide what is carried and needed to perform an action. You will see what I mean soon.

An object can be picked up (if small enough), carried around, and dropped. You can look at or examine an object. That may reveal something that wasn't originally obvious. You can open it if it can be opened. You can light it. Of course you want to do that to a lamp and not dynamite. Or just turn it on. If you add a <darkroom/> tag to any of your rooms, you will need an object that can be lit. If it has to be turned on and off, then you will need TWO lamps-one that is on and one that is off. That is a way around having too many attributes for generic objects, have one morph into another. Here is an example lamp; I will describe the tags after:

<objects>
  <object id="1">
    <name>lamp</name>
    <name>light</name>
    <weight>2</weight>
    <initroom>28</initroom>
    <initdesc>
Sitting on a small table under a window is an electric lamp     </initdesc>
    <finddesc>There is a lamp here.</finddesc>
    <detail>
This is an electric lamp and it is currently off.     </detail>
    <action>
      <verb>light</verb>
      <verb>on</verb>
      <verb>turnon</verb>
      <pass>
You turn on the lamp and a soft glow surrounds you.       </pass>
      <mutate>2</mutate>
    </action>
    <action>
      <verb>off</verb>
      <verb>turnoff</verb>
      <verb>douse</verb>
      <pass>It is already off.</pass>
    </action>
  </object>
  <object id="2">
    <litobject/>
    <name>lamp</name>
    <name>light</name>
    <weight>2</weight>
    <initroom>0</initroom>
    <initdesc>
The lamp can now be used to light the way in dark places.     </initdesc>
    <finddesc>There is a lamp here.</finddesc>
    <detail>
This is an electric lamp and it is currently on.     </detail>
    <action>
      <verb>off</verb>
      <verb>turnoff</verb>
      <verb>douse</verb>
      <pass>The lamp is now off.</pass>
      <mutate>1</mutate>
    </action>
    <action>
      <verb>light</verb>
      <verb>on</verb>
      <verb>turnon</verb>
      <pass>It is already on.</pass>
    </action>
  </object>
</objects>

With this lamp, you can pick it up, light it, turn it off, drop it anywhere (off or on). The action verbs show everything you can do with it except for "get" and "drop". Like "go"- ing a direction, get and drop are verbs intercepted and used by the engine.

Notice that there are two <object> elements within the <objects> element: Numbers 1 and 2. There is an <initdesc> and a <finddesc>--sort of like the <longdesc> and <shortdesc> in the room elements. The <initdesc> will describe what the object looks like as long as it has never been picked up. If it is picked up and set back down, the <finddesc> description will be displayed. The <weight> is any number from 1 to 9 that can add up to a value that is the limit of what can be carried. Right now, there is no limit but weight is an important indicator that the object can be carried at all. If the weight is 0 or not even defined for the object, it cannot be carried. It is either too big, heavy, or it is part of the room. If you "look at" an object, you have to be carrying it if it has weight. If it doesn't have weight, then it just has to be in the same room with you to be looked at. Looking at an object will display what is in the <detail> tag.

Notice the <action> tags. These contain all the synonyms of an action that the user types in. Those are the <verb> tags. Action tags are complex. Notice that <pass> is used to describe what happens when you "light" the lamp or "turnoff" the lamp. You will see that I added comments to attempt to "light" a lamp that is already on or "turnoff" a lamp that is already off. I could have left that out and the engine would say that it doesn't know how to do that to the lamp. The reason that this tag is called <pass> is that there may be a time when an action will <fail>. There is a tag that is not used here because nothing is needed. If something is needed to turn the lamp on, we would add the <with> tag. Let's say you decide that you have a kerosene lamp that requires a match. You need to be carrying a match to "light" the lamp. Let's give the match an object value of 3. Here is what that would look like:

<objects>
  <object id="1">
    <name>lamp</name>
    <name>light</name>
    <weight>2</weight>
    <initroom>28</initroom>
    <initdesc>
Sitting on a small table under a window is kerosene lamp.     </initdesc>
    <finddesc>There is a lamp here.</finddesc>
    <detail>
This is a lamp with a flat wick and a small amount of fuel in the base.     </detail>
    <action>
      <verb>light</verb>
      <with>3</with>
      <pass>
You strike the match and apply it to the wick and it starts to glow.       </pass>
      <fail>You have nothing to light the wick with.</fail>
      <mutate>2</mutate>
    </action>
    <action>
      <verb>extinguish</verb>
      <pass>It isn't lit.</pass>
    </action>
  </object>
  <object id="2">
    <litobject/>
    <name>lamp</name>
    <name>light</name>
    <weight>2</weight>
    <initroom>0</initroom>
    <initdesc>
This lamp can now be used to light the way in dark places.     </initdesc>
    <finddesc>There is a glowing lamp here.</finddesc>
    <detail>
This is a kerosene lamp that is currently lit.     </detail>
    <action>
      <verb>extinguish</verb>
      <pass>You move the wick down and the lamp turns off.</pass>
      <mutate>1</mutate>
    </action>
    <action>
      <verb>light</verb>
      <pass>The lamp is already lit.</pass>
    </action>
  </object>
  <object id="3">
    <name>match</name>
    <weight>1</weight>
    <initroom>24</initroom>
    <initdesc>
There is a wooden stick match lying on the table.     </initdesc>
    <finddesc>There is a match here.</finddesc>
    <detail>
This is a wooden strike-anywhere stick match.     </detail>
    <!-In case user says, "light match" instead of "light lamp" -->
    <action>
      <verb>light</verb>
      <pass>
It is not safe to play with matches! You can use it to light something though.       </pass>
    </action>
  </object>
</objects>

Now there is a <fail> element in the <light> action element. If there is no object number 3 (a match) being carried, the lamp cannot be lit. I would suggest the electric light though it sounds fun to hide a match somewhere else. The reason for that is that, in this scenario, you can light the lamp with a match, but you are still carrying around an unlit match--not very realistic. I am making a mental note (I never forget mental notes) to add a lifetime to objects and also perform backlash actions on a "with" object.

I have introduced something else in the "match" object. Notice the comment I made starting with these four characters: < ! - -, and ending with these three characters: - - >. That is how comments are done in XML (and HTML of course). I am sure you would want to make notes to yourself and others using this. As soon as you enter "< ! - -" in your document, you can make multiple-line comments until you finally end with "- - >".

Finally, notice the <litobject/> tag. Like the <darkroom/> tag, it does not need an ending tag since it has the slash character following the tag word. The <litobject/> objects provide light in the dark rooms. Unlike Colossal Cave Adventure, this currently does not have a lifetime-in other words; your battery never runs out of juice.

So, we have objects that can take any known action (verb) and act on it if you include that in the object element. Here is something else these objects can do. They can "spawn" other objects. This is similar to <mutate> except that the original object is unaffected and a new object is created. One example is to crack an egg which hatches a dragon. Literally, what cracking (breaking) the egg does is to mutate the whole egg into a broken egg and spawn a dragon. A more mundane action would be to open a drawer to discover another object (such as a ring) inside. Let's say that the drawer requires a key to open it also. What you would need for that is a key, a ring, and two mutations of the drawer:

<objects>
  <object id="10">
    <name>key</name>
    <weight>1</weight>
    <initroom>40</initroom>
    <initdesc>
There is a small key lying on the table.     </initdesc>
    <finddesc>There is a key here.</finddesc>
    <detail>
There is only one notch on each side of the key. It is very small.     </detail>
  </object>
  <object>
  <object id="11">
    <name>dresser</name>
    <name>drawer</name>
    <name>vanity</name>
    <weight>0</weight>
    <initroom>45</initroom>
    <initdesc>
There is a small vanity against the wall opposite the doorway.     </initdesc>
    <finddesc>There is a vanity here.</finddesc>
    <detail>
It has a single drawer with two knobs and a keyhole in the center.     </detail>
    <action>
      <verb>open</verb>
      <with>10</with>
      <pass>You use the small key to unlock the drawer. It easily slides open.       </pass>
      <fail>
The drawer is securely locked and you have no key.       </fail>
      <mutate>12</mutate>
      <spawn>13</spawn>
    </action>
  </object>
  <object id="12">
    <name>dresser</name>
    <name>drawer</name>
    <name>vanity</name>
    <weight>0</weight>
    <initroom>0</initroom>
    <initdesc>
There is a vanity here that now has an open drawer.     </initdesc>
    <finddesc>
There is a vanity here.     </finddesc>
    <detail>
It has a single drawer which is currently hanging open.     </detail>
<!- We will anticipate that the user will want to close the drawer. Mutating to an empty dresser may get confusing and lose the key forever if the user doesn't take the key before closing the drawer. So we conveniently stick the drawer open on a "close". -->
    <action>
      <verb>close</verb>
      <pass>
You attempt to close the drawer but it appears stuck now.       </pass>
    </action>
  </object>
  <object id="13">
    <name>ring</name>
    <weight>1</weight>
    <initroom>0</initroom>
    <initdesc>
You see a shiny golden ring lying in the drawer!     </initdesc>
    <finddesc>There is a gold ring here.</finddesc>
    <detail>
There is mysterious writing on the inside of the ring: Made in China.     </detail>
  </object>
</objects>

This is a vanity that will yield a ring with a <spawn> element. Notice that I do not allow for the closing of the drawer. If I decided to mutate the drawer back to object 12, it would work fine unless you took the ring. If you took the ring then closed the drawer, it would miraculously disappear from your inventory and end up back in the drawer. If I mutated the open drawer to a third empty drawer, then it would be great if you took the ring; but if you didn't, it would disappear forever if you closed the drawer without taking it. Here is an example play:

You are in the northeast bedroom.
There is a small vanity against the wall opposite the doorway.
>look at vanity
It has a single drawer with two knobs and a keyhole in the center.
>open drawer
You use the small key to unlock the drawer. It easily slides open.
The vanity now has an open drawer.
You see a shiny golden ring lying in the drawer!
>look at ring
You are not carrying ring.
You are in the northeast bedroom.
There is a vanity here.
You see a shiny golden ring lying in the drawer!
>get ring
Okay.
>look at ring
There is mysterious writing on the inside of the ring: Made in China.
>close drawer
You attempt to close the drawer but it appears stuck now.
>look
You are in a windowless bedroom that is empty except for one piece of furniture.
There is a vanity here that now has an open drawer.

It is very important, at times, to pay attention to the order that you define these objects. Notice that the key is defined AFTER the vanity that spawns it. That is because I describe the key as being inside the drawer (at least until it is picked up). If the key was defined before the vanity, the description of the room would read like this: You are in the northeast bedroom. You see a shiny golden ring lying in the drawer! There is a vanity here.

Finally, an object can offer directions! These directions are the same compass points, up, down, etc. that rooms have. The directions offered by the object are simply added to the possible directions that the room provides. There is a good reason for this. You may want two mutations of an object: One that blocks a passageway and one that opens a passageway. This could be a sliding bookshelf (mutated by a "move" action). Here is an example of a moving bookshelf:

<objects>
  <object id="20">
    <name>bookcase</name>
    <name>bookshelf</name>
    <weight>0</weight>
    <initroom>45</initroom>
    <initdesc>
There is a six foot tall, three-foot wide bookcase against the south wall.     </initdesc>
    <finddesc>There is a bookcase against the south wall.</finddesc>
    <detail>
None of the books look interesting enough to take. There is a Harry Potter collection but you've already read it.     </detail>
    <action>
      <verb>move</verb>
      <verb>push</verb>
      <pass>You are able to move the bookcase to the side to reveal a large five by 2 foot hole cut in the wall. You peer in and see a dark passage.       </pass>
      <mutate>21</mutate>
    </action>
  </object>
  <object id="21">
    <name>bookcase</name>
    <name>bookshelf</name>
    <weight>0</weight>
    <initroom>0</initroom>
    <initdesc>
There is a six foot tall, three-foot wide bookcase standing next to a dark five by two foot passageway.     </initdesc>
    <finddesc>
There is a bookcase on south wall standing next to a dark passageway.     </finddesc>
    <detail>
You have moved the bookshelf to reveal a hole in the south wall large enough to pass through.     </detail>
    <action>
      <verb>move</verb>
      <verb>push</verb>
      <pass>
You have moved the bookshelf back, covering the hole.       </pass>
      <mutate>20</mutate>
    </action>
    <s>49</s>
  </object>
</objects>

Notice that there are two objects that mutate into each other when they are moved. The one that has a passageway next to it is the one that has a direction associated with it also: <s>49</s>. Say you are in room #45 (the <initroom> of the original bookcase). The directions in room 45 may be north and east only. If the user enters "go south", the response will be "There is no way to go that direction." If the user enters "move bookcase", the response will be what is shown in the <pass> element plus the <initdesc> of the new mutated bookcase. If the user enters "go south" this time, he will end up in room 49.

I am hoping that showing a bit of evolution along with examples truly makes this a "Simple" Adventure Game Markup Language. The word "Simple" has been used heavily by standards creators in the IT field and they never fail to completely blow me away when describing their simple concepts. I would truly love for every man, woman, and child to try "programming" a game in this XML based language for fun and maybe a little practice at painting literary pictures. Unlike the Colossal Cave Adventure, this currently does not have pits in unlit rooms, pirates, mean little dwarves, or anything else that can lead to your demise; but you can write an object in such a way as it can menace you or chase you around the room. Chasing would be the extent of its deadliness though, and no following from room to room. Perhaps there will be a future <monster> tag or a "chase around" attribute to an object tag.

Wait! The future is here! Kinda... Remember when I said, I am making a mental note to add a lifetime to objects and also perform backlash actions on a "with" object. Well, there is still no lifetime but there is a way to affect an object you are doing something "with". There is also an opposite of "with" called "to" that can be used. Here is how that works.

Perhaps, for example, you want to insert a coin into a slot. How do you say that when you can only act on a slot "with" a coin? Insert slot? That doesn't make sense. Now, you can add a <to> element to an "insert" action for the coin. If a slot is object ID "30", you can add this to an "insert" action: <to>30</to>. Then the <pass> text would be displayed if the <to> object was being carried or in the same room. You still cannot say "insert coin into slot" but you can say "insert coin" and stuff will happen if the slot is there. The <fail> message would be, "I don't see anything to insert the coin into."

Another few of tags have been added to spice things up a little more: <mutatewith>, <mutateto>, <spawnwith>, and <spawnto>. This is telling the engine to either mutate or spawn the <with> or <to> objects. This is how you can actually light an object "with" a match and have the match become exhausted. Here is an example XML snippet:

  <object id="20">
    <name>match</name>
    <weight>1</weight>
    <initroom>0</initroom>
    <initdesc>
There is a wooden match laying in the box.     </initdesc>
    <finddesc>There is a wooden match here.</finddesc>
    <detail>
This is a wooden Strike-Anywhere match that probably still requires the sandpaper on the side of the box to light.     </detail>
    <action>
      <verb>strike</verb>
      <verb>light</verb>
      <to>22</to>
      <pass>
You strike the match and touch it to the end of the fuse       </pass>
      <fail>I don't see anything to burn. Let's not.</fail>
      <mutate>21</mutate>
    </action>
  </object>
  <object id="21">
    <name>match</name>
    <weight>1</weight>
    <initroom>0</initroom>
    <initdesc>
You are now carrying a burnt match.     </initdesc>
    <finddesc>There is a burnt match laying here.</finddesc>
  </object>
  <object id="22">
    <name>fuse</name>
    <weight>0</weight>
    <initroom>90</initroom>
    <initdesc>
There is a long fuse sticking out of the dynamite.     </initdesc>
    <finddesc>
There is a long fuse sticking out of the dynamite.     </finddesc>
    <action>
      <verb>light</verb>
      <with>20</with>
      <mutatewith>21</mutatewith>
      <pass>
You strike the match you are carrying and touch it to the fuse.       </pass>
      <transport>91</transport>
    </action>
  </object>

Notice that the fuse (object 22), if you are carrying a 20 (unlit match) will mutate the with object (20) to a 21 (burned match). The <transport> I will leave to your imagination. Actually, that that can do is change the room you are in (90 in this case) to 91 which will be a transition room describing the fuse burning down and blowing things up. And transport you to a new room that is blown up but offers more directions. Get what I mean. Be creative. This is not in the Haunted House Adventure - I just made it up just now as an example.

I want people to play the Haunted House, though it really isn't much. Look at the XML belonging to it. It will totally spoil the game for you but that is not the point. The point is that I don't care about people playing games I write. The point is that you, dear reader, can create your own! My only warning is this: XML is extremely unforgiving. If you miss a slash or misspell anything, the game will warn you of dire circumstance. One way of testing your XML is to load it from your Windows Explorer using Internet Explorer (or other browser I think). The browser will attempt to interpret the XML and give you a location (or close to) of the imperfect XML. If you have HomePage or something like that, it may provide a smarter XML editor than Notepad. Just start making rooms to begin with and add objects, transition rooms, etc. as they come to mind.

Enjoy!