1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4
<title>DM4 §21: Starting, moving, changing and killing the player</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="ch3.html" title="Chapter III: The Model World">chapter III</a> /
13
<a href="s20.html" title="§20: Daemons and the passing of time">prev</a> /
14
<a href="s22.html" title="§22: Miscellaneous constants, scoring, quotations">next</a> /
15
<a href="dm4index.html">index</a>
18
<a id="p162" name="p162"></a>
19
<h2>§21 Starting, moving, changing and killing the player</h2>
21
<blockquote>Life's but a walking shadow, a poor player<br>
22
That struts and frets his hour upon the stage<br>
23
And then is heard no more; it is a tale<br>
24
Told by an idiot, full of sound and fury,<br>
25
Signifying nothing.<br>
26
— William Shakespeare (1564–1616), <i>Macbeth</i> V v</blockquote>
28
<p class="normal"><span class="atleft"><img src="dm4-162_1.jpg" alt=""></span>
29
To recap on <a href="s4.html">§4</a>, an “entry point
30
routine” is one provided by your own source code which the
31
library may call from time to time. There are about twenty of these,
32
listed in <a href="sa5.html">§A5</a>, and all of them are
33
optional but one: <code>Initialise</code>. This routine is called
34
before any text of the game is printed, and it can do many things:
35
start timers and daemons, set the time of day, equip the player with
36
possessions, make any random settings needed and so on. It <em>usually</em>
37
prints out some welcoming text, though not the name and author of
38
the game, because that appears soon after when the “game
39
banner” is printed. The only thing it must do is to set the
40
<code>location</code> variable to where the player begins.</p>
42
<p class="indent">This is usually a room, possibly in darkness, but
43
might instead be an <code>enterable</code> object inside a room,
44
such as a chair or a bed. Like medieval romance epics, interactive
45
fiction games often start by waking the player from sleep, sometimes by
46
way of a dream sequence. If your game begins with verbose instructions
47
before the first opportunity for a player to type a command, you may
48
want to offer the chance to restore a saved game at once:</p>
50
<p class="lynxonly"></p>
52
print "Would you like to restore a game? >";
53
if (YesOrNo()) <Restore>;
56
<p class="normal">To equip the player with possessions, simply move
57
the relevant objects to <code>player</code>.</p>
59
<p class="indent">The return value from <code>Initialise</code> is
60
ordinarily ignored, whether <code>true</code> or <code>false</code>,
61
and the library goes on to print the game banner. If, however, you
62
return 2, the game banner is suppressed for now. This feature is
63
provided for games like ‘Sorcerer’ and ‘Seastalker’
64
which play out a short prelude first. If you do suppress the banner
65
from <code>Initialise</code>, you should print it no more than a
66
few turns later on by calling the library routine <code>Banner</code>.
67
The banner is familiar to players, reassuringly traditional and
68
useful when testing, because it identifies which version of a game
69
is giving trouble. Like an imprint page with an ISBN, it is invaluable
70
to bibliographers and collectors of story files.</p>
72
<a id="p163" name="p163"></a>
73
<p class="dotbreak">� � � � �</p>
75
<p class="normal">‘Ruins’ opens in classical fashion:</p>
77
<p class="lynxonly"></p>
83
move sodium_lamp to player;
84
move dictionary to player;
85
thedark.description = "The darkness of ages presses in on you, and
86
you feel claustrophobic.";
87
"^^^Days of searching, days of thirsty hacking through the briars of
88
the forest, but at last your patience was rewarded. A discovery!^";
92
<p class="normal">For the source code of the ‘Ruins’
93
<code>TitlePage</code> routine, see the exercises in
94
<a href="s42.html">§42</a>.</p>
96
<p class="dotbreak">� � � � �</p>
98
<p class="normal">The question “where is the player?”
99
can be answered in three different ways. Looking at <code>parent(player)</code>
100
tells you the object immediately containing the player, which can
101
be a location but might instead be a chair or vehicle. So a condition
104
<p class="lynxonly"></p>
105
<pre class="code">if (player in Bridleway) ...</pre>
107
<p class="normal">would be <code>false</code> if the player were riding
108
a horse through the Bridleway. The safer alternative is:</p>
110
<p class="lynxonly"></p>
111
<pre class="code">if (location == Bridleway) ...</pre>
113
<p class="normal">but even this would be <code>false</code> if the
114
Bridleway were in darkness, because then <code>location</code> would
115
be the special object <code>thedark</code> (see <a href="s19.html">§19</a>).
116
The definitive location value is stored in <code>real_location</code>,
119
<p class="lynxonly"></p>
120
<pre class="code">if (real_location == Bridleway) ...</pre>
122
<p class="normal">works in all cases. The condition for “is
123
the player in a dark Bridleway?” is:</p>
125
<p class="lynxonly"></p>
126
<pre class="code">if (location == thedark && real_location == Bridleway) ...</pre>
128
<p class="normal">Except for the one time in <code>Initialise</code>,
129
you should not attempt to change either of these variables, nor to move
130
the player-object by hand. One safe way to move the player in your
131
own source code is to cause actions like</p>
133
<p class="lynxonly"></p>
134
<pre class="code"><Go n_obj>;</pre>
136
<a id="p164" name="p164"></a>
137
<p class="normal">but for moments of teleportation it's easier to
138
use the library routine <code>PlayerTo</code>. Calling <code>PlayerTo(somewhere)</code>
139
makes the parent-object of the player <code>somewhere</code> and
140
adjusts the <code>location</code> variables accordingly: it also runs
141
through a fair number of standard game rules, for instance checking
142
the light level and performing a <code>Look</code> action to print
143
out the new room description. The value <code>somewhere</code> can
144
be a room, or an <code>enterable</code> object such as a cage or
145
a traction-engine, provided that the cardinal rule is always observed:</p>
147
<p class="aside" style="margin-left:30px">The parent of the player
148
object must at all times be “location-like”. An object
149
is “location-like” if either it is a location, or it has
150
<code>enterable</code> and its parent is location-like.</p>
152
<p class="normal">In other words, you can't put the player in an
153
<code>enterable</code> cardboard box if that box is itself shut up in
154
a free-standing safe which isn't <code>enterable</code>. And you
155
can't <code>PlayerTo(nothing)</code> or <code>PlayerTo(thedark)</code>
156
because <code>nothing</code> is not an object and <code>thedark</code>
157
is not location-like.</p>
159
<p class="aside"><span class="warning">▲</span>
160
Calling <code>PlayerTo(somewhere,1)</code> moves the player without
161
printing any room description. All other standard game rules are applied.</p>
163
<p class="aside"><span class="warning">▲</span>
164
Calling <code>PlayerTo(somewhere,2)</code> is just like <code>PlayerTo(somewhere)</code>
165
except that the room description is in the form the player would expect
166
from typing “go east” rather than from typing “look”.
167
The only difference is that in the former case the room is (normally)
168
given an abbreviated description if it has been visited before, whereas
169
in the latter case the description is always given in full.</p>
171
<p class="dotbreak">� � � � �</p>
173
<p class="aside"><span class="warning">▲▲</span>
174
It's perhaps worth taking a moment to say what the standard rules upon
175
changing location are. The following rules are applied whenever a <code>Look</code>
176
action or a call to <code>PlayerTo</code> take place.</p>
178
<ol type="1" start="0">
179
<li><!-- (0) -->If <code>PlayerTo</code> has been called then the <code>parent</code>
180
of the player, <code>location</code> and <code>real_location</code>
182
<li><!-- (1) -->Any object providing <code>found_in</code> is checked. If it
183
claims to be <code>found_in</code> the location, it is moved to that
184
location. If not, or if it has <code>absent</code>, it is removed
185
from the object tree. (See <a href="s8.html">§8</a>.)</li>
186
<li><!-- (2) -->The availability of light is checked (see <a href="s19.html">§19</a>),
187
and <code>location</code> is set to <code>thedark</code> if necessary.</li>
188
<li><!-- (3) -->The “visibility ceiling” of the player is determined.
189
For instance, the <i>VC</i> for a player in a closed wooden box is
190
the box, but for a player in a closed glass box it's the location.
193
<li><!-- (a) -->The <i>VC</i> of a room is the value of <code>location</code>,
194
i.e., either <code>thedark</code> or the room object.</li>
195
<li><!-- (b) -->If the parent of an object is a room or is “see-through” (see
196
<a href="s19.html">§19</a> for this definition), the <i>VC</i>
197
of the object is the <i>VC</i> of the parent.</li>
198
<li><a id="p165" name="p165"></a><!-- (c) -->If not, the <i>VC</i> of the object is its parent.</li>
200
<li><!-- (4) -->If the <i>VC</i> is <code>thedark</code> or (say) a box, skip
201
this rule. Otherwise: if the <i>VC</i> has changed since the
202
<em>previous</em> time that rule (3) produced a <i>VC</i> which wasn't
203
an <code>enterable</code> object, then:
205
<li><!-- (a) -->The message <code>location.initial()</code> is sent, if
206
the location provides an <code>initial</code> rule. If the library finds that the
207
player has been moved in the course of running <code>initial</code>, it
208
goes back to rule (3).</li>
209
<li><!-- (b) -->The game's entry point routine <code>NewRoom</code> is
210
called, if it provides one.</li>
212
<li><!-- (5) -->The room description is printed out, unless these rules are
213
being gone through by <code>PlayerTo(somewhere,1)</code>. For exactly
214
what happens in printing a room description, see <a href="s26.html">§26</a>.</li>
215
<li><!-- (6) -->If the <code>location</code> doesn't have <code>visited</code>,
216
give it this attribute and award the player <code>ROOM_SCORE</code>
217
points if the <code>location</code> has <code>scored</code>.
218
(See <a href="s22.html">§22</a>.) Note that this rule looks
219
at <code>location</code>, not <code>real_location</code>, so no points
220
unless the room is visible.</li>
223
<p class="dotbreak">� � � � �</p>
225
<p class="normal">In the course of this chapter, rules to interfere
226
with actions have been attached to items, rooms and people, but not
227
yet to the player. In <a href="s18.html">§18</a> it was set out
228
that an order like “austin, eat tuna” would result in the
229
action <code>Eat tuna</code> being passed to <code>austin.orders</code>,
230
and heavy hints were dropped that orders and actions are more or
231
less the same thing. This is indeed so, and the player's own object
232
has an <code>orders</code> routine. This normally does nothing and
233
always returns <code>false</code> to mean “carry on as usual”,
234
but you can install a rule of your own instead:</p>
236
<p class="lynxonly"></p>
237
<pre class="code">player.orders = MyNewRule;</pre>
239
<p class="normal">where <code>MyNewRule</code> is a new <code>orders</code>
240
rule. This rule is applied to every action or order issued by the player.
241
The variable actor holds the person asked to do something, usually
242
but not always <code>player</code>, and the variables <code>action</code>,
243
<code>noun</code> and <code>second</code> are set up as usual. For
246
<p class="lynxonly"></p>
247
<table border="1" style="margin-left:30px;margin-top:1em;margin-bottom:1em">
248
<tr><td><i>Example command</i></td>
249
<td><code>actor</code></td>
250
<td><code>action</code></td>
251
<td><code>noun</code></td>
252
<td><code>second</code></td></tr>
253
<tr><td>“put tuna in dish”</td>
254
<td><code>player</code></td>
255
<td><code>Insert</code></td>
256
<td><code>tuna</code></td>
257
<td><code>dish</code></td></tr>
258
<tr><td>“austin, eat tuna”</td>
259
<td><code>Austin</code></td>
260
<td><code>Eat</code></td>
261
<td><code>tuna</code></td>
262
<td><code>nothing</code></td></tr>
265
<p class="normal">For instance, if a cannon goes off right next to the
266
player, a period of partial deafness might ensue:</p>
268
<p class="lynxonly"></p>
271
if (actor ~= player) rfalse;
272
Listen: "Your hearing is still weak from all that cannon-fire.";
277
<a id="p166" name="p166"></a>
278
<p class="normal">The <code>if</code> statement needs to be there
279
to prevent commands like “helena, listen” from being
280
ruled out – after all, the player can still speak.</p>
282
<a id="ex51" name="ex51"></a>
283
<p class="aside"><span class="warning"><b>•</b>▲
284
<b><a href="sa6.html#ans51">EXERCISE 51</a></b></span><br>
285
Why not achieve the same effect by giving the player a <code>react_before</code>
288
<a id="ex52" name="ex52"></a>
289
<p class="aside"><span class="warning"><b>•</b>
290
<b><a href="sa6.html#ans52">EXERCISE 52</a></b></span><br>
291
(Cf. ‘Curses’.) Write an <code>orders</code> routine for
292
the player so that wearing a gas mask will prevent speech.</p>
294
<p class="dotbreak">� � � � �</p>
296
<p class="normal">The <code>player</code> object can not only be
297
altered but switched altogether, allowing the player to play from
298
the perspective of someone or something else at any point in the
299
game. The player who tampers with Dr Frankenstein's brain transference
300
machine may suddenly become the Monster strapped to the table. A
301
player who drinks too much wine could become a drunk player object
302
to whom many different rules apply. The “snavig” spell
303
of ‘Spellbreaker’, which transforms the player to an
304
animal like the one cast upon, could be implemented thus. Similarly
305
the protagonist of ‘Suspended’, who telepathically runs
306
a weather-control station by acting through six sensory robots,
307
Iris, Waldo, Sensa, Auda, Poet and Whiz. In a less original setting,
308
a player might have a team of four adventurers exploring a labyrinth,
309
and be able to switch the one being controlled by typing the name.
310
In this case, an <code>AfterLife</code> routine (see below) may be
311
needed to switch the focus back to a still-living member of the team
312
after one has met a sticky end.</p>
314
<p class="indent">The library routine <code>ChangePlayer(obj)</code> transforms
315
the player to <code>obj</code>. Any object can be used for this. There's
316
no need to give it any name, as the parser always understands pronouns
317
like “me” and “myself” to refer to the current
318
player-object. You may want to set its description, as this is the text
319
printed if the player types “examine myself”, or its
320
<code>capacity</code>, the maximum number of items which this form
321
of the player can carry. Finally, this player-object can have its
322
own <code>orders</code> property and thus its own rules about what
323
it can and can't do.</p>
325
<p class="indent">As <code>ChangePlayer</code> prints nothing, you
326
may want to follow the call with a <code><<Look>>;</code> action.</p>
328
<p class="aside"><span class="warning">▲</span>
329
You can call <code>ChangePlayer</code> as part of a game's <code>Initialise</code>
330
routine, but if so then you should do this before setting <code>location</code>.</p>
332
<p class="aside"><span class="warning">▲</span>
333
Calling <code>ChangePlayer(obj,1);</code> does the same except that
334
it makes the game print “(as Whoever)” during subsequent
335
room descriptions.</p>
337
<a id="p167" name="p167"></a>
338
<p class="aside"><span class="warning">▲</span>
339
The body dispossessed remains where it was, in play, unless you move
340
it away or otherwise dispose of it. The player-object which the player
341
begins with is a library-defined object called <code>selfobj</code>, and is
342
described in room descriptions as “your former self”.</p>
344
<a id="ex53" name="ex53"></a>
345
<p class="aside"><span class="warning"><b>•</b>
346
<b><a href="sa6.html#ans53">EXERCISE 53</a></b></span><br>
347
In Central American legend, a sorceror can transform himself into a
348
<i>nagual</i>, a familiar such as a spider-monkey; indeed, each individual
349
has an animal self or <i>wayhel</i>, living in a volcanic land over
350
which the king, as a jaguar, rules. Turn the player into <i>wayhel</i>
353
<a id="ex54" name="ex54"></a>
354
<p class="aside"><span class="warning"><b>•</b>
355
<b><a href="sa6.html#ans54">EXERCISE 54</a></b></span><br>
356
Alter the Wormcast of ‘Ruins’ (previously defined in
357
<a href="s9.html">§9</a>) so that when in <i>wayhel</i> form,
358
the player can pass through into a hidden burial shaft.</p>
360
<a id="ex55" name="ex55"></a>
361
<p class="aside"><span class="warning"><b>•</b>
362
<b><a href="sa6.html#ans55">EXERCISE 55</a></b></span><br>
363
To complete the design of this sequence from ‘Ruins’,
364
place a visible iron cage above the hidden burial shaft. The cage
365
contains skeletons and a warning written in glyphs, but the player
366
who enters it despite these (and they all will) passes into <i>wayhel</i>
367
life. (The transformed body is unable to move the sodium lamp, but
368
has nocturnal vision, so doesn't need to.) Unfortunately the player
369
is now outside a cage which has closed around the human self which
370
must be returned to, while the <i>wayhel</i> lacks the dexterity
371
to open the cage. The solution is to use the Wormcast to reach the
372
Burial Chamber, then bring its earthen roof down, opening a connection
373
between the chamber below and the cage above. Recovering human form,
374
the player can take the grave goods, climb up into the cage, open it
375
from the inside and escape. Lara Croft would be proud.</p>
377
<p class="dotbreak">� � � � �</p>
379
<p class="aside"><span class="warning">▲▲</span>
380
The situation becomes a little complicated if the same <code>orders</code>
381
routine has to do service in two situations: once while its owner is a
382
character met in the course of play, and then a second time when the
383
player has changed into it. This could be done simply by changing the
384
value of <code>orders</code> when the transformation takes place,
385
but an alternative is to arrange code for a single <code>orders</code>
388
<p class="lynxonly"></p>
391
if (player == self) {
393
! I give myself an action
396
! I give someone else an order
398
}<a id="p168" name="p168"></a>
400
! Someone else gives me an order
405
<a id="ex56" name="ex56"></a>
406
<p class="aside"><span class="warning"><b>•</b>▲▲
407
<b><a href="sa6.html#ans56">EXERCISE 56</a></b></span><br>
408
Write an <code>orders</code> routine for a Giant with a conscience,
409
who will refuse to attack even a mouse, but so that a player who
410
becomes the Giant can be wantonly cruel.</p>
412
<p class="dotbreak">� � � � �</p>
414
<p class="normal">“There are only three events in a man's life;
415
birth, life and death; he is not conscious of being born, he dies in
416
pain and he forgets to live.” (Jean de la Bruyère again.)
417
Death is indeed the usual conclusion of an adventure game, and occurs
418
when the source code sets the library variable <code>deadflag</code>
419
to <code>true</code>: in normal play <code>deadflag</code> is always
420
<code>false</code>. The “standard Inform rules” never
421
lead to the player's death, so this is something the designer must
424
<p class="indent">Unlike life, however, interactive fiction offers
425
another way out: the player can win. This happens if and when the
426
variable <code>deadflag</code> is set to 2.</p>
428
<p class="indent">Any higher values of <code>deadflag</code> are
429
considered to be more exotic ways the game can end, requiring text
430
beyond “You have died” or “You have won”.
431
The Inform library doesn't know what this text should be, so it
432
calls the <code>DeathMessage</code> entry point routine, which
433
is expected to look at <code>deadflag</code> and can then print
434
something suitable. For instance, ‘Ruins’ has a chasm
435
subject to the following <code>before</code> rule:</p>
437
<p class="lynxonly"></p>
441
"You plummet through the silent void of darkness, cracking
442
your skull against an outcrop of rock. Amid the pain and
443
redness, you dimly make out the God with the
444
Owl-Headdress...";
445
JumpOver: "It is far too wide.";
449
<p class="normal">and this means that it needs a <code>DeathMessage</code>
452
<p class="lynxonly"></p>
456
print "You have been captured";
460
<p class="normal">Capture was about the worst fate that could befall
461
you in the unspeakably inhumane world of Maya strife.</p>
463
<a id="p169" name="p169"></a>
464
<p class="indent">‘Ruins’ doesn't, but many games allow
465
reincarnation or, as David M. Baggett points out, in fact resurrection.
466
You too can allow this, by providing an <code>AfterLife</code> entry
467
point routine. This gets the chance to do as it pleases before
468
any “death message” is printed, and it can even reset
469
<code>deadflag</code> to <code>false</code>, causing the game to
470
resume as though nothing had happened. Such <code>AfterLife</code>
471
routines can be tricky to write, though, because the game often has
472
to be altered to reflect what has happened.</p>
474
<p class="aside"><span class="warning"><b>•</b>
475
<b>REFERENCES</b></span><br>
476
The magic words “xyzzy” and “plugh” in
477
‘Advent’ employ <code>PlayerTo</code>.
478
<span class="warning"><b>•</b></span>‘Advent’ has an
479
amusing <code>AfterLife</code> routine: for instance, try collapsing
480
the bridge by leading the bear across, then returning to the scene
481
after resurrection. ‘Balances’ has one which only
482
slightly penalises death.</p>
486
<a href="index.html">home</a> /
487
<a href="contents.html">contents</a> /
488
<a href="ch3.html" title="Chapter III: The Model World">chapter III</a> /
489
<a href="s20.html" title="§20: Daemons and the passing of time">prev</a> /
490
<a href="s22.html" title="§22: Miscellaneous constants, scoring, quotations">next</a> /
491
<a href="dm4index.html">index</a>