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