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’ sketch, Monty Python's Flying Circus, programme 18 (1970)
In almost every game, certain objects need to be thought of as on
top of or inside other objects. The library provides actions Insert
and PutOn
for placing things inside or on top of something,
and Remove
for taking things out of or off the top of something.
Many objects, such as house-bricks, cannot sensibly contain things,
and a designer usually only wants certain specific items ever to have
other things on top of them. In the model world, then, only objects which
the designer has given the container
attribute can contain
things, and only those given the supporter
attribute
can have items on top.
The packing case brought by our archaeologist hero
to the scene of the ‘Ruins’ (found in the opening location,
the Forest) is a thoroughly 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 openable;
A container can hold anything up to 100 items, but
this limit can be modified by giving the container a capacity
property.
Note that the packing case is defined having an
attribute called open
. This is essential, because the
library will only allow the player to put things in a container
if it is currently open
. (There is no attribute called
closed
, as any
container lacking open
is
considered closed.) If a container 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 its with_key
property. If with_key
is undeclared or equal to nothing
,
then no key will fit, but this will not be told to the player. The
actions Open
, Close
, Lock
and
Unlock
handle all of this.
•
EXERCISE 15
Construct a musical box with a silver key.
· · · · ·
An object having supporter
can have
up to 100 items put on top of it, or, once again, its capacity
value if one is given. An object cannot be both a container
and a supporter
at once, and there's no concept of
being “open” or “locked” for supporters.
Here is an example from the Shrine:
Object -> stone_table "slab altar" with name 'stone' 'table' 'slab' 'altar' 'great', initial "A great stone slab of a table, or altar, dominates the Shrine.", has enterable supporter static;
See §15 for enterable
and its consequences.
· · · · ·
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,
further down in the ‘Ruins’ is a chasm which, perhaps
surprisingly, is implemented as a container:
Object -> chasm "horrifying chasm" with name 'blackness' 'chasm' 'pit' 'horrifying' 'bottomless', react_before [; Jump: <<Enter self>>; Go: if (noun == d_obj) <<Enter self>>; ], before [; Enter: deadflag = true; "You plummet through the silent void of darkness!"; JumpOver: "It's far too wide."; ], 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 will grow in
§23, so that the chasm reacts to an
eight-foot pumice-stone ball being rolled into it.) 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 in the vicinity using react_before
and
converts it into an early death.
•
EXERCISE 16
Make an acquisitive bag which will swallow things up but refuses to
disgorge them.
▲
Receive
is sent to an object O when a player
tries to put something in O, or on O. In the rare event
that O needs to react differently to these two attempts,
it may consult the library's variable receive_action
to find out whether ##PutOn
or ##Insert
is the cause.
· · · · ·
Not all containment is about carrying or supporting
things. For instance, suppose a machine has four levers. If the
machine is fixed in place somewhere, like a printing press, the
levers could be provided as four further static
objects.
But if it is portable, like a sewing machine, we need to make sure
that the levers always move whenever it moves, and vice versa.
The natural solution is to make the lever-objects children of the
machine-object, as though the machine were a container and the
levers were its contents.
However, members of an object which isn't a container
or supporter
are normally assumed by the library to be
hidden invisibly inside. In the case of the levers, this would defeat
the point. We can get around this by giving the machine the transparent
attribute, making the levers visible but not removable.
Containers can also be transparent
, making
their contents visible even when closed. The items on top of a supporter
are of course always visible, and it makes no sense for a supporter
to be transparent
. See §26
for further details on when contents are listed in inventories and
room descriptions.
•
EXERCISE 17
Make a glass box and a steel box, which behave differently when a
lamp is shut up inside them.
•
EXERCISE 18
Make a television set with attached power button and screen.
•▲
EXERCISE 19
Implement a macramé bag hanging from the ceiling, inside
which objects are visible, audible and so forth, but cannot be
touched or manipulated in any way.
▲
The most difficult case to handle is when an object needs to be
portable, and to have sub-objects like lamps and buttons, and
also to be a container in its own right. The solution to this will
have to be left until the “scope addition” rules in
§32, but briefly: an object's
add_to_scope
property may contain a list of sub-objects
to be kept attached to it but which are not its children.
•
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’.