1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4
<title>DM4 §6: Actions and reactions</title>
5
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6
<link rel="stylesheet" type="text/css" href="dm4.css">
10
<a href="index.html">home</a> /
11
<a href="contents.html">contents</a> /
12
<a href="ch2.html" title="Chapter II: Introduction to Designing">chapter II</a> /
13
<a href="s5.html" title="§5: Introducing messages and classes">prev</a> /
14
<a href="s7.html" title="§7: Infix and the debugging verbs">next</a> /
15
<a href="dm4index.html">index</a>
18
<a id="p97" name="p97"></a>
19
<h2>§6 Actions and reactions</h2>
21
<blockquote>Only the actions of the just<br>
22
Smell sweet and blossom in their dust.<br>
23
— James Shirley (1594–1666),<br>
24
<span style="color:white">—</span> <i>The Contention of Ajax and Ulysses</i>
27
<blockquote>[Greek is] a language obsessed with action, and with
28
the joy of seeing action multiply from action, action marching
29
relentlessly ahead and with yet more actions filing in from either
30
side to fall into neat step at the rear, in a long straight rank
31
of cause and effect, to what will be inevitable, the only possible end.<br>
32
— Donna Tartt, <i>The Secret History</i></blockquote>
34
<p class="normal"><span class="atleft"><img src="dm4-097_1.jpg" alt=""></span>
35
Inform is a language obsessed with actions. An
36
‘action’ is an attempt to perform one simple task: for
39
<p class="lynxonly"></p>
40
<pre class="code">Inv Take sword Insert gold_coin cloth_bag</pre>
42
<p class="normal">are all examples. Here the actual actions are
43
<code>Inv</code> (inventory), <code>Take</code> and <code>Insert</code>.
44
An action has none, one or two objects supplied with it (or, in a few
45
special cases, some numerical information rather than objects). It also
46
has an “actor”, the person who is to perform the action, usually
47
the player. Most actions are triggered off by the game's parser, whose
48
job can be summed up as reducing the player's keyboard commands to
49
actions: “take my hat off”, “remove bowler”
50
or “togli il cappello” (if in an Italian game) might all
51
cause the same action. Some keyboard commands, like “drop
52
all”, cause the parser to fire off whole sequences of actions:
53
others, like “empty the sack into the umbrella stand”,
54
cause only a single action but one which may trigger off an avalanche
55
of other actions as it takes place.</p>
57
<p class="indent">An action is only an attempt to do something: it may
58
not succeed. Firstly, a <code>before</code> rule might interfere,
59
as we have seen already. Secondly, the action might not even be very
60
sensible. The parser will happily generate the action <code>Eat
61
iron_girder</code> if the player asked to do so in good English. In
62
this case, even if no <code>before</code> rule interferes, the normal
63
game rules will ensure that the girder is not consumed.</p>
65
<p class="indent">Actions can also be generated by your own code, and
66
this perfectly simulates the effect of a player typing something. For
68
<a id="p98" name="p98"></a>
69
a <code>Look</code> action makes the game produce
70
a room description as if the player had typed “look”.
71
More subtly, suppose the air in the Pepper Room causes the player to
72
sneeze each turn and drop something at random. This could be programmed
73
directly, with objects being moved onto the floor by explicit move
74
statements. But then suppose the game also contains a toffee apple,
75
which sticks to the player's hands. Suddenly the toffee apple problem
76
has an unintended solution. So rather than moving the objects directly
77
to the floor, the game should generate <code>Drop</code> actions,
78
allowing the game's rules to be applied. The result might read:</p>
80
<p class="output">You sneeze convulsively, and lose your grip on
81
the toffee apple…<br>The toffee apple sticks to your hand!</p>
83
<p class="normal">which is at least consistent.</p>
85
<p class="indent">As an example of causing actions, an odorous <code>low_mist</code>
86
will soon settle over ‘Ruins’. It will have the description
87
“The mist carries an aroma reminisicent of tortilla.”
88
The alert player who reads this will immediately type “smell
89
mist”, and we want to provide a better response than the game's
90
stock reply “You smell nothing unexpected.” An
91
economical way of doing this is to somehow deflect the action <code>Smell
92
low_mist</code> into the action <code>Examine low_mist</code>
93
instead, so that the “aroma of tortilla” message is printed
94
in this case too. Here is a suitable <code>before</code> rule to
97
<p class="lynxonly"></p>
98
<pre class="code">Smell: <Examine self>; rtrue;</pre>
100
<p class="normal">The statement <Examine self> causes the
101
action <code>Examine low_mist</code> to be triggered off immediately,
102
after which whatever was going on at the time resumes. In this case,
103
the action <code>Smell low_mist</code> resumes, but since we
104
immediately return <code>true</code> the action is stopped dead.</p>
106
<p class="indent">Causing an action and then returning <code>true</code> is
107
so useful that it has an abbreviation, putting the action in double
108
angle-brackets. For example, the following could be added to ‘Ruins’
109
if the designer wanted to make the stone-cut steps more enticing:</p>
111
<p class="lynxonly"></p>
114
Search: <<Enter self>>;
118
<p class="normal">If a player types “search steps”, the
119
parser will produce the action <code>Search steps</code> and
120
this rule will come into play: it will generate the action <code>Enter
121
steps</code> instead, and return <code>true</code> to stop the original
122
<code>Search</code> action from going any further. The net effect is
123
that one action has been diverted into another.</p>
125
<a id="p99" name="p99"></a>
126
<p class="dotbreak">� � � � �</p>
128
<p class="normal">At any given time, just one action is under way,
129
though others may be waiting to resume when the current one has finished.
130
The current action is always stored in the four variables</p>
132
<p class="lynxonly"></p>
133
<pre class="code">actor action noun second</pre>
135
<p class="normal"><code>actor</code>, <code>noun</code> and
136
<code>second</code> hold the objects involved, or the special value
137
<code>nothing</code> if they aren't involved at all. (There's always
138
an <code>actor</code>, and for the time being it will always be equal
139
to <code>player</code>.) <code>action</code> holds the kind of action.
140
Its possible values can be referred to in the program using the
141
<code>##</code> notation: for example</p>
143
<p class="lynxonly"></p>
144
<pre class="code">if (action == ##Look) ...</pre>
146
<p class="normal">tests to see if the current <code>action</code> is a
147
<code>Look</code>.</p>
149
<p class="aside"><span class="warning">▲</span>
150
Why have <code>##</code> at all, why not just write <code>Look</code>?
151
Partly because this way the reader of the source code can see at a
152
glance that an action type is being referred to, but also because
153
the name might be used for something else. For instance there's a
154
variable called <code>score</code> (holding the current game score),
155
quite different from the action type <code>##Score</code>.</p>
157
<p class="aside"><span class="warning">▲▲</span>
158
For a few actions, the ‘noun’ (or the ‘second
159
noun’) is actually a number (for instance, “set timer to
160
20” would probably end up with <code>noun</code> being <code>timer</code> and <code>second</code>
161
being 20). Occasionally one needs to be sure of the difference, e.g.,
162
to tell if <code>second</code> is holding a number or an object. It's then useful
163
to know that there are two more primitive variables, <code>inp1</code> and <code>inp2</code>,
164
parallel to <code>noun</code> and <code>second</code> and usually equal to them – but equal
165
to 1 to indicate “some numerical value, not an object”.</p>
167
<p class="dotbreak">� � � � �</p>
169
<p class="normal">The library supports about 120 different actions
170
and most large games will add some more of their own. The full list,
171
given in <a href="tables.html#tbl6a">Table 6</a>, is initially daunting,
172
but for any given object most of the actions are irrelevant. For
173
instance, if you only want to prevent an object from entering the
174
player's possession, you need only block the <code>Take</code> action,
175
unless the object is initially in something or on something, in which
176
case you need to block <code>Remove</code> as well. In the author's
177
game ‘Curses’, one exceptional object (Austin, the cat)
178
contains rules concerning 15 different actions, but the average is
179
more like two or three action-rules per object.</p>
181
<p class="indent">The list of actions is divided into three groups,
182
called Group 1, Group 2 and Group 3:</p>
184
<a id="p100" name="p100"></a>
186
<li>Group 1 contains ‘meta’ actions for controlling
187
the game, like <code>Score</code> and <code>Save</code>, which are
188
treated quite differently from other actions as they do not
189
happen in the “model world”.</li>
190
<li>Actions in group 2 normally do something to change the state of
191
the model world, or else to print important information about it.
192
<code>Take</code> (“pick up”) and <code>Inv</code>
193
(“inventory”) are examples of each. Such actions will
194
affect any object which doesn't block them with a <code>before</code>
196
<li>Finally, group 3 actions are the ones which normally do nothing
197
but print a polite refusal, like <code>Pull</code> (“it is
198
fixed in place”), or a bland response, like <code>Listen</code>
199
(“you hear nothing unexpected”). Such actions will never
200
affect any object which doesn't positively react with a <code>before</code>
204
<p class="aside"><span class="warning">▲</span>
205
Some of the group 2 actions can be ignored by the programmer because
206
they are really only keyboard shorthands for the player. For example,
207
<code><Empty rucksack table></code> means “empty the
208
contents of the rucksack onto the table” and is automatically
209
broken down into a stream of actions like <code><Remove fish
210
rucksack></code> and <code><PutOn fish table></code>.
211
You needn't write rules concerning <code>Empty</code>, only
212
<code>Remove</code> and <code>PutOn</code>.</p>
214
<p class="aside"><span class="warning">▲▲</span>
215
Most of the library's group 2 actions are able to “run silently”.
216
This means that if the variable <code>keep_silent</code> is set to
217
<code>true</code>, then the actions print nothing in the event of
218
success. The group 2 actions which can't run silently are exactly
219
those ones whose successful operation does nothing but print:
220
<code>Wait</code>, <code>Inv</code>, <code>Look</code>,
221
<code>Examine</code>, <code>Search</code>.</p>
224
<p class="aside"><span class="warning"><b>•</b>▲
225
<b><a href="sa6.html#ans3">EXERCISE 3</a></b></span><br>
226
“The door-handle of my room… was different from all other
227
door-handles in the world, inasmuch as it seemed to open of its own
228
accord and without my having to turn it, so unconscious had its
229
manipulation become…” (Marcel Proust). Use silent-running
230
actions to make an unconsciously manipulated door: if the player tries
231
to pass through when it's closed, print “(first opening
232
the door)” and do so. (You need to know some of
233
<a href="s13.html">§13</a>, the section on doors, to answer
237
<p class="aside"><span class="warning"><b>•</b>▲▲
238
<b><a href="sa6.html#ans4">EXERCISE 4</a></b></span><br>
239
Now add “(first unlocking the door with…)”,
240
automatically trying to unlock it using either a key already known
241
to work, or failing that, any key carried by the player which hasn't
242
been tried in the lock before.</p>
244
<p class="dotbreak">� � � � �</p>
246
<p class="aside"><span class="warning">▲</span>
247
Some actions happen even though they don't arise <em>directly</em>
248
from anything the player has typed. For instance, an action called
249
<code>ThrownAt</code> is listed under group 3 in
250
<a href="tables.html#tbl6c">Table 6</a>. It's a side-effect of the ordinary
251
<code>ThrowAt</code> action: if the player types “throw rock
252
at dalek”, the parser generates the action <code>ThrowAt
253
rock dalek</code>. As usual the rock is sent a <code>before</code>
254
message asking if it objects to being thrown at a Dalek. Since
255
the Dalek may also have an opinion on the matter, another <code>before</code>
256
message is sent to the Dalek, but
257
<a id="p101" name="p101"></a>
258
this time with the action
259
<code>ThrownAt</code>. A dartboard can thus distinguish between being
260
thrown, and having things thrown at it:</p>
262
<p class="lynxonly"></p>
265
ThrowAt: "Haven't you got that the wrong way round?";
270
print (string) random("Outer bull", "Bullseye");
272
print (string) random("Single", "Double", "Triple");
273
print " ", (number) random(20);
277
move noun to location;
278
print_ret (The) noun, " bounces back off the board.";
282
<p class="aside">Such an imaginary action – usually, as in this
283
case, a perfectly sensible action seen from the point of view of
284
the second object involved, rather than the first – is sometimes
285
called a “fake action”. Two things about it are fake:
286
there's no grammar that produces <code>ThrownAt</code>, and there's
287
no routine called <code>ThrownAtSub</code>. The important fake actions
288
are <code>ThrownAt</code>, <code>Receive</code> and <code>LetGo</code>,
289
the latter two being used for containers: see
290
<a href="s12.html">§12</a>.</p>
292
<p class="aside"><span class="warning">▲</span>
293
If you really need to, you can declare a new fake action with the
294
directive <code>Fake_action</code> ‹<span class="token">Action-name</span>›<code>;</code>.
295
You can then cause this action with <code><</code> and
296
<code>></code> as usual.</p>
299
<p class="aside"><span class="warning"><b>•</b>▲▲
300
<b><a href="sa6.html#ans5">EXERCISE 5</a></b></span><br>
301
<code>ThrownAt</code> would be unnecessary if Inform had an idea
302
of <code>before</code> and <code>after</code> routines which an
303
object could provide if it were the second noun of an action. How
304
might this be implemented?</p>
306
<p class="aside"><span class="warning">▲▲</span>
307
Very occasionally, in the darker recesses of
308
<a href="s18.html">§18</a> for instance, you want “fake
309
fake actions”, actions which are only halfway faked in that
310
they still have action routines. Actually, these are perfectly
311
genuine actions, but with the parser's grammar jinxed so that they
312
can never be produced whatever the player types.</p>
314
<p class="dotbreak">� � � � �</p>
316
<p class="normal">The standard stock of actions is easily added to.
317
Two things are necessary to create a new action: first one must provide
318
a routine to make it happen. For instance:</p>
320
<p class="lynxonly"></p>
323
"You speak the magic word ~Blorple~. Nothing happens.";
327
<a id="p102" name="p102"></a>
328
<p class="normal">Every action has to have a “subroutine”
329
like this, the name of which is always the name of the action with
330
<code>Sub</code> appended. Secondly, one must add grammar so that
331
<code>Blorple</code> can actually be called for. Far more about grammar
332
in <a href="ch4.html">Chapter IV</a>: for now we add the simplest
333
of all grammar lines, a directive</p>
335
<p class="lynxonly"></p>
336
<pre class="code">Verb 'blorple' * -> Blorple;</pre>
338
<p class="normal">placed after the inclusion of the <code>Grammar</code>
339
file. The word “blorple” can now be used as a verb. It
340
can't take any nouns, so the parser will complain if the player
341
types “blorple daisy”.</p>
343
<p class="indent"><code>Blorple</code> is now a typical Group 3 action.
344
<code>before</code> rules can be written for it, and it can be
345
triggered off by a statement like</p>
347
<p class="lynxonly"></p>
348
<pre class="code"><Blorple>;</pre>
350
<p class="indent">The unusual action in ‘Ruins’,
351
<code>Photograph</code>, needs to be a Group 2 action, since it actually
352
does something, and objects need to be able to react with <code>after</code>
353
rules. (Indeed, the definition of the <code>Treasure</code> class
354
in the previous section contains just such an <code>after</code> rule.)
355
A photographer needs a camera:</p>
357
<p class="lynxonly"></p>
359
Object -> -> camera "wet-plate camera"
360
with name 'wet-plate' 'plate' 'wet' 'camera',
362
"A cumbersome, sturdy, stubborn wooden-framed wet plate
363
model: like all archaeologists, you have a love-hate
364
relationship with your camera.";
367
<p class="normal">(This is going to be inside a packing case which is
368
inside the Forest, hence the two arrows <code>-></code>.) And now the action
369
subroutine. The sodium lamp referred to will be constructed in
370
<a href="s14.html">§14</a>.</p>
372
<p class="lynxonly"></p>
375
if (camera notin player) "Not without the use of your camera.";
376
if (noun == player) "Best not. You haven't shaved since Mexico.";
377
if (children(player) > 1)
378
"Photography is a cumbersome business, needing the use of both
379
hands. You'll have to put everything else down.";
380
if (location == Forest) "In this rain-soaked forest, best not.";
381
if (location == thedark) "It is far too dark.";
382
if (AfterRoutines()) return;
383
"You set up the elephantine, large-format, wet-plate camera, adjust
384
the sodium lamp and make a patient exposure of ", (the) noun, ".";
388
<a id="p103" name="p103"></a>
389
<p class="normal">What makes this a Group 2 action is that, if the action
390
successfully takes place, then the library routine <code>AfterRoutines</code>
391
is called. This routine takes care of all the standard rules to do with
392
<code>after</code> (see below), and returns <code>true</code> if any
393
object involved has dealt with the action and printed something already.
394
(Failing that, the message “You set up…” will be
395
printed.) Finally, some grammar for the parser:</p>
397
<p class="lynxonly"></p>
398
<pre class="code">Verb 'photograph' * noun -> Photograph;</pre>
400
<p class="normal">This matches input like “photograph statuette”,
401
because the grammar token <code>noun</code> tells the parser to expect
402
the name of a visible object. See <a href="s30.html">§30</a> and
403
<a href="s31.html">§31</a> for much more on grammar.</p>
405
<p class="aside"><span class="warning">▲</span>
406
To make a Group 1 action, define the verb as <code>meta</code>
407
(see <a href="s30.html">§30</a>).</p>
409
<p class="dotbreak">� � � � �</p>
411
<p class="normal">Actions are processed in a simple way, but one which
412
involves many little stages. There are three main stages:</p>
415
<li>‘Before’, for group 2 and 3 actions. An opportunity
416
for your code to interfere with or block altogether what might soon
418
<li>‘During’, for all actions. The library takes control
419
and decides if the action makes sense according to its normal world
420
model: for example, only an <code>edible</code> object may be eaten;
421
only an object in the player's possession can be thrown at somebody,
422
and so on. If the action is impossible, a complaint is printed and
423
that's all. Otherwise the action is now carried out.</li>
424
<li>‘After’, for group 2 actions. An opportunity for
425
your code to react to what has happened, after it has happened but
426
before any text announcing it has been printed. If it chooses, your
427
code can print and cause an entirely different outcome. If your code
428
doesn't interfere, the library reports back to the player (with such
429
choice phrases as “Dropped.”).</li>
432
<p class="aside"><span class="warning">▲</span>
433
Group 1 actions, like <code>Score</code>, have no ‘Before’
434
or ‘After’ stages: you can't (easily) stop them from
435
taking place. They aren't happening in the game's world, but in the
438
<p class="aside"><span class="warning">▲</span>
439
The ‘Before’ stage consults your code in five ways, and
440
occasionally it's useful to know in what order:</p>
442
<ul style="list-style-type:none">
443
<li>(1a) The <code>GamePreRoutine</code> is called, if you have written
444
one. If it returns <code>true</code>, nothing else happens and the
445
action is stopped.</li>
446
<li>(1b) The <code>orders</code> property of the player is called
447
on the same terms. For more details, see <a href="s18.html">§18</a>.</li>
448
<li>(1c) And the <code>react_before</code> of every object in scope,
449
which roughly means ‘in the vicinity’. For more details,
450
see <a href="s32.html">§32</a>.</li>
451
<li><a id="p104" name="p104"></a>(1d) And the <code>before</code> of the current room.</li>
452
<li>(1e) If the action has a first noun, its <code>before</code>
453
is called on the same terms.</li>
456
<p class="aside"><span class="warning">▲</span>
457
The library processes the ‘During’ stage by calling the
458
action's subroutine: for instance, by calling <code>TakeSub</code>.</p>
460
<p class="aside"><span class="warning">▲</span>
461
The ‘After’ stage only applies to Group 2 actions, as
462
all Group 3 actions have been wound up with a complaint or a bland
463
response at the ‘During’ stage. During ‘After’
464
the sequence is as follows: (3a) <code>react_after</code> rules for
465
every object in scope (including the player object); (3b) the room's
466
<code>after</code>; (3c) the first noun's <code>after</code> and
467
(3d) finally <code>GamePostRoutine</code>.</p>
469
<p class="aside"><span class="warning">▲▲</span>
470
To some extent you can even meddle with the ‘During’
471
stage, and thus even interfere with Group 1 actions, by unscrupulous
472
use of the <code>LibraryMessages</code> system. See
473
<a href="s25.html">§25</a>.</p>
475
<p class="dotbreak">� � � � �</p>
477
<p class="normal">As mentioned above, the parser can generate decidedly
478
odd actions, such as <code>Insert camel eye_of_needle</code>. The
479
parser's policy is to allow any action which the player has clearly
480
asked for at the keyboard, and it never uses knowledge about the
481
current game position except to resolve ambiguities. For instance,
482
“take house” in the presence of the Sydney Opera House
483
and also a souvenir model of the same will be resolved in favour of
484
the model. But if there is no model to cloud the issue, the parser
485
will cheerfully generate <code>Take Sydney_Opera_House</code>.</p>
487
<p class="indent">Actions are only checked for sensibleness
488
<em>after</em> the <code>before</code> stage. In many ways this is
489
a good thing, because in adventure games the very unlikely is sometimes
490
correct. But sometimes it needs to be remembered when writing
491
<code>before</code> rules. Suppose a <code>before</code> rule
492
intercepts the action of putting the mushroom in the crate, and
493
exciting things happen as a result. Now even if the mushroom is, say,
494
sealed up inside a glass jar, the parser will still generate the
495
action <code>Insert mushroom crate</code>, and the <code>before</code> rule
496
will still cut in, because the impossibility of the action hasn't yet
499
<p class="indent">The upshot of this is that the exciting happening
500
should be written not as a <code>before</code> but as an <code>after</code>
501
rule, when it's known that the attempt to put the mushroom in the crate
502
has already succeeded.</p>
504
<p class="aside"><span class="warning">▲</span>
505
That's fine if it's a Group 2 action you're working with. But consider
506
the following scenario: a siren has a cord which needs to be pulled to
507
sound the alarm. But the siren can be behind glass, and is on the
508
other side of a barred cage in which the player is imprisoned.
509
You need to write a rule for <code>Pull cord</code>, but you can't
510
place this among the cord's <code>after</code> rules because <code>Pull</code>
511
is a group 3 action and there isn't any “after”: so it has
512
to be a <code>before</code> rule. Probably it's best to write your
513
own code by hand to check
514
<a id="p105" name="p105"></a>
515
that the cord is reachable. But an alternative
516
is to call the library's routine:</p>
518
<p class="lynxonly"></p>
519
<pre class="code">ObjectIsUntouchable(item, silent_flag, take_flag)</pre>
521
<p class="aside">This determines whether or not the player can touch
522
<code>item</code>, returning <code>true</code> if there is some
523
obstruction. If <code>silent_flag</code> is <code>true</code>, or
524
if there's no obstruction anyway, nothing will be printed. Otherwise
525
a suitable message will be printed up, such as “The barred cage
526
isn't open.” So a safe way to write the cord's <code>before</code>
529
<p class="lynxonly"></p>
532
Pull: if (ObjectIsUntouchable(self)) rtrue;
533
"~Vwoorp! Vwoorp!~";
537
<p class="aside"><code>ObjectIsUntouchable</code> can also be a convenience
538
when writing action subroutines for new actions of your own.</p>
540
<p class="aside"><span class="warning">▲▲</span>
541
If you set <code>take_flag</code>, then a further restriction will be
542
imposed: the <code>item</code> must not belong to something or someone
543
already: specifically, it must not be in the possession of an <code>animate</code>
544
or a <code>transparent</code> object that isn't a <code>container</code>
545
or <code>supporter</code>. For instance, the off button on a television
546
set can certainly be touched, but if <code>take_flag</code> is <code>true</code>,
547
then <code>ObjectIsUntouchable</code> will print up “That seems
548
to be a part of the television set.” and return <code>true</code>
549
to report an obstacle.</p>
551
<p class="aside"><span class="warning"><b>•</b> <b>REFERENCES</b></span><br>
552
In a game compiled with the <code>-D</code> for “Debugging”
553
switch set, the “actions” verb will result in trace information
554
being printed each time any action is generated. Try putting many things
555
into a rucksack and asking to “empty” it for an extravagant
557
<span class="warning"><b>•</b></span>Diverted actions (using <code><<</code>
558
and <code>>></code>) are commonplace. They're used in about 20
559
places in ‘Advent’: a good example is the way “take
560
water” is translated into a <code>Fill bottle</code> action.
561
<span class="warning"><b>•</b></span>L. Ross Raszewski's library
562
extension <tt>"yesno.h"</tt> makes an interesting use of
563
<code>react_before</code> to handle semi-rhetorical questions. For
564
instance, suppose the player types “eat whale”, an absurd
565
command to which the game replies “You can fit a blue whale in
566
your mouth?” Should the player take this as a literal question
567
and type “yes”, the designer might want to be able to reply
568
“Oh. I should never have let you go through all those doors.”
569
How might this be done? The trick is that, when the game's first reply
570
is made, an invisible object is moved into play which does nothing except
571
to react to a <code>Yes</code> action by making the second reply.</p>
575
<a href="index.html">home</a> /
576
<a href="contents.html">contents</a> /
577
<a href="ch2.html" title="Chapter II: Introduction to Designing">chapter II</a> /
578
<a href="s5.html" title="§5: Introducing messages and classes">prev</a> /
579
<a href="s7.html" title="§7: Infix and the debugging verbs">next</a> /
580
<a href="dm4index.html">index</a>