Contents
Back
Forward

10. Places, scenery, directions and the map

It was a long cylinder of parchment, which he unrolled and spread out on the floor, putting a stone on one end and holding the other. I saw a drawing on it, but it made no sense.

...John Christopher (1922--), The White Mountains

Back to 'Ruins': what lies at the foot of the stone steps? We'll now add four rooms, connected together:

  Square Chamber  <-->  Web
       |       
    Corridor
       |       
     Shrine
with the Square Chamber lying underneath the original Forest location. For instance, here's the Square Chamber's definition:
Object Square_Chamber "Square Chamber"
  with name "lintelled" "lintel" "lintels" "east" "south" "doorways",
       description
          "A sunken, gloomy stone chamber, ten yards across.  A shaft
           of sunlight cuts in from the steps above, giving the chamber
           a diffuse light, but in the shadows low lintelled doorways to
           east and south lead into the deeper darkness of the Temple.",
       u_to Forest, e_to Web, s_to Corridor,
  has  light;
Like the Forest, this place has light, however dim. (If it didn't, the player would never see it, since it would be dark, and the player hasn't yet been given a lamp or torch of some kind.) Now although this is a room, and can't be referred to by the player in the way that a manipulable object can, it still can have a name property. These name words are those which Inform knows "you don't need to refer to'', and it's a convention of the genre that the designer should signpost off the game in this way. (Note that they'll only be looked at if what the player types is unrecognised, so the word "east'' is understood quite normally; but a reference to "east lintel'' will get the "don't need to refer to'' treatment.) This room is unfurnished, so:
Object -> "carved inscriptions"
  with name "carved" "inscriptions" "carvings" "marks" "markings" "symbols"
            "moving" "scuttling" "crowd" "of",
       initial
          "Carved inscriptions crowd the walls, floor and ceiling.",
       description "Each time you look at the carvings closely, they seem
           to be still.  But you have the uneasy feeling when you look
           away that they're scuttling, moving about.  Their meaning
           is lost on you.",
  has  static;
This is part of the fittings, hence the static attribute, which means it can't be taken or moved. As we went out of our way to describe a shaft of sunlight, we'll include that as well:
Object -> sunlight "shaft of sunlight"
  with name "shaft" "of" "sunlight" "sun" "light" "beam" "sunbeam" "ray"
            "rays" "sun^s",
       description "The shaft of sunlight glimmers motes of dust in the
           air, making it seem almost solid."
  has  scenery;
(The symbol in "sun^s" means an apostrophe, so the word is "sun's''.) Being scenery makes the object not only static but also not described by the game unless actually examined by the player. A true perfectionist might add a before rule:
       before
       [;  Examine, Search: ;
           default: "It's only an insubstantial shaft of sunlight.";
       ],
so that the player can look at or through the sunlight, but any other request involving them will be turned down. Note that a default rule, if given, means "any action except those already mentioned''.

We can't actually get into the Square Chamber yet, though. Just because there is a map connection up from here to the Forest, it doesn't follow that there's a corresponding connection down. So we must add a d_to to the Forest, and while we're at it:

       d_to Square_Chamber,
       u_to "The trees are spiny and you'd cut your hands to ribbons
             trying to climb them.",
       cant_go "The rainforest-jungle is dense, and you haven't hacked
           through it for days to abandon your discovery now.  Really,
           you need a good few artifacts to take back to civilization
           before you can justify giving up the expedition.",
The property cant_go contains what is printed when the player tries to go in a nonexistent direction, and replaces "You can't go that way''. As is often the case with properties, instead of giving an actual message you can instead give a routine to print one out, to vary what's printed with the circumstances. The Forest needs a cant_go because in real life one could go in every direction from there: what we're doing is explaining the game rules to the player: go underground, find some ancient treasure, then get out to win. The Forest's u_to property is a string, not a room; this means that attempts to go up result only in that string being printed.

Rooms also have rules of their own. We might add the following before rule to the Square Chamber:

       before
       [;  Insert:
               if (noun==mushroom && second==sunlight)
               {   remove mushroom;
                  "You drop the mushroom on the floor, in the glare of
                   the shaft of sunlight.  It bubbles obscenely,
                   distends and then bursts into a hundred tiny insects
                   which run for the darkness in every direction.  Only
                   tiny crumbs of fungus remain.";
               }
       ],
The variables noun and second hold the first and second nouns supplied with an action. Rooms have before and after routines just as objects do, and they apply to anything which happens in the given room. This particular rule could easily enough have been part of the definition of the mushroom or the sunlight, and in general a room's rules are best used only for geographical fixtures.

/\/\ Sometimes the room may be a different one after the action has taken place. The Go action, for instance, is offered to the before routine of the room which is being left, and the after routine of the room being arrived in. For example:
       after
       [; Go: if (noun==d_obj)
              print "You feel on the verge of a great discovery...^";
       ],
will print the message when its room is entered via the "down" direction. Note that since the message is printed with the print command, there is no "return true'' from this routine, so it returns false: and so the usual game rules resume after the printing of the message.

Some objects are present in many rooms at once. The 'Ruins', for instance, are misty:

Object low_mist "low mist"
  with name "low" "swirling" "mist",
       initial "A low mist swirls about your feet.",
       description "The mist carries a rich aroma of broth.",
       found_in  Square_Chamber  Forest,
       before
       [; Examine, Search: ;
          Smell:   <<Examine self>>;
          default: "The mist is too insubstantial.";
       ],
  has  static;
The found_in property gives a list of places in which the mist is found (so far just the Square Room and the Forest).

/\ If the rainforest contained many misty rooms, it would be tedious to give the full list and even worse to have to alter it as the mist drifted about in the course of the game. Fortunately found_in can contain a routine instead of a list. This can look at the current location and say whether or not the object should be put in it when the room is entered, e.g.,
Object Sun "Sun",
  with ...
       found_in
       [; if (location has light) rtrue;
       ],
  has  scenery;

/\/\ found_in is only consulted when the player's location changes, so if the mist has to dramatically lift or move then it needs to be moved or removed 'by hand'. A good way to lift the mist forever is to remove it, and then give it the absent attribute, which prevents it from manifesting itself whatever found_in says.

Some pieces of scenery afflict the other four senses. The mist smells of broth, which means that if the player types "smell'' in a place where the mist is, then she should be told about the broth. For this, a react_before rule attached to the mist is ideal:

       react_before
       [;  Smell: if (noun==0) <<Smell low_mist>>;
       ],
This is called a "react'' rule because the mist is reacting to the fact that a Smell action is taking place nearby. noun is compared with zero to see if the player has indeed just typed "smell'' (not, say, "smell crocus''). Thus, when the action Smell takes place near the mist, it is converted into Smell low_mist; whereas the action Smell crocus would be left alone.

The five senses all have actions in Inform: Look, Listen, Smell, Taste and Touch. Of these, Look never has a noun attached (because Examine is provided for close-ups), Smell and Listen may or may not have while Taste and Touch always have.

??EXERCISE 5:
(link to
the answer)
(Cf. 'Spellbreaker'.) Make an orange cloud descend on the player, which can't be seen through or walked out of.

Directions (such as "north") are objects called n_obj, s_obj and so on: in this case, in_obj. (They are not to be confused with the property names n_to and so on.) Moreover, you can change these directions: as far as Inform is concerned, a direction is any object in the special object compass.

??/\EXERCISE 6:
(link to
the answer)
In the first millenium A.D., the Mayan peoples of the Yucat\'an Peninsula had 'world colours' white ( sac), red ( chac), yellow ( kan) and black ( chikin) for what we call the compass bearings north, east, south, west (for instance west is associated with 'sunset', hence black, the colour of night). Implement this.

??/\EXERCISE 7:
(link to
the answer)
(Cf. 'Trinity'.) How can the entire game map be suddenly east-west reflected?

??/\/\EXERCISE 8:
(link to
the answer)
Even when the map is reflected, there may be many room descriptions referring to "east'' and "west'' by name. Reflect these too.

/\ The ordinary Inform directions all have the number property defined (initially set to zero): this is to provide a set of scratch variables useful, for instance, when coding mazes.

/\/\ If the constant WITHOUT_DIRECTIONS is defined before inclusion of the library files, then 10 of the default direction objects are not defined by the library. The designer is expected to define alternative ones (and put them in the compass object); otherwise the game will be rather static. (The "in" and "out" directions are still created, because they're needed for getting into and out of enterable objects.)

*REFERENCES:
'Advent' has a very tangled-up map in places (see the mazes) and a well-constructed exterior of forest and valley giving an impression of space with remarkably few rooms. The mist object uses found_in to the full, and see also the stream (a single object representing every watercourse in the game). Bedquilt and the Swiss Cheese room offer classic confused-exit puzzles.
For a simple movement rule using e_to, see the Office in 'Toyshop'.
The library extension "smartcantgo.h'' by David Wagner provides a system for automatically printing out "You can only go east and north.''-style messages.
'A Scenic View', by Richard Barnett, demonstrates a system for providing examinable scenery much more concisely (without defining so many objects).


Contents / Back / Forward
Chapter I / Chapter II / Chapter III / Chapter IV / Chapter V / Chapter VI / Appendix
Mechanically translated to HTML from third edition as revised 16 May 1997. Copyright © Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.