1
<HTML><HEAD><TITLE>Section 9: Actions and reactions</TITLE></HEAD>
2
<BODY BGCOLOR="#FFFFFF">
5
<TR><TD Valign="top"><A HREF="contents.html">Contents</A><BR><A HREF="section8.html">Back</A><BR><A HREF="chapter4.html">Forward</A><TD bgcolor="#F5DEB3"><BLOCKQUOTE><H3>9. Actions and reactions</H3></BLOCKQUOTE><TR><TD><TD>
9
<BR>Only the actions of the just
10
<BR>Smell sweet and blossom in their dust.
11
<BR><P>...James Shirley (<B>1594</B>--<B>1666</B>), <I>The Contention of Ajax and Ulysses</I></BLOCKQUOTE>
13
...a language obsessed with action, and with the joy of seeing
14
action multiply from action, action marching relentlessly ahead
15
and with yet more actions filing in from either side to fall into
16
neat step at the rear, in a long straight rank of cause and
17
effect, to what will be inevitable, the only possible end.
18
<P>...Donna Tartt, <I>The Secret History</I></BLOCKQUOTE>
22
Inform is a language obsessed with actions. An 'action' is an attempt
23
to perform one simple task: for instance,
26
<TT>Take sword</TT> <BR>
27
<TT>Insert gold_coin cloth_bag</TT> <BR>
30
are all examples. Here the actual actions are <TT>Inv</TT>, <TT>Take</TT> and
31
<TT>Insert</TT>. An action has 0, 1 or 2 objects supplied
32
with it (or, in a few special cases, some numerical information rather than
33
objects). Most actions are triggered off by the game's parser: in fact,
34
the parser's job can be summed up as reducing the player's keyboard
35
commands to actions. Sometimes one action causes another; a really
36
complicated keyboard command ("empty the sack into the umbrella stand'')
37
may fire off quite a sequence of actions.
40
An action is only an attempt to do something: it may not succeed.
41
Firstly, a <TT>before</TT> rule might interfere, as we have seen already.
42
Secondly, the action might not even be very sensible. The parser will
43
happily generate the action <TT>Eat iron_girder</TT> if the player asked to do
44
so in good English. In this case, even if no <TT>before</TT> rule interferes,
45
the normal game rules will ensure that the girder is not consumed.
48
Actions can also be generated by your own code, and this perfectly
49
simulates the effect of a player typing something. For example,
50
generating a <TT>Look</TT> action makes the game produce a room description
51
as if the player had typed "look''. More subtly, suppose the air
52
in the Pepper Room causes the player to sneeze each turn and drop
53
something at random. This could be programmed directly, with objects
54
being moved onto the floor by explicit <TT>move</TT> statements. But then
55
suppose the game also contains a toffee apple, which sticks to the
56
player's hands. Suddenly the toffee apple problem has an unintended
57
solution. So rather than moving the objects directly to the floor,
58
the game should generate <TT>Drop</TT> actions. The result might read:
60
You sneeze convulsively, and lose your grip on the toffee apple...<BR>
61
The toffee apple sticks to your hand!<BR>
64
which is at least consistent.
67
As an example of causing actions, an odorous <TT>low_mist</TT> will soon settle over
68
'Ruins'. It will have the <TT>description</TT> "The mist carries a
69
rich aroma of broth.'' The alert player who reads this will immediately
70
type "smell mist'', and we want to provide a better response than the game's
71
stock reply "You smell nothing unexpected.'' An economical way of doing this
72
is to somehow deflect the action <TT>Smell low_mist</TT> into the action
73
<TT>Examine low_mist</TT> instead, so that the "aroma of broth'' message is
74
printed in this case too. Here is a suitable <TT>before</TT> rule to do that:
76
Smell: <Examine self>; rtrue;
79
The statement <TT><Examine self></TT> causes the action <TT>Examine low_mist</TT> to be
80
triggered off immediately, after which whatever was going on at the time
81
resumes. In this case, the action <TT>Smell low_mist</TT> resumes, but since we
82
immediately return <TT>true</TT> the action is stopped dead.
85
Causing an action and then returning <TT>true</TT> (i.e., causing a new action
86
and killing the old one) is so useful that it has an abbreviation,
87
putting the action in double angle-brackets. For example,
89
<Look>; <<ThrowAt smooth_stone spider>>;
92
will behave as if the player has asked to look around and to throw
93
the stone at the spider, and will then return <TT>true</TT>.
97
At any given time, just one action is under way (though others
98
may be waiting to resume when the current one has finished). This
99
current action is stored in the three variables
104
<TT>noun</TT> and <TT>second</TT> hold the objects involved, or the special
105
value <TT>nothing</TT> if they aren't involved at all. <TT>action</TT> holds
106
the kind of action. Its possible values can be referred to in
107
the program using the <TT>##</TT> notation: for example
109
if (action == ##Look) ...
112
tests to see if the current action is a <TT>Look</TT>.
115
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> Why have <TT>##</TT> at all, why not just write <TT>Look</TT>? Partly
116
because this way the reader can see at a glance that an action
117
type is being referred to, but also because the name might be
118
wanted for something else. For instance there's a variable called
119
<TT>score</TT> (holding the current game score), quite different from
120
the action type <TT>##Score</TT>.
124
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> For a few actions, the 'noun' (or the 'second noun') is
125
actually a number (for instance, "set timer to 20'' would probably
126
end up with <TT>noun</TT> being <TT>timer</TT> and <TT>second</TT> being 20). Occasionally
127
one needs to be sure of the difference, e.g., to tell if <TT>second</TT>
128
is holding a number or an object. It's then useful to know that
129
there are two further variables, <TT>inp1</TT> and <TT>inp2</TT>, parallel to
130
<TT>noun</TT> and <TT>second</TT> and usually equal to them -- but equal to 1 to
131
indicate "some numerical value, not an object''.
137
The library supports about 120 different actions and any game of serious
138
proportion will add some more of its own. This list is initially daunting
139
but many are used only rarely and others are always knocked down into
140
simpler actions (for example, <TT><Empty rucksack table></TT>, meaning
141
"empty the contents of the rucksack onto the table'', is broken down into
142
a stream of actions like <TT><Remove fish rucksack></TT> and <TT><PutOn fish table></TT>).
143
It's useful to know that an object can only enter the player's possession
144
through a <TT>Take</TT> or <TT>Remove</TT> action: block those two and it can never be
145
acquired whatever the player types.
148
The list of actions is traditionally divided into three groups, called
149
Group 1, Group 2 and Group 3.
150
Group 1 contains 'meta' actions for controlling the game, like <TT>Score</TT>
151
and <TT>Save</TT>, which are treated quite differently from other actions and
152
are not worth listing. Of the rest, actions which normally do something
153
form Group 2, while actions which normally only print a polite refusal
154
form Group 3. Group 2 contains:
156
Inv, Take, Drop, Remove, PutOn, Insert, Enter, Exit, Go, Look, Examine,
157
Unlock, Lock, SwitchOn, SwitchOff, Open, Close, Disrobe, Wear, Eat, Search.
160
It should be apparent why these do something. However, an action
161
like <TT>Listen</TT> falls into Group 3: the library would normally respond
162
to it by printing "You hear nothing unexpected.'' Only if your program
163
interferes (using a <TT>before</TT> rule) can anything happen. Group 3 contains,
164
in rough order of usefulness:
166
Pull, Push, PushDir [push object in direction], Turn,
167
Consult, LookUnder [look underneath something], Search,
168
Listen, Taste, Drink, Touch, Smell,
169
Wait, Sing, Jump [jump on the spot], JumpOver, Attack,
170
Swing [something], Blow, Rub, Set, SetTo, Wave [something],
171
Burn, Dig, Cut, Tie, Fill, Swim, Climb, Buy, Squeeze,
172
Pray, Think, Sleep, Wake, WaveHands [i.e., just "wave"],
173
WakeOther [person], Kiss, Answer, Ask, ThrowAt,
174
Yes, No, Sorry, Strong [swear word], Mild [swear word]
178
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> Actions involving other people, like <TT>Kiss</TT>, are often best
179
dealt with by a <TT>life</TT> rule, which will be discussed in <A HREF="section16.html">Section 16</A>.
183
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> A few actions (e.g., <TT>Transfer</TT>, <TT>Empty</TT>, <TT>GetOff</TT>) are omitted
184
from the list above because they're always translated into more familiar
185
ones. For instance, <TT>InvWide</TT> (asking for a "wide--format'' inventory
186
listing) always ends up in an <TT>Inv</TT>.
190
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> The <TT>Search</TT> action (generated by "look inside <I><B><container></B></I>''
191
or "search <I><B><something></B></I>'') only ever prints text, but is in Group 2
192
rather than Group 3 because it does something substantial. It decides
193
whether something is a container, and if there's enough light to see by,
194
it prints out the contents. Thus, a <TT>before</TT> rule applied to <TT>Search</TT>
195
traps the searching of random scenery, while an <TT>after</TT> can be used
196
to alter the contents-listing rules of containers.
200
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> Most of the group 2 actions -- specifically,
202
Take, Drop, Insert, PutOn, Remove, Enter, Exit, Go, Unlock, Lock,
203
SwitchOn, SwitchOff, Open, Close, Wear, Disrobe, Eat
206
can happen "silently''. If the variable <TT>keep_silent</TT> is set to 1,
207
then these actions print nothing in the event of success. (E.g.,
208
if the door was unlocked as requested.) They print up objections
209
as usual if anything goes wrong (e.g., if the suggested key doesn't
210
fit). This is useful to implement implicit actions: for instance,
211
to code a door which will be automatically unlocked by a player
212
asking to go through it, who is holding the right key.
218
The standard stock of actions is easily added to. Two things are
219
necessary to create a new action: first one must provide a routine
220
to make it happen. For instance:
223
"You speak the magic word ~Blorple~. Nothing happens.";
227
Every action has to have a "subroutine'' like this, the name of which
228
is always the name of the action with <TT>Sub</TT> appended. Secondly,
229
one must add grammar so that <TT>Blorple</TT> can actually be called for.
230
Far more about grammar in Chapter V: for now we add the simplest of
231
all grammar lines, a directive
233
Verb "blorple" * -> Blorple;
236
placed after the inclusion of the <TT>Grammar</TT> file. (The spacing around
237
the <TT>*</TT> is just a matter of convention.) The word "blorple" can now
238
be used as a verb. It can't take any nouns, so the parser will complain
239
if the player types "blorple daisy''.
242
<TT>Blorple</TT> is now a typical Group 3 action. <TT>before</TT> rules can be
243
written for it, and it can be triggered off by a statement like
249
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> To make it a Group 1 action, define the verb as <TT>meta</TT> (see <A HREF="section26.html">Section 26</A>).
253
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> To make it a Group 2 action, rewrite the subroutine in the
257
... do whatever the action is supposed to do,
258
printing a suitable message and returning
259
if it turns out not to be a sensible thing to do...
260
if (AfterRoutines()==1) rtrue;
261
... print a suitable message saying that it has been done ...
265
(<TT>AfterRoutines</TT> is a library routine which sends suitable <TT>after</TT>
266
messages to see if the objects want to prevent the usual message
271
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> A few of the library's actions fall into none of Groups 1,
272
2 or 3, though these aren't proper actions at all, but are used
273
only to signal goings-on. For instance, when the player types
274
"throw rock at dalek'', the parser generates the action
275
<TT>ThrowAt rock dalek</TT>. As usual the rock is sent a <TT>before</TT> message
276
asking if it objects to being thrown at a Dalek. Since the Dalek
277
may also have an opinion on the matter, another <TT>before</TT> message
278
is sent to the Dalek, but this time as if the action were something
279
called <TT>ThrownAt</TT>. For example, here is a dartboard's response to a
283
[; ThrownAt: if (noun==dart)
284
{ move dart to self; "Triple 20!"; }
285
move noun to location;
286
print_ret (The) noun, " bounces back off the board.";
290
Such an imaginary action -- usually, as in this case, a perfectly
291
sensible action seen from the point of view of the second object
292
involved, rather than the first -- is called a "fake action''.
293
The important ones are <TT>ThrownAt</TT>, <TT>Receive</TT> and <TT>LetGo</TT>
294
(the latter two being used for containers: see <A HREF="section11.html">Section 11</A>).
298
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> If you really need to, you can declare a new fake action
299
with the directive <TT>Fake_action</TT> <I><B><Action-name></B></I><TT>;</TT>.
303
<P><TR><TD Valign="top"><IMG SRC="icons/ddexercise.gif" ALT="??/\/\"><TD bgcolor="#FBB9AC"><A NAME="ex3"><B>EXERCISE 3:</B><BR>(link to <A HREF="answers1/answer3.html">the answer</A>)<TR><TD><TD> <TT>ThrownAt</TT> would be unnecessary if Inform had an
304
idea of <TT>before</TT> and <TT>after</TT> routines which an object could provide if
305
it were the <TT>second</TT> noun of an action. How might this be
313
Actions are processed in a simple way, but one which involves many
314
little stages. There are three main stages:
317
<P>(a) -- 'Before'. An opportunity for your code to interfere with
318
or block altogether what might soon happen.
319
<P>(b) -- 'During'. The library takes control and decides if the
320
action makes sense according to its normal world model: for example,
321
only an <TT>edible</TT> object may be eaten; only an object in the
322
player's possession can be thrown at somebody, and so on. If the
323
action is impossible, a complaint is printed and that's all.
324
Otherwise the action is now carried out.
325
<P>(c) -- 'After'. An opportunity for your code to react to what
326
has happened, after it has happened but before any text announcing
327
it has been printed. If it chooses, your code can print and cause
328
an entirely different outcome. If your code doesn't interfere,
329
the library reports back to the player (with such choice phrases as
333
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> Group 1 actions (like <TT>Score</TT>) have no 'Before' or
334
'After' stages: you can't (easily) stop them from taking place.
335
They aren't happening in the game's world, but in the player's.
339
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The 'Before' stage consults your code in five ways, and
340
occasionally it's useful to know in what order:
341
<TR><TD><TD bgcolor="#EEEEEE"><SMALL>
342
<P>i. -- The <TT>GamePreRoutine</TT> is called, if you have written one.
343
If it returns 'true',
344
nothing else happens and the action is stopped.
345
<P>ii. -- The <TT>orders</TT> property of the player is called on the
346
same terms. For more details, see <A HREF="section16.html">Section 16</A>.
347
<P>iii. -- And the <TT>react_before</TT> of every object in scope
348
(which roughly means 'in the vicinity').
349
<P>iv. -- And the <TT>before</TT> of the current room.
350
<P>v. -- If the action has a first noun, its <TT>before</TT> is called
351
on the same terms.</SMALL><TR><TD><TD>
355
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The library processes the 'During' stage by calling
356
the action's subroutine. (Subroutines like <TT>TakeSub</TT> make up
357
a large part of the library.)
361
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL> The 'After' stage only applies to Group 2 actions, as
362
all Group 3 actions have been packed up at the 'During' stage
363
if not 'Before'. During 'After' the sequence is as follows:
364
<TT>react_after</TT> rules for every object in scope (including the
365
player object); the room's <TT>after</TT>; the first noun's <TT>after</TT>
366
and finally <TT>GamePostRoutine</TT>.
370
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> Two things are fake about "fake actions'' (see above):
371
they don't have subroutines, and they never occur in the grammar
372
of any verb (so they're never directly generated by the parser).
376
<P><TR><TD Valign="top"><IMG SRC="icons/dbend.gif" ALT="/\"><TD bgcolor="#EEEEEE"><SMALL>
377
As mentioned above, the parser can generate very peculiar actions,
378
and this sometimes needs to be remembered when writing <TT>before</TT>
379
rules. Suppose a <TT>before</TT> rule intercepts the action of putting
380
the mushroom in the crate, and makes something exciting happen
381
as a result. Now even if the mushroom is, say, sealed up inside
382
a glass jar, the parser might still generate this action: the
383
impossibility won't be realised until 'During' time. So the
384
exciting happening should be written as an <TT>after</TT> rule, when the
385
attempt to put the mushroom in the crate has already succeeded.
389
<P><TR><TD Valign="top"><IMG SRC="icons/dexercise.gif" ALT="??/\"><TD bgcolor="#FBB9AC"><A NAME="ex4"><B>EXERCISE 4:</B><BR>(link to <A HREF="answers1/answer4.html">the answer</A>)<TR><TD><TD> This kind of snag could be avoided altogether if Inform
390
had a 'validation stage' in action processing, to check whether an action is
391
sensible before allowing it to get as far as <TT>before</TT> rules. How could
392
this be added to Inform?
396
<P><TR><TD Valign="top"><IMG SRC="icons/ddbend.gif" ALT="/\/\"><TD bgcolor="#EEEEEE"><SMALL> To some extent you can even meddle with the 'During' stage
397
(and with the final messages produced), and thus even interfere with
398
Group 1 actions if you are unscrupulous enough, by cunning use of the
399
<TT>LibraryMessages</TT> system. See <A HREF="section21.html">Section 21</A>.
403
<P><TR><TD Valign="top"><IMG SRC="icons/refs.gif" ALT="*"><TD bgcolor="#EEEEEE"><B>REFERENCES:</B><BR><SMALL>
404
In a game compiled with the <TT>-D</TT> switch set, typing in the "actions''
405
verb will result in trace information being printed each time any
406
action is generated. Try putting many things into a rucksack and
407
asking to "empty'' it for an extravagant list.
409
Diverted actions (using <TT><<</TT> and <TT>>></TT>) are commonplace. They're used
410
in about 20 places in 'Advent': a good example is the way "take water''
411
is translated into a <TT>Fill bottle</TT> action.
413
Sometimes you want "fake fake actions'' which are fully--fledged
414
actions (with action routines and so on) but are still never generated
415
by the parser (see <A HREF="section16.html">Section 16</A>).
417
<HR><A HREF="contents.html">Contents</A> / <A HREF="section8.html">Back</A> / <A HREF="chapter4.html">Forward</A> <BR>
418
<A HREF="chapter1.html">Chapter I</A> / <A HREF="chapter2.html">Chapter II</A> / <A HREF="chapter3.html">Chapter III</A> / <A HREF="chapter4.html">Chapter IV</A> / <A HREF="chapter5.html">Chapter V</A> / <A HREF="chapter6.html">Chapter VI</A> / <A HREF="chapterA.html">Appendix</A><HR><SMALL><I>Mechanically translated to HTML from third edition as revised 16 May 1997. Copyright © Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.</I></SMALL></BODY></HTML>