For LaTeX: Start each chapter and appendix on a new page.
[ibg.git] / chapters / 05.rst
1 .. raw:: latex
2
3    \newpage
4
5 =================
6  Heidi revisited
7 =================
8
9 .. epigraph::
10
11    | *I was an innkeeper, who loved to carouse;*
12    | *J was a joiner, and built up a house.*
13
14 .. only:: html
15
16   .. image:: /images/picI.png
17      :align: left
18
19 .. raw:: latex
20
21     \dropcap{i}
22
23 n even the simplest story, there's bound to be scope for the player to
24 attempt activities that you hadn't anticipated.  Sometimes there may be
25 alternative ways of approaching a problem: if you can't be sure which
26 approach the player will take, you really ought to allow for all
27 possibilities.  Sometimes the objects you create and the descriptions you
28 provide may suggest to the player that doing such-and-such should be
29 possible, and, within reason, you ought to allow for that also.  The basic
30 game design is easy: what takes the time, and makes a game large and
31 complex, is taking care of all the *other* things that the player may think
32 of trying.
33
34 Here, we try to illustrate what this means by addressing a few of the more
35 glaring deficiencies in our first game.
36
37 Listening to the bird
38 =====================
39
40 Here's a fragment of the game being played:
41
42 .. code-block:: transcript
43
44    Deep in the forest
45    Through the dense foliage, you glimpse a building to the west. A track heads
46    to the northeast.
47
48    You can see a baby bird here.
49
50    >EXAMINE THE BIRD
51    Too young to fly, the nestling tweets helplessly.
52
53    >LISTEN TO BIRD
54    You hear nothing unexpected.
55
56    >
57
58 That's not too smart, is it?  Our description specifically calls the
59 player's attention to the sound of the bird -- and then she finds out that
60 we've got nothing special to say about its helpless tweeting.
61
62 The library has a stock of actions and responses for each of the game's
63 defined verbs, so it can handle most of the player's input with a default,
64 standard behaviour instead of remaining impertinently silent or saying that
65 it doesn't understand what the player intends.  "You hear nothing
66 unexpected" is the library's standard LISTEN response, good enough after
67 LISTEN TO NEST or LISTEN TO TREE, but fairly inappropriate here; we really
68 need to substitute a more relevant response after LISTEN TO BIRD.  Here's
69 how we do it:
70
71 .. code-block:: inform6
72
73    Object   bird "baby bird" forest
74      with   description "Too young to fly, the nestling tweets helplessly.",
75             name 'baby' 'bird' 'nestling',
76             before [;
77                   Listen:
78                     print "It sounds scared and in need of assistance.^";
79                     return true;
80             ],
81       has   ;
82
83 We'll go through this a step at a time:
84
85 #. We've added a new ``before`` property to our bird object.  The
86    interpreter looks at the property *before* attempting to perform any
87    action which is directed specifically at this object::
88
89       before [; ... ],
90
91 #. The value of the property is an embedded routine, containing a label and
92    two statements::
93
94        Listen:
95          print "It sounds scared and in need of assistance.^";
96          return true;
97
98 #. The label is the name of an action, in this case ``Listen``.  What we're
99    telling the interpreter is: if the action that you're about to perform
100    on the bird is a ``Listen``, execute these statements first; if it's any
101    other action, carry on as normal.  So, if the player types EXAMINE BIRD,
102    PICK UP BIRD, PUT BIRD IN NEST, HIT BIRD or FONDLE BIRD, then she'll get
103    the standard response.  If she types LISTEN TO BIRD, then our two
104    statements get executed before anything else happens.  We call this
105    "trapping" or "intercepting" the action of Listening to the bird.
106
107 #. The two statements that we execute are, first::
108
109        print "It sounds scared and in need of assistance.^";
110
111    which causes the interpreter to display the string given in double
112    quotes; remember that a ``^`` character in a string appears as a
113    newline.  Second, we execute::
114
115        return true;
116
117    which tells the interpreter that it doesn't need to do anything else,
118    because we've handled the ``Listen`` action ourselves.  And the game now
119    behaves like this -- perfect:
120
121    .. code-block:: transcript
122
123       >LISTEN TO BIRD
124       It sounds scared and in need of assistance.
125
126       >
127
128 The use of the ``return true`` statement probably needs a bit more
129 explanation.  An object's ``before`` property traps an action aimed at that
130 object right at the start, before the interpreter has started to do
131 anything.  That's the point at which the statements in the embedded routine
132 are executed.  If the last of those statements is ``return true`` then the
133 interpreter assumes that the action has been dealt with by those
134 statements, and so there's nothing left to do: no action, no message;
135 nothing.  On the other hand, if the last of the statements is ``return
136 false`` then the interpreter carries on to perform the default action as
137 though it hadn't been intercepted.  Sometimes that's what you want it to
138 do, but not here: if instead we'd written this:
139
140 .. code-block:: inform6
141
142    Object    bird "baby bird" forest
143      with    description "Too young to fly, the nestling tweets helplessly.",
144              name 'baby' 'bird' 'nestling',
145              before [;
146                 Listen:
147                   print "It sounds scared and in need of assistance.^";
148                   return false;
149              ],
150        has   ;
151
152 then the interpreter would first have displayed our string, and then
153 carried on with its normal response, which is to display the standard
154 message:
155
156 .. code-block:: transcript
157
158    >LISTEN TO BIRD
159    It sounds scared and in need of assistance.
160    You hear nothing unexpected.
161
162    >
163
164 This technique -- intercepting an action aimed at a particular object in
165 order to do something appropriate for that object -- is one that we'll use
166 again and again.
167
168 Entering the cottage
169 ====================
170
171 At the start of the game the player character stands "outside a cottage", which
172 might lead her to believe that she can go inside:
173
174 .. code-block:: transcript
175
176    In front of a cottage
177    You stand outside a cottage. The forest stretches east.
178
179    >IN
180    You can't go that way.
181
182    >
183
184 Again, that isn't perhaps the most appropriate response, but it's easy to
185 change:
186
187 .. code-block:: inform6
188
189    Object    before_cottage "In front of a cottage"
190      with    description
191                  "You stand outside a cottage. The forest stretches east.",
192              e_to forest,
193              in_to "It's such a lovely day -- much too nice to go inside.",
194              cant_go "The only path lies to the east.",
195        has   light;
196
197 The ``in_to`` property would normally link to another room, in the same way
198 as the ``e_to`` property contain the internal ID of the ``forest`` object.
199 However, if instead you set its value to be a string, the interpreter
200 displays that string when the player tries the IN direction.  Other --
201 unspecified -- directions like NORTH and UP still elicit the standard "You
202 can't go that way" response, but we can change that too, by supplying a
203 ``cant_go`` property whose value is a suitable string.  We then get this
204 friendlier behaviour:
205
206 .. code-block:: transcript
207
208    In front of a cottage
209    You stand outside a cottage. The forest stretches east.
210
211    >IN
212    It's such a lovely day -- much too nice to go inside.
213
214    >NORTH
215    The only path lies to the east.
216
217    >EAST
218
219    Deep in the forest
220    ...
221
222 There's another issue here; since we haven't actually implemented an object
223 to represent the cottage, a perfectly reasonable EXAMINE COTTAGE command
224 receives the obviously nonsensical reply "You can't see any such thing".
225 That's easy to fix; we can add a new ``cottage`` object, making it a piece
226 of ``scenery`` just like the ``tree``:
227
228 .. code-block:: inform6
229
230    Object   cottage "tiny cottage" before_cottage
231      with   description "It's small and simple, but you're very happy here.",
232             name 'tiny' 'cottage' 'home' 'house' 'hut' 'shed' 'hovel',
233       has   scenery;
234
235 This solves the problem, but promptly gives us another unreasonable
236 response:
237
238 .. code-block:: transcript
239
240    In front of a cottage
241    You stand outside a cottage. The forest stretches east.
242
243    >ENTER COTTAGE
244    That's not something you can enter.
245
246    >
247
248 The situation here is similar to our LISTEN TO BIRD problem, and the
249 solution we adopt is similar as well:
250
251 .. code-block:: inform6
252
253    Object   cottage "tiny cottage" before_cottage
254      with   description "It's small and simple, but you're very happy here.",
255             name 'tiny' 'cottage' 'home' 'house' 'hut' 'shed' 'hovel',
256             before [;
257                Enter:
258                  print_ret "It's such a lovely day -- much too nice to go inside.";
259             ],
260       has   scenery;
261
262 We use a ``before`` property to intercept the ``Enter`` action applied to
263 the cottage object, so that we can display a more appropriate message.
264 This time, however, we've done it using one statement rather than two.  It
265 turns out that the sequence "``print`` a string which ends with a newline
266 character, and then ``return true``" is so frequently needed that there's a
267 special statement which does it all.  That is, this single statement (where
268 you'll note that the string doesn't need to end in ``^``)::
269
270      print_ret "It's such a lovely day -- much too nice to go inside.";
271
272 works exactly the same as this pair of statements::
273
274      print "It's such a lovely day -- much too nice to go inside.^";
275      return true;
276
277 We could have used the shorter form when handling LISTEN TO BIRD, and we
278 *will* use it from now on.
279
280 Climbing the tree
281 =================
282
283 In the clearing, holding the nest and looking at the tree, the player is
284 meant to type UP.  Just as likely, though, she'll try CLIMB TREE (which
285 currently gives the completely misleading response "I don't think much is
286 to be achieved by that").  Yet another opportunity to use a ``before``
287 property, but now with a difference.
288
289 .. code-block:: inform6
290
291    Object   tree "tall sycamore tree" clearing
292      with   description
293                  "Standing proud in the middle of the clearing,
294                   the stout tree looks easy to climb.",
295             name 'tall' 'sycamore' 'tree' 'stout' 'proud',
296             before [;
297                Climb:
298                  PlayerTo(top_of_tree);
299                  return true;
300             ],
301      has    scenery;
302
303 This time, when we intercept the ``Climb`` action applied to the ``tree``
304 object, it's not in order to display a better message; it's because we want
305 to move the player character to another room, just as if she'd typed UP.
306 Relocating the player character is actually quite a complex business, but
307 fortunately all of that complexity is hidden: there's a standard **library
308 routine** to do the job, not one that we've written, but one that's
309 provided as part of the Inform system.
310
311 You'll remember that, when we first mentioned routines (see "Standalone
312 routines" on page 57), we used the example of ``Initialise()`` and said
313 that "the routine's name followed by opening and closing parentheses is all
314 that it takes to call a routine".  That was true for ``Initialise()``, but
315 not quite the whole story.  To move the player character, we've got to
316 specify where we want her to go, and we do that by supplying the internal
317 ID of the destination room within the opening and closing parentheses.
318 That is, instead of just ``PlayerTo()`` we call ``PlayerTo(top_of_tree)``,
319 and we describe ``top_of_tree`` as the routine's **argument**.
320
321 Although we've moved the player character to another room, we're still in
322 the middle of the intercepted ``Climb`` action.  As previously, we need to
323 tell the interpreter that we've dealt with the action, and so we don't want
324 the standard rejection message to be displayed.  The ``return true``
325 statement does that, as usual.
326
327 Dropping objects from the tree
328 ==============================
329
330 In a normal room like the ``forest`` or the ``clearing``, the player can
331 DROP something she's carrying and it'll effectively fall to the ground at
332 her feet.  Simple, convenient, predictable -- except when the player is at
333 the top of the tree.  Should she DROP something from up there, having it
334 land nearby might seem a bit improbable; much more likely that it would
335 fall to the clearing below.
336
337 It looks like we might want to intercept the ``Drop`` action, but not quite
338 in the way we've been doing up until now.  For one thing, we don't want to
339 complicate the definitions of the ``bird`` and the ``nest`` and any other
340 objects we may introduce: much better to find a general solution that will
341 work for all objects.  And second, we need to recognise that not all
342 objects are droppable; the player can't, for example, DROP THE BRANCH.
343
344 The best approach to the second problem is to intercept the ``Drop`` action
345 *after* it has occurred, rather than beforehand.  That way, we let the
346 library take care of objects which aren't being held or which can't be
347 dropped, and only become involved once a ``Drop`` has been successful.  And
348 the best approach to the first problem is to do this particular
349 interception not on an object-by-object basis, as we have been doing so
350 far, but instead for every ``Drop`` which takes place in our troublesome
351 ``top_of_tree`` room.  This is what we have to write:
352
353 .. code-block:: inform6
354
355    Object   top_of_tree "At the top of the tree"
356      with   description "You cling precariously to the trunk.",
357             d_to clearing,
358             after [;
359                Drop:
360                  move noun to clearing;
361                  return false;
362             ],
363       has   light;
364
365 Let's again take it a step at a time:
366
367 #. We've added a new ``after`` property to our ``top_of_tree`` object.  The
368    interpreter looks at the property *subsequent to* performing any action in
369    this room::
370
371        after [; ... ],
372
373 #. The value of the property is an embedded routine, containing a label and
374    two statements::
375
376        Drop:
377          move noun to clearing;
378          return false;
379
380 #. The label is the name of an action, in this case ``Drop``.  What we're
381    telling the interpreter is: if the action that you've just performed
382    here is a ``Drop``, execute these statements before telling the player
383    what you've done; if it's any other action, carry on as normal.
384
385 #. The two statements that we execute are first::
386
387        move noun to clearing;
388
389    which takes the object which has just been moved from the ``player``
390    object to the ``top_of_tree`` object (by the successful ``Drop`` action)
391    and moves it again so that its parent becomes the ``clearing`` object.
392    That ``noun`` is a library variable that always contains the internal ID
393    of the object which is the target of the current action.  If the player
394    types DROP NEST, ``noun`` contains the internal ID of the ``nest``
395    object; if she types DROP NESTLING then ``noun`` contains the internal
396    ID of the ``bird`` object.  Second, we execute::
397
398        return false;
399
400    which tells the interpreter that it should now let the player know
401    what's happened.  Here's the result of all this:
402
403    .. code-block:: transcript
404
405       At the top of the tree
406       You cling precariously to the trunk.
407
408       You can see a wide firm bough here.
409
410       >DROP NEST
411       Dropped.
412
413       >LOOK
414
415       At the top of the tree
416       You cling precariously to the trunk.
417
418       You can see a wide firm bough here.
419
420       >DOWN
421
422       A forest clearing
423       A tall sycamore stands in the middle of this clearing. The path winds
424       southwest through the trees.
425
426       You can see a bird's nest (in which is a baby bird) here.
427
428       >
429
430 Of course, you might think that the standard message "Dropped" is slightly
431 unhelpful in these non-standard circumstances.  If you prefer to hint at
432 what's just happened, you could use this alternative solution:
433
434 .. code-block:: inform6
435
436    Object   top_of_tree "At the top of the tree"
437      with   description "You cling precariously to the trunk.",
438             d_to clearing,
439             after [;
440                Drop:
441                  move noun to clearing;
442                  print_ret "Dropped... to the ground far below.";
443             ],
444      has    light;
445
446 The ``print_ret`` statement does two things for us: displays a more
447 informative message, and returns ``true`` to tell the interpreter that
448 there's no need to let the player know what's happened -- we've handled
449 that ourselves.
450
451 Is the bird in the nest?
452 ========================
453
454 The game ends when the player character puts the nest onto the branch.  Our
455 assumption here is that the bird is inside the nest, but this might not be
456 so; the player may have first taken up the bird and then gone back for the
457 nest, or vice versa.  It would be better not to end the game until we'd
458 checked for the bird actually being in the nest; fortunately, that's easy
459 to do:
460
461 .. code-block:: inform6
462
463    Object   branch "wide firm bough" top_of_tree
464      with   description "It's flat enough to support a small object.",
465             name 'wide' 'firm' 'flat' 'bough' 'branch',
466             each_turn [; if (bird in nest && nest in branch) deadflag = 2; ],
467       has   static supporter;
468
469 The extended ``if`` statement::
470
471     if (bird in nest && nest in branch) deadflag = 2;
472
473 should now be read as: "Test whether the ``bird`` is currently in (or on)
474 the ``nest``, and whether the ``nest`` is currently on (or in) the
475 ``branch``; if both parts are ``true``, set the value of ``deadflag`` to 2;
476 otherwise, do nothing".
477
478 Summing up
479 ==========
480
481 You should by now have some appreciation of the need not only to handle the
482 obvious actions which were at the forefront of your mind when designing the
483 game, but also as many as you can of the other possible ways that a player
484 may choose to interact with the objects presented to her.  Some of those
485 ways will be highly intelligent, some downright dumb; in either case you
486 should try to ensure that the game's response is at least sensible, even
487 when you're telling the player "sorry, you can't do that".
488
489 The new topics that we've encountered here include these:
490
491 .. rubric:: Object properties
492
493 Objects can have a ``before`` property -- if there is one, the interpreter
494 looks at it *before* performing an action which in some way involves that
495 object.  Similarly, you can provide an ``after`` property, which the
496 interpreter looks at *after* performing an action but before telling the
497 player what's happened.  Both ``before`` and ``after`` properties can be
498 used not only with tangible objects like the ``bird``, ``cottage`` and
499 ``tree`` (when they intercept actions aimed at that particular object) but
500 also with rooms (when they intercept actions aimed at any object in that
501 room).
502
503 The value of each ``before`` and ``after`` property is an embedded routine.
504 If such a routine ends with ``return false``, the interpreter then carries
505 on with the next stage of the action which has been intercepted; if it ends
506 with ``return true``, the interpreter does nothing further for that action.
507 By combining these possibilities, you can supplement the work done by a
508 standard action with statements of your own, or you can replace a standard
509 action completely.
510
511 Previously, we've seen connection properties used with the internal ID of
512 the room to which they lead.  In this chapter, we showed that the value
513 could also be a string (explaining why movement in that direction isn't
514 possible).  Here are examples of both, and also of the ``cant_go`` property
515 which provides just such an explanation for *all* connections that aren't
516 explicitly listed::
517
518     e_to forest,
519     in_to "It's such a lovely day -- much too nice to go inside.",
520     cant_go "The only path lies to the east.",
521
522 .. rubric:: Routines and arguments
523
524 The library includes a number of useful routines, available to perform
525 certain common tasks if you require them; there's a list in "Library
526 routines" on page 264.  We used the ``PlayerTo`` routine, which moves the
527 player character from her current room to another one -- not necessarily
528 adjacent to the first room.
529
530 When calling ``PlayerTo``, we had to tell the library which room is the
531 destination.  We did this by supplying that room's internal ID within
532 parentheses, thus::
533
534     PlayerTo(clearing);
535
536 A value given in parentheses like that is called an **argument** of the
537 routine.  In fact, a routine can have more than one argument; if so,
538 they're separated by commas.  For example, to move the player character to
539 a room *without* displaying that room's description, we could have supplied
540 a second argument::
541
542     PlayerTo(clearing,1);
543
544 In this example, the effect of the ``1`` is to prevent the description
545 being displayed.
546
547 .. rubric:: Statements
548
549 We encountered several new statements:
550
551 ``return true;``
552
553 ``return false;``
554     We used these at the end of embedded routines to control what the
555     interpreter did next.
556
557 ``print "string";``
558
559 ``print_ret "string";``
560     The ``print`` statement simply displays the string of characters
561     represented here by *string*.  The ``print_ret`` statement also does
562     that, then outputs a newline character, and finally executes a ``return
563     true;``
564
565 ``if (condition && condition ) ...``
566     We extended the simple ``if`` statement that we met before.  The ``&&``
567     (to be read as "and") is an operator commonly used when testing for
568     more than one condition at the same time.  It means "if this condition
569     is true *and* this condition is also true *and* ..."  There's also a
570     ``||`` operator, to be read as "or", and a "not" operator ``~~``, which
571     turns true into false and vice versa.
572
573     .. note::
574
575        In addition, there are ``&``, ``|`` and ``~`` operators, but they do
576        a rather different job and are much less common.  Take care not to
577        get them confused.
578
579 ``move obj_id to parent_obj_id;``
580      The ``move`` statement rearranges the object tree, by making the first
581      ``obj_id`` a child of the ``parent_obj_id``.
582
583 .. rubric:: Actions
584
585 We've talked a lot about intercepting actions like ``Listen``, ``Enter``,
586 ``Climb`` and ``Drop``.  An action is a generalised representation of
587 something to be done, determined by the verb which the player types.  For
588 example, the verbs HEAR and LISTEN are ways of saying much the same thing,
589 and so both result in the same action: ``Listen``.  Similarly, verbs like
590 ENTER, GET INTO, SIT ON and WALK INSIDE all lead to an action of ``Enter``,
591 CLIMB and SCALE lead to Climb, and DISCARD, DROP, PUT DOWN and THROW all
592 lead to ``Drop``.  This makes life much easier for the designer; although
593 Inform defines quite a lot of actions, there are many fewer than there are
594 ways of expressing those same actions using English verbs.
595
596 Each action is represented internally by a number, and the value of the
597 current action is stored in a library variable called, erm, ``action``.
598 Two more variables are also useful here: ``noun`` holds the internal ID of
599 the object which is the focus of the action, and ``second`` holds the
600 internal ID of the secondary object (if there is one).  Here are some
601 examples of these:
602
603 ===============================    ======     =======   =======
604 Player types                       action     noun      second
605 -------------------------------    ------     -------   -------
606 LISTEN                             Listen     nothing   nothing
607 LISTEN TO THE BIRD                 Listen     bird      nothing
608 PICK UP THE BIRD                   Take       bird      nothing
609 PUT BIRD IN NEST                   Insert     bird      nest
610 DROP THE NEST                      Drop       nest      nothing
611 PUT NEST ON BRANCH                 PutOn      nest      branch
612 ===============================    ======     =======   =======
613
614 The value ``nothing`` is a built-in constant (like ``true`` and ``false``)
615 which means, well, there isn't any object to refer to.  There's a list of
616 standard library actions in "Group 1 actions" on page 270, "Group 2
617 actions" on page 271 and "Group 3 actions" on page 271.
618
619 We've now reached the end of our first game.  In these three chapters we've
620 shown you the basic principles on which almost all games are based, and
621 introduced you to many of the components that you'll need when creating
622 more interesting IF.  We suggest that you take one last look at the source
623 code (see "Heidi" story on page 213), and then move on to the next stage.