Chapter 4: Items

Items are objects that can be picked up by the player:

#bowl
(name *)small bowl
(descr *)It's a small bowl.
(item *)%% This is what allows the player to pick up the bowl.
(* is #on #table)
[Copy to clipboard]

Pristine and handled objects

As a general rule, the standard library doesn't call attention to game objects. The story author is expected to mention them as part of the description of their parent object (such as the room).

But there is an important exception: As soon as the player picks up an object (or otherwise moves it from its original location), the responsibility for mentioning that object is transferred to the library. We say that the object has become handled or, equivalently, that it is no longer pristine.

There's a compelling pragmatic reason for this: When players are able to move objects around, those objects will eventually end up in strange locations, unanticipated by the story author. Players will put the flower pot on top of the bed, or take off their clothes and put them inside the ashtray, and the story author cannot be expected to provide custom text for every combination the player can think of. So, once objects start moving around, the library takes over the initiative in calling attention to them, using bland, default messages. They story author may then choose to override those messages on a case-by-case basis, and we will soon see how that's done in practice.

For now, the important thing to remember is that items (and wearable objects) can move around, and therefore we should only call them out in room descriptions (and in the descriptions of containers and supporters) when they are in their pristine state. Whenever we include a movable object in our story, we have a responsibility to check this. It can be done with an if-statement as in the following example:

#bowl
(name *)small bowl
(descr *)It's a small bowl.
(item *)
(* is #on #table)
(descr #table)
It's wooden; possibly mahogany.
(if) (#bowl is pristine) (then)
A small bowl is placed exactly in its centre.
(endif)
[Copy to clipboard]

Non-movable objects will remain pristine forever, so they can be described without a check.

Here is a complete example game with movable objects:

(current player #player)
#room
(name *)tutorial room
(room *)
(#player is #in *)
(look *)This is a very nondescript room, dominated by a
wooden table. (notice #table)
#table
(name *)wooden table
(dict *)mahogany  %% Add a synonym.
(supporter *)
(* is #in #room)
(descr *)It's wooden; possibly mahogany.
(if) (#bowl is pristine) (then)
A small bowl is placed exactly in its centre.
(endif)
#sapphire
(name *)sapphire
(stone *)%% This is a custom, story-specific trait.
#amethyst
(an *)%% The indefinite article should be 'an'.
(name *)amethyst
(stone *)
#bowl
(name *)small bowl
(item *)
(container *)
(* is #on #table)
(descr *)It's a small bowl.
%% Some generic properties of stones:
(item (stone $))
((stone $) is #in #bowl)
(descr (stone $Obj))
(The $Obj) looks very pretty.
(dict (stone $))
precious stone gem
(plural dict (stone $))
stones
[Copy to clipboard]

Try it! You might want to LOOK, X TABLE, LOOK IN BOWL, GET ALL, PUT STONE IN BOWL, PUT STONE ON TABLE, DROP ALL...

Plural forms

(dict $) and (plural dict $) can be used to add synonyms to objects. In the example above, we added both singular and plural synonyms to all objects belonging to the (stone $) category. A command such as GET STONES will result in every stone being picked up, due to the plural form. In contrast, GET STONE triggers a disambiguating question, where the game asks the player whether they meant to pick up the amethyst or the sapphire.

Appearance

You may have noticed a problem with the last example: When the player examines the bowl, there is no mention of the stones within. For an oldschool game, it may be acceptable to expect the player to SEARCH or LOOK IN the bowl in order to find them. But for modern, narrative-driven games, that approach is generally frowned upon. We could mention the stones in the description of the bowl. But there are two stones, so how do we do that? Do we check whether they are both pristine? I.e.:

(descr #bowl)
It's a small bowl.
(if)
(#sapphire is pristine)
(#amethyst is pristine)
(then)
There are two precious stones in it.
(endif)
[Copy to clipboard]

But what if the player only picks up the amethyst, and then puts it back? The sapphire is still in the bowl, but the story doesn't mention it, and the library only prints a stock message about the amethyst (because it is no longer pristine). Another option is to add lots of special cases:

(descr #bowl)
It's a small bowl.
(if)
(#sapphire is pristine)
(#amethyst is pristine)
(then)
There are two precious stones in it.
(elseif)
*($Stone is one of [#sapphire #amethyst])
($Stone is pristine)
(then)
There's (a $Stone) in it.
(endif)
[Copy to clipboard]

But this doesn't scale well, if there were more than two precious stones in the bowl to begin with. We also have the option to cop out entirely, and tell the library to narrate these objects already from the start:

(descr #bowl)
It's a small bowl.
(#sapphire is handled)
(#amethyst is handled)
[Copy to clipboard]

Remember, handled is the opposite of pristine in this context. Now, when the player first examines the bowl, the game responds:

It's a small bowl.

An amethyst is in the small bowl.

A sapphire is in the small bowl.

But that's decidedly clunky. A somewhat better approach, although still a cop-out, is to print a vague message that encourages the player to look inside the bowl, without mentioning any details about what's inside:

(descr #bowl)
It's a small bowl.
(if) ($ is #in #bowl) (then)
There appears to be something inside.
(endif)
[Copy to clipboard]

But this will backfire, in a sense, if the player takes the amethyst and then puts it back. Examining the bowl would then result in the following output:

It's a small bowl. There appears to be something inside.

An amethyst is in the small bowl.

Here, the library called attention to the amethyst (handled), but not to the sapphire (pristine). The printed text is technically correct, but while the first paragraph encourages the player to look inside the bowl, the second paragraph takes that incentive away, and the player is mislead to believe that there's nothing in the bowl apart from the amethyst.

Instead, the recommended way to handle this situation is to selectively override the appearance text that's printed for handled objects by the library. The message “An amethyst is in the small bowl” originates from a predicate called (appearance $Object $Relation $Parent). The first step is to tell the library to refrain from printing such a message about any object that's currently in the bowl:

(appearance $ #in #bowl)
%% Objects in the bowl have a blank appearance.
[Copy to clipboard]

Now that we have silenced those particular messages from the standard library, we must provide our own variant in the description of the bowl. But we have to be careful: With the rule above, we turned off automatic descriptions for any object in the bowl, not just the amethyst and the sapphire. So we have to take care of any foreign objects that might end up there too. In some situations, it might be sufficient to drop a vague hint:

(descr #bowl)
It's a small bowl.
(if) ($ is #in #bowl) (then)
There appears to be something inside.
(endif)
(appearance $ #in #bowl)
[Copy to clipboard]

A more advanced technique is to use a multi-query and a collect statement to print a list of all objects currently inside the bowl:

(descr #bowl)
It's a small bowl.
(collect $Obj)
*($Obj is #in #bowl)
(into $List)
You can see (a $List) in it.
(appearance $ #in #bowl)
[Copy to clipboard]

An entirely different approach is to allow objects to call attention to themselves, but to replace the stock message with a custom one. This is done by overriding (appearence $ $ $) with a rule that prints text:

#sapphire
(appearance * $ $)
(* is handled)
A gleaming sapphire catches your eye.
(notice *)  %% Bind “it”
[Copy to clipboard]

That rule did not check the location of the sapphire, so it would override the default message also when the sapphire makes an appearance as part of a room description, or in any other place. Without the line (* is handled), the message would also be printed while the object is still pristine.

To summarize, movable items are more complicated than other objects, because there is a transfer of responsibility for calling attention to them. At first, while they are pristine, the story author should mention them as a natural part of the prose describing nearby objects (e.g. the room). As soon as they are handled, the library takes over, unless the story author explicitly reclaims control over their appearance.