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