Section 10: Places, scenery, directions and the map

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.