§6.15. Actions on Multiple Objects
Inform allows a handful of actions - TAKE, DROP, PUT, INSERT - to apply to more than one item at a time, so that the player can move things around easily.
The general principle is that multiple objects are allowed if the actions are likely to be successful but not interesting most of the time, and if they're things that the player could plausibly do all at once. For most actions, the use of ALL would seem weirdly indiscriminate: EAT ALL, say, describes very implausible behavior, and EXAMINE ALL would likely generate a screenful of text at once.
But this is all under our control. To create an action that uses multiples, or to allow the use of multiple objects with an already-existing action, we need to create an understand statement that uses the "[things]" token (note the plural). For instance:
Understand "give [things] to [someone]" as giving it to.
This would let the existing give action apply to multiple objects, in just the same way that "take" does. Shawn's Bad Day demonstrates how we might allow EXAMINE ALL to print descriptions of every visible item.
Alternatively, we could generate a new action:
Understand "give [things] to [someone]" as multiply-giving it to. Multiply-giving it to is an action applying to one carried thing and one thing.
(In theory the language here should perhaps be "several carried things" -- but Inform is still going to process multiply-giving item by item, unless we redirect it. More about this in a moment.)
When handling an action that uses the "[things]" token, the parser makes a list of every item to which it is going to apply the action: this is called the multiple objects list. The multiple objects list can be the result of a vague request (GET ALL) or a specific one involving identical multiples (GET PENNIES, GET THREE APPLES) or a very specific one involving unique, named nouns (GET GERBIL, APPLE, AND POMEGRANATE).
We can manipulate what Inform includes in "ALL" in sentences like TAKE ALL with the "deciding whether all includes..." activity; for instance
Rule for deciding whether all includes scenery: it does not.
prevents TAKE ALL from applying to things that can't be moved anyway, avoiding lots of lines like
tree: That's hardly portable.
swing set: That's hardly portable.
A slightly tedious technical note: the multiple objects list is not strictly a list in the standard Inform sense, because it is used so frequently in parsing that it would be cumbersome to handle it with the more flexible but less efficient structure used for lists. However, if we want to manipulate the multiple objects list as though it were an ordinary list -- that is, sort it, rotate it, truncate it, remove entries from it, etc -- we may do so by creating a list like this:
let L be the multiple object list.
and later after making L conform to our desires:
alter the multiple object list to L.
Inform next repeatedly runs the action rulebook for the action generated, using each item from the multiple object list as "noun" in turn (or as "second noun", if that's where the [things] token appeared in the understand line). Since it is possible to alter the multiple object list before the "generate action rule" portion of the turn sequence consults the rulebooks, we can also affect the order in which the player's matched objects are handled; see Formicidae. We should not attempt to change the multiple object list after this point, because this is likely to introduce bugs.
Each time Inform tries the action on a new noun, it prefixes the action-attempt with the name of the item it's currently working on. This is where we get such output as "frog eyeballs:" and "newt toes:" in long lists like
frog eyeballs: Taken.
newt toes: Taken.
These names are generated by the "announce items from multiple object lists rule" in the action-handling rules; Escape from the Seraglio shows how to alter them. In the context of this rule, the thing we are currently printing the name of can be called "the current item from the multiple objects list".
Suppressing names of objects entirely, while occasionally tempting, may have unintended consequences, especially if some of the attempted actions are prevented by check rules that themselves print things. It is safest to suppress the multiple object names in the case where we already know that the action will succeed wherever it is attempted (more often for observational actions like examining than for manipulative actions like taking, or where we mean to completely override default handling).
Given that our hypothetical "multiply-giving" applies to each given object in turn, it might seem to be useless to create "multiply-giving" as an action different from "giving" -- but the convenience is that manipulating the multiple object list makes it possible to group behavior artificially. The trick here is that, on the first pass of the multiply-giving rulebook, we look at the entire multiple object list, perform actions, print output, and set a flag saying that the action has been handled. The flag tells Inform not to do or print anything for any of the subsequent passes through that action rulebook; thus we artificially create a situation where, instead of performing an action on each object in turn, Inform acts once on the entire group. That allows us to assess the cumulative qualities of the group and have the action respond differently than it might when assessing each item individually.
The Facts Were These demonstrates how we might write an action for GIVE THREE DOLLARS TO MAN or GIVE PIE AND HAT TO MAN where the man would only accept the collective gift when its total proved satisfactory.
See Examining for groups of objects that have a collective description different from their individual descriptions, and for commands that search multiple things at once
See Dispensers and Supplies of Small Objects for ways to let the player pick up a number of identical items from a dispenser or supply
![]() | Start of Chapter 6: Commands |
![]() | Back to §6.14. Remembering, Converting and Combining Actions |
![]() | Onward to §6.16. Alternate Default Messages |
|
|
Suppose we have an item that produces an interesting result the first time the player lifts it -- a rock with dangerous ants revealed underneath. The effect of the surprise is a little weakened, though, if the player sees that response as the result of a TAKE ALL, when it might be printed like this:
The calm response to "rusty nail" looks odd now, and the score change is disconnected from the event that caused it. To manage this, we might institute a system so that interesting objects are handled last in their list, like so:
Note that while one could also manipulate the object list to add or remove items at this stage, there's a simpler way to control what Inform considers "ALL" to mean in commands: see the activity "Deciding whether all includes" in the activities chapter. |
|
Suppose we have an item that produces an interesting result the first time the player lifts it -- a rock with dangerous ants revealed underneath. The effect of the surprise is a little weakened, though, if the player sees that response as the result of a TAKE ALL, when it might be printed like this:
The calm response to "rusty nail" looks odd now, and the score change is disconnected from the event that caused it. To manage this, we might institute a system so that interesting objects are handled last in their list, like so:
Note that while one could also manipulate the object list to add or remove items at this stage, there's a simpler way to control what Inform considers "ALL" to mean in commands: see the activity "Deciding whether all includes" in the activities chapter. |
|