Add special RST roles for the Inform entities.
[ibg.git] / chapters / 13.rst
index 3eb00a7d0c8ab6ccd1c456b2d3633afb219e4275..d4c86424f3f91a115d0d66bb60f4e8f82c4e637f 100644 (file)
@@ -4,29 +4,25 @@ Captain Fate: the final cut
 
 .. epigraph::
 
-   | *Y was a youth, that did not love school;*
-   | *Z was a zany, a poor harmless fool.*
+   | |CENTER| *Y was a youth, that did not love school;*
+   | |CENTER| *Z was a zany, a poor harmless fool.*
 
 .. only:: html
 
    .. image:: /images/picY.png
       :align: left
 
-.. raw:: latex
-
-   \dropcap{y}
-
-ou'll probably be pleased to hear that Captain Fate has almost run his 
-allotted span. There are some minor objects still to be defined -- the 
-toilet, our hero’s clothes, the all-important costume -- but first we 
-need to decorate the café a little more.
+|Y|\ou'll probably be pleased to hear that Captain Fate has almost run his
+allotted span. There are some minor objects still to be defined -- the
+toilet, our hero’s clothes, the all-important costume -- but first we need
+to decorate the café a little more.
 
 Additional catering garnish
 ===========================
 
 We must not forget a couple of tiny details in the café room:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Object   food "Benny's snacks" cafe
     with   name 'food' 'pastry' 'pastries' 'sandwich' 'sandwiches' 'snack'
@@ -49,7 +45,7 @@ We must not forget a couple of tiny details in the café room:
 
 And a not-so-trivial object:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Object  coffee "cup of coffee" benny
     with  name 'cup' 'of' 'coffee' 'steaming' 'cappuccino'
@@ -81,7 +77,7 @@ And a not-so-trivial object:
                it's Colombian.";
           ];
 
-There's nothing really new in this object (other than that the ``name`
+There's nothing really new in this object (other than that the :prop:`name
 property caters for orthographically challenged players), but notice how 
 we don't ``remove`` it after the player drinks it. In an apparently 
 absurd whim, the coffee returns to Benny magically (although this is not 
@@ -93,18 +89,18 @@ first one has been removed, Benny will complain "I don’t think that’s on
 the menu, sir" -- a blatant lie -- which was the default in Benny’s 
 orders property. Since the removed coffee object does not belong to 
 Benny, it's not a noun that the player can ASK Benny FOR. By making it a 
-child of the barman (who has the ``transparent`` attribute set), the 
+child of the barman (who has the :attr:`transparent` attribute set), the 
 coffee is still an object that players can refer to. We ensure that they 
-don't get more cups thanks to Benny's ``coffee_asked_for property``
-which will remain ``true`` after the first time.
+don't get more cups thanks to Benny's ``coffee_asked_for`` property
+which will remain :const:`true` after the first time.
 
 We also ensure that Benny doesn't ask for money from players who have 
 already paid, by first printing a "You pick up the cup..." message and 
 then testing Benny's ``coffee_not_paid`` property. If its value is 
-``true``, we can finish the message with the "quidbuck" print-and-return 
-statement. If its value is ``false``, the player has previously paid, 
+:const:`true`, we can finish the message with the "quidbuck" print-and-return 
+statement. If its value is :const:`false`, the player has previously paid, 
 and so there's nothing else to say. However, we still need to terminate 
-the incomplete message with a newline, and to return ``true`` from the 
+the incomplete message with a newline, and to return :const:`true` from the 
 property routine; we *could* have used the statements ``{ print "^"; 
 return true; }``, but an empty ``""`` statement does the same thing more 
 neatly.
@@ -121,7 +117,7 @@ erm, bogged down with details of the room's function or plumbing.
 There's not a lot about the toilet room and its contents, though there 
 will be some tricky side effects:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Room    toilet "Unisex toilet"
     with  description
@@ -165,7 +161,7 @@ will be some tricky side effects:
 
 We initially place the coin as a child of the lavatory (just so that we 
 can easily make the ``if (coin in self)`` one-time test). Since the 
-lavatory does not have the ``transparent`` attribute set, the coin will 
+lavatory does not have the :attr:`transparent` attribute set, the coin will 
 be invisible to players until they try to inspect the lavatory, an 
 action that will move the coin into the toilet room. Once taken, the 
 coin will remain in the inventory until the player gives it to Benny, 
@@ -178,11 +174,11 @@ problem: the other objects here which may have TOILET in their names --
 the key and the door -- both use the ``pname`` property to turn their 
 use of ``'toilet'`` into a lower-priority adjective.
 
-See that here we have the only two ``scored`` attributes of the game. 
+See that here we have the only two :attr:`scored` attributes of the game. 
 The player will be awarded one point for entering the toilet room, and 
 another for finding and picking up the coin.
 
-You might have noticed that we are forcefully clearing the ``light`
+You might have noticed that we are forcefully clearing the :attr:`light
 attribute, inherited from the ``Room`` class. This will be a windowless 
 space and, to add a touch of realism, we'll make the room a dark one, 
 which will enable us to tell you about Inform's default behaviour when 
@@ -190,7 +186,7 @@ there's no light to see by. However, let's define first the light switch
 mentioned in the room's description to aid players in their dressing 
 duties.
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Appliance  light_switch "light switch" toilet
     with     name 'light' 'switch',
@@ -212,11 +208,13 @@ duties.
              ],
     has      switchable ~on;
 
-Please notice the appearance of new attributes ``switchable`` and 
-``on``. switchable enables the object to be turned on and off, and is 
+Please notice the appearance of new attributes :attr:`switchable` and 
+:attr:`on`. switchable enables the object to be turned on and off, and is 
 typical of lanterns, computers, television sets, radios, and so on. The 
 library automatically extends the description of these objects by 
-indicating if they are currently on or off::
+indicating if they are currently on or off:
+
+.. code-block:: transcript
 
   > X LIGHT SWITCH
   A notorious ACHIEVEMENT of technological SCIENCE, elegant yet EASY to use.
@@ -224,42 +222,44 @@ indicating if they are currently on or off::
 
 Two new actions are ready to use, ``SwitchOn`` and ``SwitchOff``. Left 
 to themselves, they toggle the object's state between ON and OFF and 
-display a message like::
+display a message like:
+
+.. code-block:: transcript
 
   You switch the brass lantern on.
 
 They also take care of checking if the player fumbled and tried to turn 
 on (or off) an object which was already on (or off). How does the 
-library know the state of the object? This is thanks to the ``on`
+library know the state of the object? This is thanks to the :attr:`on
 attribute, which is set or cleared automatically as needed. You can, of 
 course, set or clear it manually like any other attribute, with the 
 ``give`` statement:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   give self on;
 
   give self ~on;
 
-and check if a ``switchable`` object is on or off with the test:
+and check if a :attr:`switchable` object is on or off with the test:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   if (light_switch has on) ...
 
   if (light_switch hasnt on) ...
 
-A ``switchable`` object is OFF by default. However, you’ll notice that 
+A :attr:`switchable` object is OFF by default. However, you’ll notice that 
 the has line of the object definition includes ``~on`` :
 
-.. code-block:: inform6
+.. code-block:: inform
 
   has    switchable ~on;
 
 Surely that’s saying "not-on"? Surely that's what would have happened 
 anyway if the line hadn't mentioned the attribute at all?
 
-.. code-block:: inform6
+.. code-block:: inform
 
   has    switchable;
 
@@ -270,31 +270,33 @@ that at some point we'll be setting it for some purpose. Trust us: it's
 worthwhile taking tiny opportunities like this to help yourself.
 
 Let’s see how our light switch works. We trap the ``SwitchOn`` and 
-``SwitchOff`` actions in the ``after`` property (when the switching has 
-successfully taken place) and use them to give ``light`` to the light 
+``SwitchOff`` actions in the :prop:`after` property (when the switching has 
+successfully taken place) and use them to give :attr:`light` to the light 
 switch.
 
 Uh, wait. To the light switch? Why not to the toilet room? Well, there's 
 a reason and we'll see it in a minute. For now, just remember that, in 
 order for players to see their surroundings, you need only one object in 
-a room with the ``light`` attribute set. It doesn't have to be the room 
+a room with the :attr:`light` attribute set. It doesn't have to be the room 
 itself (though this is usually convenient).
 
-After setting the ``light`` attribute, we display a customised message, 
-to avoid the default::
+After setting the :attr:`light` attribute, we display a customised message, 
+to avoid the default:
+
+.. code-block:: transcript
 
   You switch the light switch on.
 
 which, given the name of the object, doesn't read very elegantly. We 
 foresee that players might try to PUSH SWITCH, so we trap this attempt 
-in a ``before`` property and redirect it to ``SwitchOn`` and 
+in a :prop:`before` property and redirect it to ``SwitchOn`` and 
 ``SwitchOff`` actions, checking first which one is needed by testing the 
-``on`` attribute. Finally, we have made the switch a member of the class 
+:attr:`on` attribute. Finally, we have made the switch a member of the class 
 ``Appliance``, so that the player doesn't walk away with it.
 
 .. note::
 
-  remember what we said about class inheritance? No matter what you 
+  Remember what we said about class inheritance? No matter what you 
   define in the class, the object’s definition has priority. The class 
   ``Appliance`` defines a response for the ``Push`` action, but we 
   override it here with a new behaviour.
@@ -318,7 +320,7 @@ perhaps it would be a good idea to append a little code to the door
 object to account for this. A couple of lines in the after property will 
 suffice:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   after [ ks;
     Unlock:
@@ -334,7 +336,7 @@ suffice:
 
   ],
 
-And this is the reason why the light switch didn't set the ``light`
+And this is the reason why the light switch didn't set the :attr:`light
 attribute of the toilet room, but did it to itself. We avoid running 
 into trouble if we let the open/closed states of the door control the 
 light of the room object, and the on/off states of the switch control 
@@ -343,9 +345,9 @@ players are never aware of this glowing artefact.
 
 .. note::
 
-  now, could they? Well, if players could TAKE the light switch (which
+  Now, could they? Well, if players could TAKE the light switch (which
   we have forbidden) and then did INVENTORY, the trick would be given
-  away, because all objects with the ``light`` attribute set are listed 
+  away, because all objects with the :attr:`light` attribute set are listed 
   as ``(providing light)`` .
 
 So the player walks into the toilet and
@@ -422,7 +424,7 @@ example to fix our particular problem. In the section "``Entry point
 routines``" of our game -- after the ``Initialise`` routine, for 
 instance -- include the following lines:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   [ InScope person;
       if (person == player && location == thedark && real_location == toilet) {
@@ -432,42 +434,42 @@ instance -- include the following lines:
       return false;
   ];
 
-``InScope(actor_obj_id)`` is an entry point routine that can tamper with 
-the scope rules for the given ``actor_obj_id`` (either the player 
-character or a NPC). We define it with one variable (which we name as we 
-please; it's also a good idea to name variables in an intuitive way to 
-remind us of what they represent), ``person`` , and then we make a 
-complex test to see if the player is actually in the toilet and in the 
+:samp:`InScope({actor_obj_id})` is an entry point routine that can tamper
+with the scope rules for the given :samp:`{actor_obj_id}` (either the
+player character or a NPC). We define it with one variable (which we name
+as we please; it's also a good idea to name variables in an intuitive way
+to remind us of what they represent), ``person`` , and then we make a
+complex test to see if the player is actually in the toilet and in the
 dark.
 
-We have told you that the library variable ``location`` holds the 
+We have told you that the library variable :var:`location` holds the 
 current 
 room that the player is in. However, when there is no light, the 
 variable location gets assigned to the value of the special library 
 object thedark . It doesn't matter if we have ten dark rooms in our 
 game; location will be equal to thedark in all of them. There is yet 
-another variable, called ``real_location``, which holds the room the 
+another variable, called :var:`real_location`, which holds the room the 
 player is in *even when there is no light to see by*.
 
 So the test:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   if (person == player && location == thedark && real_location == toilet) ...
 
-is stating: if the specified actor is the ``player`` character *and* he 
+is stating: if the specified actor is the :var:`player` character *and* he 
 finds himself in the dark *and* he actually happens to be in the 
 toilet...
 
-Then we make a call to one of the library routines, 
-``PlaceInScope(obj_id)``, which has a very descriptive name: it places 
-in scope the given object. In our case, we want both the door and the 
-light switch to be within reach of the player, hence both additional 
-lines. Finally, we must ``return false``, because we want the normal 
-scope rules for the defined actor -- the player -- to apply to the rest 
-of the objects of the game (if we returned ``true``, players would find 
-that they are able to interact with very little indeed). Now we get a 
-friendlier and more logical response:
+Then we make a call to one of the library routines,
+:samp:`PlaceInScope({obj_id})`, which has a very descriptive name: it
+places in scope the given object. In our case, we want both the door and
+the light switch to be within reach of the player, hence both additional
+lines. Finally, we must ``return false``, because we want the normal scope
+rules for the defined actor -- the player -- to apply to the rest of the
+objects of the game (if we returned :const:`true`, players would find that they
+are able to interact with very little indeed). Now we get a friendlier and
+more logical response:
 
 .. code-block:: transcript
 
@@ -495,16 +497,15 @@ key has disappeared, engulfed by the darkness -- unless the player
 thinks to turn on the light switch, thereby placing the key in scope 
 once more.
 
-Why don't we add a ``PlaceInScope(toilet_key)`` to the above routine? 
-Well, for starters, the key can be moved around (as opposed to the door 
-or the light switch, which are fixed items in the toilet room). Suppose 
-the player opens the door of the toilet, but drops the key in the café, 
-then enters the toilet and closes the door. The condition is met and the 
-key is placed in scope, when it's in another room. Second, this is a 
-simple game with just a few objects, so you can define a rule for each 
-of them; but in any large game, you might like to be able to refer to 
-objects in bunches, and make general rules that apply to all (or some) 
-of them.
+Why don't we add a :samp:`PlaceInScope({toilet_key})` to the above routine?
+Well, for starters, the key can be moved around (as opposed to the door or
+the light switch, which are fixed items in the toilet room). Suppose the
+player opens the door of the toilet, but drops the key in the café, then
+enters the toilet and closes the door. The condition is met and the key is
+placed in scope, when it's in another room. Second, this is a simple game
+with just a few objects, so you can define a rule for each of them; but in
+any large game, you might like to be able to refer to objects in bunches,
+and make general rules that apply to all (or some) of them.
 
 We need to add code to the ``InScope`` routine, telling the game to 
 place in scope all objects that we drop in the dark, so that we might 
@@ -512,13 +513,13 @@ recover them (maybe going on all fours and groping a little, but it’s a
 possible action). We don’t want the player to have other objects in 
 scope (like the coin, for instance), so it might be good to have a way 
 of testing if the objects have been touched and carried by the player. 
-The attribute ``moved`` is perfect for this. The library sets it for 
+The attribute :attr:`moved` is perfect for this. The library sets it for 
 every object that the player has picked up at one time in the game; 
-``scenery`` and ``static`` objects, and those we have not yet seen don't 
-have ``moved``. Here is the reworked ``InScope`` routine. There are a 
+:attr:`scenery` and :attr:`static` objects, and those we have not yet seen don't 
+have :attr:`moved`. Here is the reworked ``InScope`` routine. There are a 
 couple of new concepts to look at:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   [ InScope person item;
       if (person == player && location == thedark && real_location == toilet) {
@@ -544,7 +545,7 @@ are trying to provide a general rule).
 is a loop statement, one of the four defined in Inform. A loop statement is
 a construct that allows you to run several times through a statement (or a
 statement block). ``objectloop`` performs the :samp:`{statement}` once for
-every object defined in the (``variable``) . If we were to code:
+every object defined in the (:samp:`{variable}`) . If we were to code:
 
    :samp:`objectloop (item) {statement};`
 
@@ -557,13 +558,13 @@ objects in the same room as the player, so we instead code:
 
 What is the actual :samp:`{statement}` that we'll repeatedly execute?
 
-.. code-block:: inform6
+.. code-block:: inform
 
   if (item has moved)
       PlaceInScope(item);
 
 The test: ``if (item has moved)`` ensures that ``PlaceInScope(item)`` 
-deals only with objects with the ``moved`` attribute set. So: if the 
+deals only with objects with the :attr:`moved` attribute set. So: if the 
 player is in the dark, let’s go through the objects which are in the 
 same room, one at a time. For each of them, check if it's an item that 
 the player has at some time carried, in which case, place it in scope. 
@@ -582,7 +583,7 @@ Amazing techicolour dreamcoats
 This leaves us the clothing items themselves, which will require a few 
 tailored actions. Let's see first the ordinary garments of John Covarth:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Object  clothes "your clothes"
     with  name 'ordinary' 'street' 'clothes' 'clothing',
@@ -655,7 +656,7 @@ expect them to try this almost anywhere; but first of all we have to
 check that the ``clothes`` object is actually being worn. If not, we 
 display a message reminding the player that this action has become 
 irrelevant. What we do with the ``switch`` statement is to offer a 
-variety of responses according to the ``location`` variable. The street 
+variety of responses according to the :var:`location` variable. The street 
 (in or out of the booth) and the café all display refusals of some kind, 
 until the player character manages to enter the toilet, where we 
 additionally require that he locks the door before taking off his 
@@ -663,13 +664,13 @@ clothes. If the door is closed but not locked, he is interrupted in his
 naked state by a nervous woman who starts shouting, and the game is lost 
 (this is not as unfair as it seems, because the player may always revert 
 to the previous state with UNDO). If the door is locked, he succeeds in 
-his transformation (we take away the ``worn`` attribute from the 
+his transformation (we take away the :attr:`worn` attribute from the 
 ``clothes`` and give it to the ``costume`` instead). We add a special 
 refusal to change in the dark, forcing players to turn on the light and 
 then, we hope, to find the coin. And finally we code a ``default`` 
 entry; you'll remember that, in a ``switch`` statement, this is supposed 
 to cater for any value not explicitly listed for the expression under 
-control -- in this case, for the variable ``location``. Since we have 
+control -- in this case, for the variable :var:`location`. Since we have 
 already gone through all the possible locations of the game, this entry 
 appears only as a defensive measure, just in case something unexpected 
 happens (for instance, we might extend the game with another room and 
@@ -683,7 +684,7 @@ change into the hero's suit, after which we'll prevent a change back
 into ordinary clothes. So now we are dealing with a Captain Fate in full 
 costume:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Object   costume "your costume"
     with   name 'captain' 'captain^s' 'fate' 'fate^s' 'costume' 'suit',
@@ -725,7 +726,7 @@ All the objects of our game are defined. Now we must add a couple of
 lines to the ``Initialise`` routine to make sure that the player does 
 not start the game naked:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   [ Initialise;
       #Ifdef DEBUG; pname_verify(); #Endif;       ! suggested by pname.h
@@ -752,7 +753,7 @@ The designer of the package has made a debugging tool (a routine) to
 check for errors when using his library, and he tells us how to use it. 
 So we include the suggested lines into our ``Initialise`` routine:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   #Ifdef DEBUG; pname_verify(); #Endif;
 
@@ -780,15 +781,15 @@ two states display, respectively,
 
   *** You have won ***
 
-These states correspond to the values of the ``deadflag`` variable: 1 
+These states correspond to the values of the :var:`deadflag` variable: 1 
 for losing, 2 for winning. However, we have made up different messages, 
 because our hero does not really die -- ours suffers a FATE worse than 
 death -- and because we want to give him a more descriptive winning 
 line. Therefore, we must define a ``DeathMessage`` routine as we did in 
 "William Tell", to write our customised messages and assign them to 
-``deadflag`` values greater than 2.
+:var:`deadflag` values greater than 2.
 
-.. code-block:: inform6
+.. code-block:: inform
 
   [ DeathMessage;
       if (deadflag == 3) print "Your secret identity has been revealed";
@@ -802,7 +803,7 @@ Finally, we need to extend the existing grammar, to allow for a couple
 of things. We have already seen that we need a verb CHANGE. We'll make 
 it really simple:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   [ ChangeSub;
       if (noun has pluralname) print "They're";
@@ -828,7 +829,7 @@ One might reasonably imagine that the ``default`` line at the end of the
 ``Give`` action in the orders property handles every input not already 
 specified:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   orders [;
     Give:
@@ -838,23 +839,23 @@ specified:
         food:        ! code for the food...
         menu:        ! code for the menu...
         default:
-          "~I don't
+          "~I don't think that's on the menu, sir.~";
       }
   ],
 
 Not so. The library grammar that deals with ASK BENNY FOR... is this
 (specifically, the last line):
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Verb 'ask'
       * creature 'about' topic    -> Ask
       * creature 'for' noun       -> AskFor
 
-You'll see the ``noun`` token, which means that whatever the player asks 
+You'll see the :var:`noun` token, which means that whatever the player asks 
 him for must be a real game object, visible at that moment. Assuming 
 that the player mentions such an object, the interpreter finds it in the 
-dictionary and places its internal ID in the ``noun`` variable, where 
+dictionary and places its internal ID in the :var:`noun` variable, where 
 our ``switch`` statement can handle it. So, ASK BENNY FOR KEY assigns 
 the ``toilet_key`` object to the noun variable, and Benny responds. ASK 
 BENNY FOR CUSTOMERS also works; the ``default`` case picks that one up. 
@@ -866,7 +867,7 @@ takes very little to allow Benny to use his default line for *any*
 undefined input from the player. We need to extend the existing ASK 
 grammar:
 
-.. code-block:: inform6
+.. code-block:: inform
 
   Extend 'ask'
       * creature 'for' topic    -> AskFor;