CONTAINERS
CONTAINERS
Is That an Open Container, Son?
There are all sorts of OBJECTS in Interactive Fiction that are CONTAINERS: boxes and baskets, bowls and cups and bottles; of course these are CONTAINERS, as well as cabinets, drawers, trash cans, and so on. Many CONTAINERS can be opened and/or closed, locked or unlocked, transparent (such as a wine glass) or not (such as a lead-lined box), empty or with contents inside.
Our game "TV Time!" will have several CONTAINERS, one of which we have already created but not yet given the CONTAINER property. No, it's not the chair. Even though we will later program the chair for sitting in, the chair is not a CONTAINER. In fact, neither the Hero nor any Actor (NPC, or "non-player character") can be inside a CONTAINER. The proto-CONTAINER in our game is the table.
...
THE table Isa OBJECT AT tv_room
DESCRIPTION
VERB examine
DOES ONLY
"It's an ordinary table, set conveniently by your chair."
END VERB.
END THE table.
...
Oh yes, right now it is only "an ordinary table". But it is about to be transformed with a single word.
...
THE table Isa OBJECT AT tv_room
CONTAINER
DESCRIPTION
VERB examine
DOES ONLY
"It's an ordinary table, set conveniently by your chair."
END VERB.
END THE table.
...
And just like that (snap!) it is done. Note that being a CONTAINER is not an Attribute. (Though it can be one of the non-Boolean sort if we wish, with "HAS CONTAINER". That will not be covered in this guide.)
Now the player can "put <something> in" the table or "take <something> from" it. Try it, if you like.
Each of these VERBS requiring a CONTAINER is covered in the library. But our table does not have any drawers or anything to put something inside. Our table is a simple surface, and all we want is to be able to put something on the table (and take from it). Nevertheless, in order to understand what we are going to do with the "put on" VERB, we will first have to understand the "put in" VERB, from "put.i":
SYNTAX
put_in = put (obj1) 'in' (obj2)
WHERE obj1 ISA OBJECT
ELSE "You can't put that anywhere."
AND obj2 ISA CONTAINER
ELSE "You can't put anything in that."
Sin Tax?
As you can see, the construction of a VERB becomes more complex when it involves not just one, but two or more OBJECTS. In this case we have two OBJECTS, represented by obj1 and obj2. It is important to figure out which is the CONTAINER and which is being "put in" the CONTAINER.
The SYNTAX statement defines which is which: obj1 ISA OBJECT and obj2 ISA CONTAINER. We can think of the SYNTAX statement as that which defines the parameters of the VERB. It tells us the exact wording of the VERB. The single word "put_in" that is used by the VERB equals the two player-input words "put" and "'in'" (another Alan reserved word) in regards to the OBJECT and the CONTAINER.
The SYNTAX statement also often acts as a CHECK. It will not allow the VERB if the parameters defined by the SYNTAX statement are not met. If the obj1 is not an OBJECT or if the obj2 is not a CONTAINER, the SYNTAX will inform the player that "You can't put...", etc.
The put_in VERB
Add To Every object
Verb put_in
When obj1
Check obj1 In hero
Else
"You haven't got" Say The obj1. "."
And obj1 <> obj2
Else "You can't put something into itself!"
And obj2 <> hero
Else "You can't put" Say obj1. "into yourself!"
Does
Locate obj1 In obj2.
"Done."
End Verb.
End Add To.
Notice that the VERB is in reference to obj1, the OBJECT to be put in the CONTAINER. There are two clues to this. First, the library is Adding To Every object, not To Every CONTAINER. Second, and the main indicator, the line after "Verb put_in" says "When obj1".
"When" can be translated to mean, "When you want to do this to", in this case, "when you want to put this obj1 in something." If the line were to read instead, "When obj2", it would mean, "when you want to put something in this obj2." We are going to use "When obj2" in just a moment, but for now let's look at the VERB as it is in the library.
The next lines CHECK whether the Hero has the obj1 in his/her Inventory. Again, I prefer to accommodate the player if the obj1 is present in the same LOCATION. So let's change the library VERB to allow that.
Add To Every object
Verb put_in
When obj1
Check obj1 Here -- *** CHANGED FROM In Hero, etc. ***
Else
"You don't see" Say The obj1. "here."
And obj1 <> obj2
Else "You can't put something into itself!"
And obj2 <> hero
Else "You can't put" Say obj1. "into yourself!"
Does
Locate obj1 In obj2.
"Done."
End Verb.
End Add To.
The two "And" statements act as two more CHECKS to the VERB, preventing the player from putting something into itself or into their self. Finally there is the "Does", which LOCATES the obj1 IN the obj2.
The put_on VERB
The library ("put.i") has the "put on" VERB:
...
Syntax
...
put_on = put (obj1) 'on' (obj2)
Where obj1 Isa object
Else "You can't put that anywhere."
And obj2 Isa thing
Else "You can't put anything on that."
...
The library SYNTAX has set the parameters for the "put on" VERB for obj1 as an OBJECT and obj2 as a THING. This works for us, because a CONTAINER is an OBJECT, and an OBJECT is a THING.
The reason obj2 is a THING and not a CONTAINER is to allow the player to put <something> on himself/herself, i.e., to wear it. See "wear.i" in the library.
...
THE table Isa OBJECT AT tv_room
CONTAINER
DESCRIPTION
VERB examine
DOES ONLY
"It's an ordinary table, set conveniently by your chair."
END VERB.
VERB put_on
WHEN obj2
DOES ONLY
LOCATE obj1 IN table.
"You set" Say The obj1. "on the table.""
END VERB.
END THE table.
...
Making the VERB Not Work for the Table
There is a VERB that we do not want to apply to the table, and that is the "put in" VERB. Our table has no drawers to put anything into. So:
...
THE table Isa OBJECT AT tv_room
CONTAINER
DESCRIPTION
VERB examine
DOES ONLY
"It's an ordinary table, set conveniently by your chair."
END VERB.
VERB put_on
WHEN obj2
DOES ONLY
LOCATE obj1 IN table.
"You set" Say The obj1. "on the table.""
END VERB.
VERB put_in
WHEN obj2
CHECK
"There are no drawers in the table to put anything in."
END VERB.
END THE table.
...
WHEN obj2 equals "WHEN you want to put something in this table" (see note above). The VERB hits the CHECK and displays the explanation. There are no drawers in the table to put anything in.
If on the other hand there were another CONTAINER in the game (perhaps a big box), it would be possible to "put the table in the box". The WHEN obj2 only CHECKS and stops the VERB when the table is being used as the CONTAINER. The player could not "put the box in the table". But he/she could "put the box on the table".
What Does a Surface "Contain"?
When "examined" or otherwise described, CONTAINERS will describe their contents as well (unless programmed not to do so) with the default message, "The <CONTAINER> contains <its contents>." So if the player were for example to "put the remote on the table", this would be the result:
> x the table
It's an ordinary table, set conveniently by your chair.
> put the remote on the table
Done.
> x the table
It's an ordinary table, set conveniently by your chair. The table contains a remote control.
We can change the "contains" message to better fit the table, which after all is a surface. To do this, we add a HEADER statement.
...
THE table Isa OBJECT AT tv_room
CONTAINER
HEADER
"Resting on the table is"
DESCRIPTION
VERB examine
DOES ONLY
"It's an ordinary table, set conveniently by your chair."
END VERB.
VERB put_on
WHEN obj2
DOES ONLY
LOCATE obj1 IN table.
"You set" Say The obj1. "on the table.""
END VERB.
VERB put_in
WHEN obj2
CHECK
"There are no drawers in the table to put anything in."
END VERB.
END THE table.
...
Which gives the desired result:
> x the table
It's an ordinary table, set conveniently by your chair. Resting on the table is a remote control.