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