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