Section 11: Containers, supporters and sub-objects

Contents Back Forward | ### 11. Containers, supporters and sub-objects
| The concept of a surface is implemented as a special kind of containment. Objects which have surfaces on which other objects may sit are actually containers with an additional property of "surfaceness". ...P. David Lebling, Zork and the Future The year has been a good one for the Society (hear, hear). This year our members have put more things on top of other things than ever before. But, I should warn you, this is no time for complacency. No, there are still many things, and I cannot emphasize this too strongly, not on top of other things. ...'The Royal Society For Putting Things On Top Of Other Things', Monty Python's Flying Circus, programme 18 (1970) Objects can be inside or on top of one another. An object which has the `container` attribute can contain things, like a box: one which has `supporter` can hold them up, like a table. (An object can't have both at once.) It can hold up to 100 items, by default: this is set by the `capacity` property. However, one can only put things inside a container when it has `open`. If it has `openable`, the player can open and close it at will, unless it also has `locked`. A `locked` object (whether it be a door or a container) cannot be opened. But if it has `lockable` then it can be locked or unlocked with the key object given in the `with_key` property. If `with_key` is undeclared, then no key will fit, but this will not be told to the player, who can try as many as he likes. Containers (and supporters) are able to react to things being put inside them, or removed from them, by acting on the signal to `Receive` or `LetGo`. For example, deep under the 'Ruins' is a chasm which, perhaps surprisingly, is implemented as a container:
    Object -> chasm "horrifying chasm"
      with name "blackness" "chasm" "pit" "depths" "horrifying" "bottomless",
           react_before
           [;  Jump: <<Enter self>>;
               Go: if (noun==d_obj) <<Enter self>>;
           ],
           before
           [;  Enter: deadflag=1;
                  "You plummet through the silent void of darkness!";
           ],
           after
           [;  Receive: remove noun;
                   print_ret (The) noun, " tumbles silently into the
                       darkness of the chasm.";
               Search: "The chasm is deep and murky.";
           ],
      has  scenery open container;
(Actually the definition is a little longer, so that the chasm reacts to a huge pumice-stone ball being rolled into it; see 'Ruins'.) Note the use of an `after` rule for the `Search` action: this is because an attempt to "examine'' or "look inside'' the chasm will cause this action. `Search` means, in effect, "tell me what is inside the container'' and the `after` rule prevents a message like "There is nothing inside the chasm.'' from misleading the player. Note also that the chasm 'steals' any stray `Jump` action and converts it into an early death.
| EXERCISE 9: (link to the answer)
| Make the following, rather acquisitive bag:
    >put fish in bag
    The bag wriggles hideously as it swallows the fish.
    >get fish
    The bag defiantly bites itself shut on your hand until you desist.
| `LetGo` and `Receive` are examples of actions which aren't explicitly requested by the player, but are generated by the game in the course of play (so-called "fake actions'').
| `Receive` is sent to an object O both when a player tries to put something in O, and put something on O. In the rare event that O needs to react differently to these, it may consult the variable `receive_action` to find out whether `##PutOn` or `##Insert` is the cause.
| The 'Ruins' packing case is a typical container:
    Object -> packing_case "packing case"
      with name "packing" "case" "box" "strongbox",
           initial
              "Your packing case rests here, ready to hold any important
               cultural finds you might make, for shipping back to civilisation.",
           before
           [;  Take, Remove, PushDir:
                  "The case is too heavy to bother moving, as long as your
                   expedition is still incomplete.";
           ],
      has  static container open;
Now suppose we want a portable television set with four different buttons on it. Obviously, when the television moves, its buttons should move with it, and the sensible way to arrange this is to make the four buttons possessions of the `television` object. But members of an object which isn't a container are normally assumed by the game to be hidden invisibly inside (they are said to be "not in scope''). We have to override this in order to make the four buttons visible from outside, by giving the television the `transparent` attribute.
| EXERCISE 10: (link to the answer)
| Implement a television set with attached power button and screen.
| EXERCISE 11: (link to the answer)
| Make a glass box and a steel box, which would behave differently when a lamp is shut up inside them.
| It sometimes happens that an object should have sub-objects, like lamps and buttons, as well as possessions, in which case the above solution is unsatisfactory. Fuller details will be given in the "scope addition'' rules in Section 28, but briefly: an object's `add_to_scope` property may contain a list of sub-objects to be kept attached to it (and these sub-objects don't count as possessions).
| EXERCISE 12: (link to the answer)
| Implement a macramè bag hanging from the ceiling, inside which objects are visible (and audible, etc.) but cannot be touched or manipulated in any way.
| REFERENCES: Containers and supporters abound in the example games (except 'Advent', which is too simple, though see the water-and-oil carrying bottle). Interesting containers include the lottery-board and the podium sockets from 'Balances' and the 'Adventureland' bottle. For supporters, the hearth-rug, chessboard, armchair and mantelpiece of 'Alice Through The Looking-Glass' are typical examples; the mantelpiece and spirit level of 'Toyshop' make a simple puzzle, and the pile of building blocks a complicated one; see also the scales in 'Balances'.

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.