Mention in README.md the need for the iftex package and how to get it.
[ibg.git] / chapters / 13.rst
1 ===========================
2 Captain Fate: the final cut
3 ===========================
4
5 .. epigraph::
6
7    | |CENTER| *Y was a youth, that did not love school;*
8    | |CENTER| *Z was a zany, a poor harmless fool.*
9
10 .. only:: html
11
12    .. image:: /images/picY.png
13       :align: left
14
15 |Y|\ou'll probably be pleased to hear that Captain Fate has almost run his
16 allotted span.  There are some minor objects still to be defined -- the
17 toilet, our hero’s clothes, the all-important costume -- but first we need
18 to decorate the café a little more.
19
20 Additional catering garnish
21 ===========================
22
23 We must not forget a couple of tiny details in the café room:
24
25 .. include:: /config/typethis.rst
26
27 .. code-block:: inform
28
29   Object   food "Benny's snacks" cafe
30     with   name 'food' 'pastry' 'pastries' 'sandwich' 'sandwiches' 'snack'
31            before [; "There is no time for FOOD right now."; ],
32     has    scenery proper;
33
34   Object   menu "menu" cafe
35     with   name 'informative' 'menu' 'board' 'picture' 'writing',
36            description
37                "The menu board lists Benny's food and drinks, along with their
38                 prices. Too bad you've never learnt how to read, but luckily
39                 there is a picture of a big cup of coffee among the
40                 incomprehensible writing.",
41            before [;
42              Take:
43                "The board is mounted on the wall behind Benny. Besides, it's
44                 useless WRITING.";
45            ],
46     has    scenery;
47
48 And a not-so-trivial object:
49
50 .. include:: /config/typethis.rst
51
52 .. code-block:: inform
53
54   Object  coffee "cup of coffee" benny
55     with  name 'cup' 'of' 'coffee' 'steaming' 'cappuccino'
56                'cappucino' 'capuccino' 'capucino',
57           description [;
58               if (self in benny)
59                   "The picture on the menu board SURE looks good.";
60               else
61                   "It smells delicious.";
62           ],
63           before [;
64             Take,Drink,Taste:
65               if (self in benny) "You should ask Benny for one first.";
66               else {
67                   move self to benny;
68                   print "You pick up the cup and swallow a mouthful. Benny's
69                          WORLDWIDE REPUTATION is well deserved. Just as you
70                          finish, Benny takes away the empty cup.";
71                   if (benny.coffee_not_paid == true)
72                       " ~That will be one quidbuck, sir.~";
73                   else
74                       "";
75               }
76             Buy:
77               if (coin in player) <<Give coin benny>>;
78               else                "You have no money.";
79             Smell:
80               "If your HYPERACTIVE pituitary glands are to be trusted,
81                it's Colombian.";
82           ];
83
84 There's nothing really new in this object (other than that the :prop:`name`
85 property caters for orthographically challenged players), but notice how we
86 don't ``remove`` it after the player drinks it.  In an apparently absurd
87 whim, the coffee returns to Benny magically (although this is not
88 information that the player needs to know).  Why?  After you remove an
89 object from the game, if the player attempts, say, to EXAMINE it, the
90 interpreter will impertinently state that "You can't see any such thing".
91 Moreover, if the player asks Benny for a second coffee, once the first one
92 has been removed, Benny will complain "I don’t think that’s on the menu,
93 sir" -- a blatant lie -- which was the default in Benny’s orders property.
94 Since the removed coffee object does not belong to Benny, it's not a noun
95 that the player can ASK Benny FOR.  By making it a child of the barman (who
96 has the :attr:`transparent` attribute set), the coffee is still an object
97 that players can refer to.  We ensure that they don't get more cups thanks
98 to Benny's ``coffee_asked_for`` property, which will remain :const:`true`
99 after the first time.
100
101 .. Generated by autoindex
102 .. index::
103    pair: false; library constant
104
105 We also ensure that Benny doesn't ask for money from players who have
106 already paid, by first printing a "You pick up the cup..."  message and
107 then testing Benny's ``coffee_not_paid`` property.  If its value is
108 :const:`true`, we can finish the message with the "quidbuck"
109 print-and-return statement.  If its value is :const:`false`, the player has
110 previously paid, and so there's nothing else to say.  However, we still
111 need to terminate the incomplete message with a newline, and to return
112 :const:`true` from the property routine; we *could* have used the
113 statements ``{ print "^"; return true; }``, but an empty ``""`` statement
114 does the same thing more neatly.
115
116 Toilet or dressing room?
117 ========================
118
119 Rather more of the latter, actually, since it's the only place away from
120 curious eyes where our hero will be able to metamorphose from weakling into
121 the bane of all evildoers.  And we *really* don't want to become, erm,
122 bogged down with details of the room's function or plumbing.
123
124 There's not a lot about the toilet room and its contents, though there will
125 be some tricky side effects:
126
127 .. include:: /config/typethis.rst
128
129 .. code-block:: inform
130
131   Room    toilet "Unisex toilet"
132     with  description
133               "A surprisingly CLEAN square room covered with glazed-ceramic
134                tiles, featuring little more than a lavatory and a light switch.
135                The only exit is south, through the door and into the cafe.",
136           s_to toilet_door,
137     has   ~light scored;
138
139   Appliance lavatory "lavatory" toilet
140     with name 'lavatory' 'wc' 'toilet' 'loo' 'bowl' 'can' 'john' 'bog',
141          before [;
142            Examine,Search,LookUnder:
143              if (coin in self) {
144                  move coin to parent(self);
145                  "The latest user CIVILLY flushed it after use, but failed to
146                   pick up the VALUABLE coin that fell from his pants.";
147              }
148            Receive:
149              "While any other MORTALS might unwittingly throw just about
150               ANYTHING into ", (the) self, ", you remember the WISE teachings
151               of your mentor, Duke ELEGANT, about elderly plumbing and rising
152               waters.";
153          ];
154
155   Object  coin "valuable coin" lavatory
156     with  name 'valuable' 'coin' 'silver' 'quidbuck',
157           description "It's a genuine SILVER QUIDBUCK.",
158           before [;
159             Drop:
160               if (self notin player) return false;
161               "Such a valuable coin? Har, har! This must be a demonstration of
162                your ULTRA-FLIPPANT jesting!";
163           ],
164           after [;
165             Take:
166               "You crouch into the SLEEPING DRAGON position and deftly, with
167                PARAMOUNT STEALTH, you pocket the lost coin.";
168           ],
169     has   scored;
170
171 We initially place the coin as a child of the lavatory (just so that we can
172 easily make the ``if (coin in self)`` one-time test).  Since the lavatory
173 does not have the :attr:`transparent` attribute set, the coin will be
174 invisible to players until they try to inspect the lavatory, an action that
175 will move the coin into the toilet room.  Once taken, the coin will remain
176 in the inventory until the player gives it to Benny, because we trap any
177 :act:`Drop` actions to help the player to Do the Right Thing.
178
179 The lavatory object includes a load of helpful synonyms in its name
180 property, including our favourite word ``'toilet'`` .  That won't be a
181 problem: the other objects here which may have TOILET in their names -- the
182 key and the door -- both use the ``pname`` property to turn their use of
183 ``'toilet'`` into a lower-priority adjective.
184
185 .. Generated by autoindex
186 .. index::
187    pair: scored; library attribute
188
189 See that here we have the only two :attr:`scored` attributes of the game.
190 The player will be awarded one point for entering the toilet room, and
191 another for finding and picking up the coin.
192
193 .. Generated by autoindex
194 .. index::
195    pair: light; library attribute
196
197 You might have noticed that we are forcefully clearing the :attr:`light`
198 attribute, inherited from the ``Room`` class.  This will be a windowless
199 space and, to add a touch of realism, we'll make the room a dark one, which
200 will enable us to tell you about Inform's default behaviour when there's no
201 light to see by.  However, let's define first the light switch mentioned in
202 the room's description to aid players in their dressing duties.
203
204 .. include:: /config/typethis.rst
205
206 .. code-block:: inform
207
208   Appliance  light_switch "light switch" toilet
209     with     name 'light' 'switch',
210              description
211                  "A notorious ACHIEVEMENT of technological SCIENCE, elegant yet
212                   EASY to use.",
213              before [;
214                Push:
215                  if (self has on) <<SwitchOff self>>;
216                  else             <<SwitchOn  self>>;
217              ],
218              after [;
219                SwitchOn:
220                  give self light;
221                  "You turn on the light in the toilet.";
222                SwitchOff:
223                  give self ~light;
224                  "You turn off the light in the toilet.";
225              ],
226     has      switchable ~on;
227
228 Please notice the appearance of new attributes :attr:`switchable` and
229 :attr:`on`.  :attr:`switchable` enables the object to be turned on and off,
230 and is typical of lanterns, computers, television sets, radios, and so on.
231 The library automatically extends the description of these objects by
232 indicating if they are currently on or off:
233
234 .. code-block:: transcript
235
236   > X LIGHT SWITCH
237   A notorious ACHIEVEMENT of technological SCIENCE, elegant yet EASY to use.
238   The light switch is currently switched on.
239
240 Two new actions are ready to use, :act:`SwitchOn` and :act:`SwitchOff`.
241 Left to themselves, they toggle the object's state between ON and OFF and
242 display a message like:
243
244 .. code-block:: transcript
245
246   You switch the brass lantern on.
247
248 They also take care of checking if the player fumbled and tried to turn on
249 (or off) an object which was already on (or off).  How does the library
250 know the state of the object?  This is thanks to the :attr:`on` attribute,
251 which is set or cleared automatically as needed.  You can, of course, set
252 or clear it manually like any other attribute, with the ``give`` statement:
253
254 .. code-block:: inform
255
256   give self on;
257
258   give self ~on;
259
260 and check if a :attr:`switchable` object is on or off with the test:
261
262 .. code-block:: inform
263
264   if (light_switch has on) ...
265
266   if (light_switch hasnt on) ...
267
268 A :attr:`switchable` object is OFF by default.  However, you’ll notice that
269 the has line of the object definition includes ``~on`` :
270
271 .. code-block:: inform
272
273   has    switchable ~on;
274
275 Surely that’s saying "not-on"?  Surely that's what would have happened
276 anyway if the line hadn't mentioned the attribute at all?
277
278 .. code-block:: inform
279
280   has    switchable;
281
282 Absolutely true.  Adding that ``~on`` attribute has no effect whatsoever on
283 the game -- but nevertheless it's a good idea.  It's an aide-mémoire, a way
284 of reminding ourselves that we start with the attribute clear, and that at
285 some point we'll be setting it for some purpose.  Trust us: it's worthwhile
286 taking tiny opportunities like this to help yourself.
287
288 .. Generated by autoindex
289 .. index::
290    pair: after; library property
291
292 Let’s see how our light switch works.  We trap the :act:`SwitchOn` and
293 :act:`SwitchOff` actions in the :prop:`after` property (when the switching
294 has successfully taken place) and use them to give :attr:`light` to the
295 light switch.
296
297 Uh, wait.  To the light switch?  Why not to the toilet room?  Well, there's
298 a reason and we'll see it in a minute.  For now, just remember that, in
299 order for players to see their surroundings, you need only one object in a
300 room with the :attr:`light` attribute set.  It doesn't have to be the room
301 itself (though this is usually convenient).
302
303 After setting the :attr:`light` attribute, we display a customised message,
304 to avoid the default:
305
306 .. code-block:: transcript
307
308   You switch the light switch on.
309
310 which, given the name of the object, doesn't read very elegantly.  We
311 foresee that players might try to PUSH SWITCH, so we trap this attempt in a
312 :prop:`before` property and redirect it to :act:`SwitchOn` and
313 :act:`SwitchOff` actions, checking first which one is needed by testing the
314 :attr:`on` attribute.  Finally, we have made the switch a member of the
315 class ``Appliance``, so that the player doesn't walk away with it.
316
317 .. note::
318
319   Remember what we said about class inheritance?  No matter what you define
320   in the class, the object’s definition has priority.  The class
321   ``Appliance`` defines a response for the :act:`Push` action, but we
322   override it here with a new behaviour.
323
324 And there was light
325 ===================
326
327 So the player walks into the toilet and
328
329 .. code-block:: transcript
330
331   Darkness
332   It is pitch dark, and you can't see a thing.
333
334 Oops!  No toilet description, no mention of the light switch, nothing.  It
335 is reasonable to think that if we have opened the toilet door to access the
336 toilet, some light coming from the café room will illuminate our
337 surroundings -- at least until the player decides to close the door.  So
338 perhaps it would be a good idea to append a little code to the door object
339 to account for this.  A couple of lines in the after property will suffice:
340
341 .. include:: /config/typethis.rst
342
343 .. code-block:: inform
344
345   after [ ks;
346     Unlock:
347       if (self has locked) return false;
348       print "You unlock ", (the) self, " and open it.^";
349       ks = keep_silent; keep_silent = true;
350       <Open self>; keep_silent = ks;
351       return true;
352     Open:
353       give toilet light;
354     Close:
355       give toilet ~light;
356
357   ],
358
359 And this is the reason why the light switch didn't set the :attr:`light`
360 attribute of the toilet room, but did it to itself.  We avoid running into
361 trouble if we let the open/closed states of the door control the light of
362 the room object, and the on/off states of the switch control the light of
363 the switch.  So it is one shiny light switch.  Fortunately, players are
364 never aware of this glowing artefact.
365
366 .. note::
367
368   Now, could they?  Well, if players could TAKE the light switch (which we
369   have forbidden) and then did INVENTORY, the trick would be given away,
370   because all objects with the :attr:`light` attribute set are listed as
371   ``(providing light)`` .
372
373 So the player walks into the toilet and
374
375 .. code-block:: transcript
376
377   Unisex toilet
378   A surprisingly CLEAN square room covered with glazed-ceramic tiles, featuring
379   little more than a lavatory and a light switch. The only exit is south, through
380   the door and into the cafe.
381
382   [Your score has just gone up by one point.]
383
384 Better.  Now, suppose the player closes the door.
385
386 .. code-block:: transcript
387
388   >CLOSE DOOR
389   You close the door to the cafe.
390
391   It is now pitch dark in here!
392
393 The player might try then to LOOK:
394
395 Well, no problem.  We have mentioned that there is a light switch.  Surely 
396 the player will now try to:
397
398 .. code-block:: transcript
399
400   >TURN ON LIGHT SWITCH
401   You can't see any such thing.
402
403 Oops!  Things are getting nasty here in the dark.  It's probably time to
404 leave this place and try another approach:
405
406 .. code-block:: transcript
407
408   >OPEN DOOR
409   You can't see any such thing.
410
411 And this illustrates one of the terrible things about darkness in a game.
412 You can't see anything; you can do very little indeed.  All objects except
413 those in your inventory are out of scope, unreachable, as if non-existent.
414 Worse, if you DROP one of the objects you are carrying, it will be
415 swallowed by the dark, never to be found until there is light to see by.
416
417 The player, who is doubtless immersed in the fantasy of the game, will now
418 be a little annoyed.  "I am in a small bathroom and I can't even reach the
419 door I have just closed?"  The player's right, of course [#dark]_.
420 Darkened rooms are one cliché of traditional games.  Usually you move in
421 one direction while looking for treasure in some underground cave, and
422 suddenly arrive at a pitch black place.  It's good behaviour of the game to
423 disallow exploration of unknown dark territory, and it's a convention to
424 bar passage to players until they return with a light source.  However, if
425 the scenario of the game features, say, the player character's home, a
426 little apartment with two rooms, and there’s no light in the kitchen, we
427 could expect the owner of the house to know how to move around a little,
428 perhaps groping for the light switch or even going to the refrigerator in
429 the dark.
430
431 We are in a similar situation.  The inner logic of the game demands that
432 blind players should be able to open the door and probably operate the
433 light switch they've just encountered.  We have been telling you that an
434 object is in scope when it’s in the same room as the player.  Darkness
435 changes that rule.  All objects not directly carried by the player become
436 out of scope.
437
438 One of the advantages of an advanced design system like Inform is the
439 flexibility to change all default behaviours to suit your particular needs.
440 Scope problems are no different.  There is a set of routines and functions
441 to tamper with what's in scope when.  We'll see just a tiny example to fix
442 our particular problem.  In the section "``Entry point routines``" of our
443 game -- after the ``Initialise`` routine, for instance -- include the
444 following lines:
445
446 .. code-block:: inform
447
448   [ InScope person;
449       if (person == player && location == thedark && real_location == toilet) {
450           PlaceInScope(light_switch);
451           PlaceInScope(toilet_door);
452       }
453       return false;
454   ];
455
456 :samp:`InScope({actor_obj_id})` is an entry point routine that can tamper
457 with the scope rules for the given :samp:`{actor_obj_id}` (either the
458 player character or a NPC).  We define it with one variable (which we name
459 as we please; it's also a good idea to name variables in an intuitive way
460 to remind us of what they represent), ``person`` , and then we make a
461 complex test to see if the player is actually in the toilet and in the
462 dark.
463
464 .. Generated by autoindex
465 .. index::
466    pair: location; library variable
467    pair: real_location; library variable
468
469 We have told you that the library variable :var:`location` holds the
470 current room that the player is in.  However, when there is no light, the
471 variable location gets assigned to the value of the special library object
472 thedark .  It doesn't matter if we have ten dark rooms in our game;
473 location will be equal to thedark in all of them.  There is yet another
474 variable, called :var:`real_location`, which holds the room the player is
475 in *even when there is no light to see by*.
476
477 So the test:
478
479 .. code-block:: inform
480
481   if (person == player && location == thedark && real_location == toilet) ...
482
483 is stating: if the specified actor is the :var:`player` character *and* he
484 finds himself in the dark *and* he actually happens to be in the toilet...
485
486 .. Generated by autoindex
487 .. index::
488    pair: true; library constant
489
490 Then we make a call to one of the library routines,
491 :samp:`PlaceInScope({obj_id})`, which has a very descriptive name: it
492 places in scope the given object.  In our case, we want both the door and
493 the light switch to be within reach of the player, hence both additional
494 lines.  Finally, we must ``return false``, because we want the normal scope
495 rules for the defined actor -- the player -- to apply to the rest of the
496 objects of the game (if we returned :const:`true`, players would find that
497 they are able to interact with very little indeed).  Now we get a
498 friendlier and more logical response:
499
500 .. code-block:: transcript
501
502   Darkness
503   It is pitch dark, and you can't see a thing.
504
505   >TURN ON SWITCH
506   You turn on the light in the toilet.
507
508   Unisex toilet
509   A surprisingly CLEAN square room covered with glazed-ceramic tiles, featuring
510   little more than a lavatory and a light switch. The only exit is south, through
511   the door and into the cafe.
512
513 And the same would happen with the door.  Notice how the room description
514 gets displayed after we pass from dark to light; this is the normal library
515 behaviour.
516
517 There is still one final problem which, admittedly, might originate from an
518 improbable course of action; however, it could be a nuisance.  Suppose that
519 the player enters the toilet, locks the door -- which is possible in the
520 dark now that the door is in scope -- and then drops the key.  There's no
521 way to exit the toilet -- because the door is locked and the key has
522 disappeared, engulfed by the darkness -- unless the player thinks to turn
523 on the light switch, thereby placing the key in scope once more.
524
525 Why don't we add a :samp:`PlaceInScope({toilet_key})` to the above routine?
526 Well, for starters, the key can be moved around (as opposed to the door or
527 the light switch, which are fixed items in the toilet room).  Suppose the
528 player opens the door of the toilet, but drops the key in the café, then
529 enters the toilet and closes the door.  The condition is met and the key is
530 placed in scope, when it's in another room.  Second, this is a simple game
531 with just a few objects, so you can define a rule for each of them; but in
532 any large game, you might like to be able to refer to objects in bunches,
533 and make general rules that apply to all (or some) of them.
534
535 .. Generated by autoindex
536 .. index::
537    pair: moved; library attribute
538    pair: scenery; library attribute
539    pair: static; library attribute
540
541 We need to add code to the ``InScope`` routine, telling the game to place
542 in scope all objects that we drop in the dark, so that we might recover
543 them (maybe going on all fours and groping a little, but it’s a possible
544 action).  We don’t want the player to have other objects in scope (like the
545 coin, for instance), so it might be good to have a way of testing if the
546 objects have been touched and carried by the player.  The attribute
547 :attr:`moved` is perfect for this.  The library sets it for every object
548 that the player has picked up at one time in the game; :attr:`scenery` and
549 :attr:`static` objects, and those we have not yet seen don't have
550 :attr:`moved`.  Here is the reworked ``InScope`` routine.  There are a
551 couple of new concepts to look at:
552
553 .. include:: /config/typethis.rst
554
555 .. code-block:: inform
556
557   [ InScope person item;
558       if (person == player && location == thedark && real_location == toilet) {
559           PlaceInScope(light_switch);
560           PlaceInScope(toilet_door);
561       }
562       if (person == player && location == thedark)
563           objectloop (item in parent(player))
564               if (item has moved) PlaceInScope(item);
565       return false;
566   ];
567
568 We have added one more local variable to the routine, ``item`` -- again,
569 this is a variable we have created and named on our own; it is not part of
570 the library.  We make now a new test: if the actor is the player and the
571 location is any dark room, then perform a certain action.  We don't need to
572 specify the toilet, because we want this rule to apply to all dark rooms
573 (well, the only dark room in the game *is* the toilet, but we are trying to
574 provide a general rule).
575
576    :samp:`objectloop (variable) {statement};`
577
578 is a loop statement, one of the four defined in Inform.  A loop statement
579 is a construct that allows you to run several times through a statement (or
580 a statement block).  ``objectloop`` performs the :samp:`{statement}` once
581 for every object defined in the (:samp:`{variable}`) .  If we were to code:
582
583    :samp:`objectloop (item) {statement};`
584
585 then the :samp:`{statement}` would be executed once for each object in the
586 game.  However, we want to perform the statement only for those objects
587 whose parent object is the same as the player's parent object: that is, for
588 objects in the same room as the player, so we instead code:
589
590    :samp:`objectloop (item in parent(player)) {statement};`
591
592 What is the actual :samp:`{statement}` that we'll repeatedly execute?
593
594 .. code-block:: inform
595
596   if (item has moved)
597       PlaceInScope(item);
598
599 The test: ``if (item has moved)`` ensures that ``PlaceInScope(item)`` deals
600 only with objects with the :attr:`moved` attribute set.  So: if the player
601 is in the dark, let’s go through the objects which are in the same room,
602 one at a time.  For each of them, check if it's an item that the player has
603 at some time carried, in which case, place it in scope.  All dropped
604 objects within the room were carried at one time, so we let players
605 recollect them even if they can’t see them.
606
607 As you see, darkness has its delicate side.  If you plan to have dark rooms
608 galore in your games, bear in mind that you are in for some elaborate code
609 (unless you let the library carry on with default rules, in which case
610 there won't be much for your players to do).
611
612 Amazing techicolour dreamcoats
613 ==============================
614
615 This leaves us the clothing items themselves, which will require a few
616 tailored actions.  Let's see first the ordinary garments of John Covarth:
617
618 .. include:: /config/typethis.rst
619
620 .. code-block:: inform
621
622   Object  clothes "your clothes"
623     with  name 'ordinary' 'street' 'clothes' 'clothing',
624           description
625               "Perfectly ORDINARY-LOOKING street clothes for a NOBODY like
626                John Covarth.",
627           before [;
628             Wear:
629               if (self has worn)
630                   "You are already dressed as John Covarth.";
631               else
632                   "The town NEEDS the power of Captain FATE, not the anonymity
633                    of John Covarth.";
634             Change,Disrobe:
635               if (self hasnt worn)
636                  "Your KEEN eye detects that you're no longer wearing them.";
637               switch (location) {
638                 street:
639                   if (player in booth)
640                       "Lacking Superman's super-speed, you realise that it
641                        would be awkward to change in plain view of the passing
642                        pedestrians.";          
643                   else
644                       "In the middle of the street? That would be a PUBLIC
645                        SCANDAL, to say nothing of revealing your secret
646                        identity.";
647                 cafe:
648                       "Benny allows no monkey business in his establishment.";
649                 toilet:
650                   if (toilet_door has open)
651                       "The door to the bar stands OPEN at tens of curious eyes.
652                        You'd be forced to arrest yourself for LEWD conduct.";
653                   print "You quickly remove your street clothes and bundle them
654                          up together into an INFRA MINUSCULE pack ready for easy
655                          transportation. ";
656                   if (toilet_door has locked) {
657                       give clothes ~worn; give costume worn;
658                       "Then you unfold your INVULNERABLE-COTTON costume and
659                        turn into Captain FATE, defender of free will, adversary
660                        of tyranny!";
661                   }
662                   else {
663                       deadflag = 3;
664                       "Just as you are slipping into Captain FATE's costume,
665                        the door opens and a young woman enters. She looks at
666                        you and starts screaming, ~RAPIST! NAKED RAPIST IN THE
667                        TOILET!!!~^^
668                        Everybody in the cafe quickly comes to the rescue, only
669                        to find you ridiculously jumping on one leg while trying
670                        to get dressed. Their laughter brings a QUICK END to
671                        your crime-fighting career!";
672                   }
673                 thedark:
674                   "Last time you changed in the dark, you wore the suit inside
675                    out!";
676                 default:                  ! this _should_ never happen...
677                   "There must be better places to change your clothes!";
678               }
679           ],
680     clothing proper pluralname;
681
682 See how the object deals only with :act:`Wear`, :act:`Disrobe` and
683 :act:`Change`.  :act:`Wear` and :act:`Disrobe` are standard library actions
684 already defined in Inform, but we'll have to make a new verb to allow for
685 CHANGE CLOTHES.  In this game, :act:`Disrobe` and :act:`Change` are
686 considered synonymous for all purposes; we'll deal with them first.
687
688 .. Generated by autoindex
689 .. index::
690    pair: location; library variable
691    pair: worn; library attribute
692
693 The goal of the game is for players to change their clothes, so we might
694 expect them to try this almost anywhere; but first of all we have to check
695 that the ``clothes`` object is actually being worn.  If not, we display a
696 message reminding the player that this action has become irrelevant.  What
697 we do with the ``switch`` statement is to offer a variety of responses
698 according to the :var:`location` variable.  The street (in or out of the
699 booth) and the café all display refusals of some kind, until the player
700 character manages to enter the toilet, where we additionally require that
701 he locks the door before taking off his clothes.  If the door is closed but
702 not locked, he is interrupted in his naked state by a nervous woman who
703 starts shouting, and the game is lost (this is not as unfair as it seems,
704 because the player may always revert to the previous state with UNDO).  If
705 the door is locked, he succeeds in his transformation (we take away the
706 :attr:`worn` attribute from the ``clothes`` and give it to the ``costume``
707 instead).  We add a special refusal to change in the dark, forcing players
708 to turn on the light and then, we hope, to find the coin.  And finally we
709 code a ``default`` entry; you'll remember that, in a ``switch`` statement,
710 this is supposed to cater for any value not explicitly listed for the
711 expression under control -- in this case, for the variable :var:`location`.
712 Since we have already gone through all the possible locations of the game,
713 this entry appears only as a defensive measure, just in case something
714 unexpected happens (for instance, we might extend the game with another
715 room and forget about this ``switch`` statement).  In normal and controlled
716 conditions, it should never be reached, but it doesn't hurt one bit to have
717 it there.
718
719 The :act:`Wear` action just checks if these clothes are already being worn,
720 to offer two different rejection responses: the goal of the game is to
721 change into the hero's suit, after which we'll prevent a change back into
722 ordinary clothes.  So now we are dealing with a Captain Fate in full
723 costume:
724
725 .. include:: /config/typethis.rst
726
727 .. code-block:: inform
728
729   Object   costume "your costume"
730     with   name 'captain' 'captain^s' 'fate' 'fate^s' 'costume' 'suit',
731            description
732                "STATE OF THE ART manufacture, from chemically reinforced 100%
733                 COTTON-lastic(tm).",
734            before [;
735              Wear:
736                if (self has worn)
737                    "You are already dressed as Captain FATE.";
738                else
739                    "First you'd have to take off your commonplace unassuming
740                     John Covarth INCOGNITO street clothes.";
741              Change,Disrobe:
742                if (self has worn)
743                    "You need to wear your costume to FIGHT crime!";
744                else
745                    "But you're not yet wearing it!";
746              Drop:
747                "Your UNIQUE Captain FATE multi-coloured costume? The most
748                 coveted clothing ITEM in the whole city? Certainly NOT!";
749            ],
750     has    clothing proper;
751
752 Note that we intercept the action WEAR COSTUME and hint that players should
753 try TAKE OFF CLOTHES instead.  We don't let them take off the costume once
754 it’s being worn, and we certainly don't let them misplace it anywhere, by
755 refusing to accept a :act:`Drop` action.
756
757 It's a wrap
758 ===========
759
760 Nearly there; just a few minor odds and ends to round things off.
761
762 .. rubric:: Initialise routine
763
764 All the objects of our game are defined.  Now we must add a couple of lines
765 to the ``Initialise`` routine to make sure that the player does not start
766 the game naked:
767
768 .. include:: /config/typethis.rst
769
770 .. code-block:: inform
771
772   [ Initialise;
773       #Ifdef DEBUG; pname_verify(); #Endif;       ! suggested by pname.h
774       location = street;
775       move costume to player;
776       move clothes to play; give clothes worn;
777       lookmode = 2;
778       "^^Impersonating mild mannered John Covarth, assistant help boy at an
779        insignificant drugstore, you suddenly STOP when your acute hearing
780        deciphers a stray radio call from the POLICE. There's some MADMAN
781        attacking the population in Granary Park! You must change into your
782        Captain FATE costume fast...!^^";
783   ];
784
785 Remember that we included a disambiguation package, ``pname.h``?  There
786 were some additional comments in the accompanying text file that should be
787 taken in consideration:
788
789   pname.h provides a pname_verify routine.  When DEBUG is defined, you may
790   call pname_verify() in your Initialise() routine to verify the pname
791   properties in your objects.
792
793 The designer of the package has made a debugging tool (a routine) to check
794 for errors when using his library, and he tells us how to use it.  So we
795 include the suggested lines into our ``Initialise`` routine:
796
797 .. code-block:: inform
798
799   #Ifdef DEBUG; pname_verify(); #Endif;
800
801 As the text explains, what this does is: first check whether the game is
802 being compiled in Debug mode; if this is the case, run the ``pname_verify``
803 routine, so that it tests all ``pname`` properties to see if they are
804 written correctly.
805
806 .. rubric:: Demise of our hero
807
808 We have made three possible endings:
809
810 #. The player attempts to change in the toilet with an unlocked door.
811
812 #. The player tries to attack Benny while wearing the costume.
813
814 #. The player manages to exit the café dressed as Captain Fate.
815
816 (1) and (2) lose the game, (3) wins it.  The library defaults for these two
817 states display, respectively,
818
819 .. code-block:: transcript
820
821   *** You have died ***
822
823   *** You have won ***
824
825 These states correspond to the values of the :var:`deadflag` variable: 1
826 for losing, 2 for winning.  However, we have made up different messages,
827 because our hero does not really die -- ours suffers a FATE worse than
828 death -- and because we want to give him a more descriptive winning line.
829 Therefore, we must define a ``DeathMessage`` routine as we did in "William
830 Tell", to write our customised messages and assign them to :var:`deadflag`
831 values greater than 2.
832
833 .. include:: /config/typethis.rst
834
835 .. code-block:: inform
836
837   [ DeathMessage;
838       if (deadflag == 3) print "Your secret identity has been revealed";
839       if (deadflag == 4) print "You have been SHAMEFULLY defeated";
840       if (deadflag == 5) print "You fly away to SAVE the DAY";
841   ];
842
843 .. rubric:: Grammar
844
845 Finally, we need to extend the existing grammar, to allow for a couple of
846 things.  We have already seen that we need a verb CHANGE.  We'll make it
847 really simple:
848
849 .. include:: /config/typethis.rst
850
851 .. code-block:: inform
852
853   [ ChangeSub;
854       if (noun has pluralname) print "They're";
855       else                     print "That's";
856       " not something you must change to save the day.";
857   ];
858
859   Verb 'change' 'exchange' 'swap' 'swop'
860       * noun                     -> Change;
861
862 Just notice how the verb handler checks whether the noun given is plural or
863 singular, to display a suitable pronoun.
864
865 A further detail: when players are in the café, they might ask Benny for
866 the coffee (as we intend and heavily hint), for a sandwich or a pastry
867 (both mentioned in the café description), for food or a snack (mentioned
868 here and there, and we have provided for those); but what if they try a
869 meat pie?  Or scrambled eggs?  There’s just so much decoration one can
870 reasonably insert in a game, and loading the dictionary with Benny’s full
871 menu would be overdoing it a bit.
872
873 .. Generated by autoindex
874 .. index::
875    pair: Give; library action
876
877 One might reasonably imagine that the ``default`` line at the end of the
878 :act:`Give` action in the orders property handles every input not already
879 specified:
880
881 .. code-block:: inform
882
883   orders [;
884     Give:
885       switch (noun) {
886         toilet_key:  ! code for the key...
887         coffee:      ! code for the coffee...
888         food:        ! code for the food...
889         menu:        ! code for the menu...
890         default:
891           "~I don't think that's on the menu, sir.~";
892       }
893   ],
894
895 Not so.  The library grammar that deals with ASK BENNY FOR... is this
896 (specifically, the last line):
897
898 .. code-block:: inform
899
900   Verb 'ask'
901       * creature 'about' topic    -> Ask
902       * creature 'for' noun       -> AskFor
903
904 You'll see the :var:`noun` token, which means that whatever the player asks
905 him for must be a real game object, visible at that moment.  Assuming that
906 the player mentions such an object, the interpreter finds it in the
907 dictionary and places its internal ID in the :var:`noun` variable, where
908 our ``switch`` statement can handle it.  So, ASK BENNY FOR KEY assigns the
909 ``toilet_key`` object to the noun variable, and Benny responds.  ASK BENNY
910 FOR CUSTOMERS also works; the ``default`` case picks that one up.  But, ASK
911 BENNY FOR SPAGHETTI BOLOGNESE won't work: we have no object for Spaghetti
912 Bolognese (or any other delicacy from Benny's kitchen) -- the words
913 ``'spaghetti'`` and ``'bolognese'`` simply aren't in the dictionary.  This
914 is perhaps not a major deficiency in our game, but it takes very little to
915 allow Benny to use his default line for *any* undefined input from the
916 player.  We need to extend the existing ASK grammar:
917
918 .. include:: /config/typethis.rst
919
920 .. code-block:: inform
921
922   Extend 'ask'
923       * creature 'for' topic    -> AskFor;
924
925 This line will be added to the end of the existing grammar for Ask, so it
926 doesn’t override the conventional noun-matching line.  ``topic`` is a token
927 that roughly means "any input at all"; the value of noun isn't important,
928 because it'll be handled by the default case.  Now players may ask Benny
929 for a tuna sandwich or a good time; they'll get: "I don’t think that’s on
930 the menu, sir", which makes Benny a barman with attitude.
931
932 And that's it; on the slightly surreal note of ASK BENNY FOR A GOOD TIME
933 we've taken "Captain Fate" as far as we intend to.  The guide is nearly
934 done.  All that's left is to recap some of the more important issues, talk
935 a little more about compilation and debugging, and send you off into the
936 big wide world of IF authorship.
937
938 .. rubric:: Footnotes
939
940 .. [#dark]
941    We're alluding here to the Classical concept of mimesis.  In an
942    oft-quoted essay from 1996, Roger Giner-Sorolla wrote: "I see successful
943    fiction as an imitation or 'mimesis' of reality, be it this world's or
944    an alternate world's.  Well-written fiction leads the reader to
945    temporarily enter and believe in the reality of that world.  A crime
946    against mimesis is any aspect of an IF game that breaks the coherence of
947    its fictional world as a representation of reality."