.. 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:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object food "Benny's snacks" cafe
And a not-so-trivial object:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object coffee "cup of coffee" benny
it's Colombian.";
];
-There's nothing really new in this object (other than that the ``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
-information that the player needs to know). Why? After you remove an
-object from the game, if the player attempts, say, to EXAMINE it, the
-interpreter will impertinently state that "You can't see any such
-thing". Moreover, if the player asks Benny for a second coffee, once the
-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
-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.
-
-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,
-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
-property routine; we *could* have used the statements ``{ print "^";
-return true; }``, but an empty ``""`` statement does the same thing more
-neatly.
-
+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
+information that the player needs to know). Why? After you remove an
+object from the game, if the player attempts, say, to EXAMINE it, the
+interpreter will impertinently state that "You can't see any such thing".
+Moreover, if the player asks Benny for a second coffee, once the 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 :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 :const:`true`
+after the first time.
+
+.. Generated by autoindex
+.. index::
+ pair: false; library constant
+
+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
+: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
+: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.
Toilet or dressing room?
========================
-Rather more of the latter, actually, since it's the only place away from
-curious eyes where our hero will be able to metamorphose from weakling
-into the bane of all evildoers. And we *really* don't want to become,
-erm, bogged down with details of the room's function or plumbing.
+Rather more of the latter, actually, since it's the only place away from
+curious eyes where our hero will be able to metamorphose from weakling into
+the bane of all evildoers. And we *really* don't want to become, 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:
-There's not a lot about the toilet room and its contents, though there
-will be some tricky side effects:
+.. include:: /config/typethis.rst
.. code-block:: inform
],
has scored;
-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
-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,
-because we trap any ``Drop`` actions to help the player to Do the Right
-Thing.
-
-The lavatory object includes a load of helpful synonyms in its name
-property, including our favourite word ``'toilet'`` . That won't be a
-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.
-The player will be awarded one point for entering the toilet room, and
+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 :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, because we trap any
+:act:`Drop` actions to help the player to Do the Right Thing.
+
+The lavatory object includes a load of helpful synonyms in its name
+property, including our favourite word ``'toilet'`` . That won't be a
+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.
+
+.. Generated by autoindex
+.. index::
+ pair: scored; library attribute
+
+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``
-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
-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.
+.. Generated by autoindex
+.. index::
+ pair: light; library attribute
+
+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 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.
+
+.. include:: /config/typethis.rst
.. code-block:: inform
],
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
-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::
+Please notice the appearance of new attributes :attr:`switchable` and
+:attr:`on`. :attr:`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:
+
+.. code-block:: transcript
> X LIGHT SWITCH
A notorious ACHIEVEMENT of technological SCIENCE, elegant yet EASY to use.
The light switch is currently switched on.
-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::
+Two new actions are ready to use, :act:`SwitchOn` and :act:`SwitchOff`.
+Left to themselves, they toggle the object's state between ON and OFF and
+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``
-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:
+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 :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:: inform
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:: inform
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:: inform
has switchable ~on;
-Surely that’s saying "not-on"? Surely that's what would have happened
+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:: inform
has switchable;
-Absolutely true. Adding that ``~on`` attribute has no effect whatsoever
-on the game -- but nevertheless it's a good idea. It's an aide-mémoire,
-a way of reminding ourselves that we start with the attribute clear, and
-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
-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
+Absolutely true. Adding that ``~on`` attribute has no effect whatsoever on
+the game -- but nevertheless it's a good idea. It's an aide-mémoire, a way
+of reminding ourselves that we start with the attribute clear, and 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.
+
+.. Generated by autoindex
+.. index::
+ pair: after; library property
+
+Let’s see how our light switch works. We trap the :act:`SwitchOn` and
+:act:`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 :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
-``SwitchOff`` actions, checking first which one is needed by testing the
-``on`` attribute. Finally, we have made the switch a member of the class
-``Appliance``, so that the player doesn't walk away with it.
+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
+:prop:`before` property and redirect it to :act:`SwitchOn` and
+:act:`SwitchOff` actions, checking first which one is needed by testing the
+: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
- define in the class, the object’s definition has priority. The class
- ``Appliance`` defines a response for the ``Push`` action, but we
+ 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 :act:`Push` action, but we
override it here with a new behaviour.
-
And there was light
===================
Darkness
It is pitch dark, and you can't see a thing.
-Oops! No toilet description, no mention of the light switch, nothing. It
-is reasonable to think that if we have opened the toilet door to access
-the toilet, some light coming from the café room will illuminate our
-surroundings -- at least until the player decides to close the door. So
-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:
+Oops! No toilet description, no mention of the light switch, nothing. It
+is reasonable to think that if we have opened the toilet door to access the
+toilet, some light coming from the café room will illuminate our
+surroundings -- at least until the player decides to close the door. So
+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:
+
+.. include:: /config/typethis.rst
.. code-block:: inform
],
-And this is the reason why the light switch didn't set the ``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
-the light of the switch. So it is one shiny light switch. Fortunately,
-players are never aware of this glowing artefact.
+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 the light of
+the switch. So it is one shiny light switch. Fortunately, players are
+never aware of this glowing artefact.
.. note::
- 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
- as ``(providing light)`` .
+ 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 :attr:`light` attribute set are listed as
+ ``(providing light)`` .
So the player walks into the toilet and
[Your score has just gone up by one point.]
-Better. Now, suppose the player closes the door.
+Better. Now, suppose the player closes the door.
.. code-block:: transcript
The player might try then to LOOK:
-Well, no problem. We have mentioned that there is a light switch. Surely
+Well, no problem. We have mentioned that there is a light switch. Surely
the player will now try to:
.. code-block:: transcript
>TURN ON LIGHT SWITCH
You can't see any such thing.
-Oops! Things are getting nasty here in the dark. It's probably time to
+Oops! Things are getting nasty here in the dark. It's probably time to
leave this place and try another approach:
.. code-block:: transcript
>OPEN DOOR
You can't see any such thing.
-And this illustrates one of the terrible things about darkness in a
-game. You can't see anything; you can do very little indeed. All objects
-except those in your inventory are out of scope, unreachable, as if
-non-existent. Worse, if you DROP one of the objects you are carrying, it
-will be swallowed by the dark, never to be found until there is light to
-see by.
-
-The player, who is doubtless immersed in the fantasy of the game, will
-now be a little annoyed. "I am in a small bathroom and I can't even
-reach the door I have just closed?" The player's right, of
-course [#dark]_. Darkened rooms are one cliché of traditional games.
-Usually you move in one direction while looking for treasure in some
-underground cave, and suddenly arrive at a pitch black place. It's good
-behaviour of the game to disallow exploration of unknown dark territory,
-and it's a convention to bar passage to players until they return with a
-light source. However, if the scenario of the game features, say, the
-player character's home, a little apartment with two rooms, and there’s
-no light in the kitchen, we could expect the owner of the house to know
-how to move around a little, perhaps groping for the light switch or
-even going to the refrigerator in the dark.
-
-We are in a similar situation. The inner logic of the game demands that
-blind players should be able to open the door and probably operate the
-light switch they've just encountered. We have been telling you that an
-object is in scope when it’s in the same room as the player. Darkness
-changes that rule. All objects not directly carried by the player become
+And this illustrates one of the terrible things about darkness in a game.
+You can't see anything; you can do very little indeed. All objects except
+those in your inventory are out of scope, unreachable, as if non-existent.
+Worse, if you DROP one of the objects you are carrying, it will be
+swallowed by the dark, never to be found until there is light to see by.
+
+The player, who is doubtless immersed in the fantasy of the game, will now
+be a little annoyed. "I am in a small bathroom and I can't even reach the
+door I have just closed?" The player's right, of course [#dark]_.
+Darkened rooms are one cliché of traditional games. Usually you move in
+one direction while looking for treasure in some underground cave, and
+suddenly arrive at a pitch black place. It's good behaviour of the game to
+disallow exploration of unknown dark territory, and it's a convention to
+bar passage to players until they return with a light source. However, if
+the scenario of the game features, say, the player character's home, a
+little apartment with two rooms, and there’s no light in the kitchen, we
+could expect the owner of the house to know how to move around a little,
+perhaps groping for the light switch or even going to the refrigerator in
+the dark.
+
+We are in a similar situation. The inner logic of the game demands that
+blind players should be able to open the door and probably operate the
+light switch they've just encountered. We have been telling you that an
+object is in scope when it’s in the same room as the player. Darkness
+changes that rule. All objects not directly carried by the player become
out of scope.
-One of the advantages of an advanced design system like Inform is the
-flexibility to change all default behaviours to suit your particular
-needs. Scope problems are no different. There is a set of routines and
-functions to tamper with what's in scope when. We'll see just a tiny
-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:
+One of the advantages of an advanced design system like Inform is the
+flexibility to change all default behaviours to suit your particular needs.
+Scope problems are no different. There is a set of routines and functions
+to tamper with what's in scope when. We'll see just a tiny 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:: inform
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
-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
-player is in *even when there is no light to see by*.
+.. Generated by autoindex
+.. index::
+ pair: location; library variable
+ pair: real_location; library variable
+
+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 :var:`real_location`, which holds the room the player is
+in *even when there is no light to see by*.
So the test:
if (person == player && location == thedark && real_location == toilet) ...
-is stating: if the specified actor is the ``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
+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...
+
+.. Generated by autoindex
+.. index::
+ pair: true; library constant
+
+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
little more than a lavatory and a light switch. The only exit is south, through
the door and into the cafe.
-And the same would happen with the door. Notice how the room description
-gets displayed after we pass from dark to light; this is the normal
-library behaviour.
-
-There is still one final problem which, admittedly, might originate from
-an improbable course of action; however, it could be a nuisance. Suppose
-that the player enters the toilet, locks the door -- which is possible
-in the dark now that the door is in scope -- and then drops the key.
-There's no way to exit the toilet -- because the door is locked and the
-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.
-
-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
-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
-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
+And the same would happen with the door. Notice how the room description
+gets displayed after we pass from dark to light; this is the normal library
+behaviour.
+
+There is still one final problem which, admittedly, might originate from an
+improbable course of action; however, it could be a nuisance. Suppose that
+the player enters the toilet, locks the door -- which is possible in the
+dark now that the door is in scope -- and then drops the key. There's no
+way to exit the toilet -- because the door is locked and the 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 :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.
+
+.. Generated by autoindex
+.. index::
+ pair: moved; library attribute
+ pair: scenery; library attribute
+ pair: static; library attribute
+
+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 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
+: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; :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:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
[ InScope person item;
return false;
];
-We have added one more local variable to the routine, ``item`` -- again,
-this is a variable we have created and named on our own; it is not part
-of the library. We make now a new test: if the actor is the player and
-the location is any dark room, then perform a certain action. We don't
-need to specify the toilet, because we want this rule to apply to all
-dark rooms (well, the only dark room in the game *is* the toilet, but we
-are trying to provide a general rule).
+We have added one more local variable to the routine, ``item`` -- again,
+this is a variable we have created and named on our own; it is not part of
+the library. We make now a new test: if the actor is the player and the
+location is any dark room, then perform a certain action. We don't need to
+specify the toilet, because we want this rule to apply to all dark rooms
+(well, the only dark room in the game *is* the toilet, but we are trying to
+provide a general rule).
:samp:`objectloop (variable) {statement};`
-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:
+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 (:samp:`{variable}`) . If we were to code:
:samp:`objectloop (item) {statement};`
then the :samp:`{statement}` would be executed once for each object in the
-game. However, we want to perform the statement only for those objects
+game. However, we want to perform the statement only for those objects
whose parent object is the same as the player's parent object: that is, for
objects in the same room as the player, so we instead code:
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
-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.
-All dropped objects within the room were carried at one time, so we let
-players recollect them even if they can’t see them.
-
-As you see, darkness has its delicate side. If you plan to have dark
-rooms galore in your games, bear in mind that you are in for some
-elaborate code (unless you let the library carry on with default rules,
-in which case there won't be much for your players to do).
+The test: ``if (item has moved)`` ensures that ``PlaceInScope(item)`` 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. All dropped
+objects within the room were carried at one time, so we let players
+recollect them even if they can’t see them.
+As you see, darkness has its delicate side. If you plan to have dark rooms
+galore in your games, bear in mind that you are in for some elaborate code
+(unless you let the library carry on with default rules, in which case
+there won't be much for your players to do).
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:
+This leaves us the clothing items themselves, which will require a few
+tailored actions. Let's see first the ordinary garments of John Covarth:
+
+.. include:: /config/typethis.rst
.. code-block:: inform
],
clothing proper pluralname;
-See how the object deals only with ``Wear``, ``Disrobe`` and ``Change``.
-``Wear`` and ``Disrobe`` are standard library actions already defined in
-Inform, but we'll have to make a new verb to allow for CHANGE CLOTHES.
-In this game, ``Disrobe`` and ``Change`` are considered synonymous for
-all purposes; we'll deal with them first.
-
-The goal of the game is for players to change their clothes, so we might
-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
-(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
-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
-``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
-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
-forget about this ``switch`` statement). In normal and controlled
-conditions, it should never be reached, but it doesn't hurt one bit to
-have it there.
-
-The ``Wear`` action just checks if these clothes are already being worn,
-to offer two different rejection responses: the goal of the game is to
-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
+See how the object deals only with :act:`Wear`, :act:`Disrobe` and
+:act:`Change`. :act:`Wear` and :act:`Disrobe` are standard library actions
+already defined in Inform, but we'll have to make a new verb to allow for
+CHANGE CLOTHES. In this game, :act:`Disrobe` and :act:`Change` are
+considered synonymous for all purposes; we'll deal with them first.
+
+.. Generated by autoindex
+.. index::
+ pair: location; library variable
+ pair: worn; library attribute
+
+The goal of the game is for players to change their clothes, so we might
+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 :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 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
+: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 :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 forget about this ``switch`` statement). In normal and controlled
+conditions, it should never be reached, but it doesn't hurt one bit to have
+it there.
+
+The :act:`Wear` action just checks if these clothes are already being worn,
+to offer two different rejection responses: the goal of the game is to
+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:
+.. include:: /config/typethis.rst
+
.. code-block:: inform
Object costume "your costume"
],
has clothing proper;
-Note that we intercept the action WEAR COSTUME and hint that players
-should try TAKE OFF CLOTHES instead. We don't let them take off the
-costume once it’s being worn, and we certainly don't let them misplace
-it anywhere, by refusing to accept a ``Drop`` action.
-
+Note that we intercept the action WEAR COSTUME and hint that players should
+try TAKE OFF CLOTHES instead. We don't let them take off the costume once
+it’s being worn, and we certainly don't let them misplace it anywhere, by
+refusing to accept a :act:`Drop` action.
It's a wrap
===========
.. rubric:: Initialise routine
-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:
+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:
+
+.. include:: /config/typethis.rst
.. code-block:: inform
Captain FATE costume fast...!^^";
];
-Remember that we included a disambiguation package, ``pname.h``? There
-were some additional comments in the accompanying text file that should
-be taken in consideration:
+Remember that we included a disambiguation package, ``pname.h``? There
+were some additional comments in the accompanying text file that should be
+taken in consideration:
- pname.h provides a pname_verify routine. When DEBUG is defined, you
- may call pname_verify() in your Initialise() routine to verify the pname
+ pname.h provides a pname_verify routine. When DEBUG is defined, you may
+ call pname_verify() in your Initialise() routine to verify the pname
properties in your objects.
-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:
+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:: inform
#Ifdef DEBUG; pname_verify(); #Endif;
-As the text explains, what this does is: first check whether the game is
-being compiled in Debug mode; if this is the case, run the
-``pname_verify`` routine, so that it tests all ``pname`` properties to
-see if they are written correctly.
+As the text explains, what this does is: first check whether the game is
+being compiled in Debug mode; if this is the case, run the ``pname_verify``
+routine, so that it tests all ``pname`` properties to see if they are
+written correctly.
.. rubric:: Demise of our hero
We have made three possible endings:
-#. The player attempts to change in the toilet with an unlocked door.
+#. The player attempts to change in the toilet with an unlocked door.
-#. The player tries to attack Benny while wearing the costume.
+#. The player tries to attack Benny while wearing the costume.
-#. The player manages to exit the café dressed as Captain Fate.
+#. The player manages to exit the café dressed as Captain Fate.
-(1) and (2) lose the game, (3) wins it. The library defaults for these
-two states display, respectively,
+(1) and (2) lose the game, (3) wins it. The library defaults for these two
+states display, respectively,
.. code-block:: transcript
*** You have won ***
-These states correspond to the values of the ``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.
+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 :var:`deadflag`
+values greater than 2.
+
+.. include:: /config/typethis.rst
.. code-block:: inform
.. rubric:: Grammar
-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:
+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:
+
+.. include:: /config/typethis.rst
.. code-block:: inform
Verb 'change' 'exchange' 'swap' 'swop'
* noun -> Change;
-Just notice how the verb handler checks whether the noun given is plural
-or singular, to display a suitable pronoun.
+Just notice how the verb handler checks whether the noun given is plural or
+singular, to display a suitable pronoun.
+
+A further detail: when players are in the café, they might ask Benny for
+the coffee (as we intend and heavily hint), for a sandwich or a pastry
+(both mentioned in the café description), for food or a snack (mentioned
+here and there, and we have provided for those); but what if they try a
+meat pie? Or scrambled eggs? There’s just so much decoration one can
+reasonably insert in a game, and loading the dictionary with Benny’s full
+menu would be overdoing it a bit.
-A further detail: when players are in the café, they might ask Benny for
-the coffee (as we intend and heavily hint), for a sandwich or a pastry
-(both mentioned in the café description), for food or a snack (mentioned
-here and there, and we have provided for those); but what if they try a
-meat pie? Or scrambled eggs? There’s just so much decoration one can
-reasonably insert in a game, and loading the dictionary with Benny’s
-full menu would be overdoing it a bit.
+.. Generated by autoindex
+.. index::
+ pair: Give; library action
-One might reasonably imagine that the ``default`` line at the end of the
-``Give`` action in the orders property handles every input not already
+One might reasonably imagine that the ``default`` line at the end of the
+:act:`Give` action in the orders property handles every input not already
specified:
.. code-block:: inform
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
+Not so. The library grammar that deals with ASK BENNY FOR... is this
(specifically, the last line):
.. code-block:: inform
* creature 'about' topic -> Ask
* creature 'for' noun -> AskFor
-You'll see the ``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
-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.
-But, ASK BENNY FOR SPAGHETTI BOLOGNESE won't work: we have no object for
-Spaghetti Bolognese (or any other delicacy from Benny's kitchen) -- the
-words ``'spaghetti'`` and ``'bolognese'`` simply aren't in the
-dictionary. This is perhaps not a major deficiency in our game, but it
-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:
+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 :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. But, ASK
+BENNY FOR SPAGHETTI BOLOGNESE won't work: we have no object for Spaghetti
+Bolognese (or any other delicacy from Benny's kitchen) -- the words
+``'spaghetti'`` and ``'bolognese'`` simply aren't in the dictionary. This
+is perhaps not a major deficiency in our game, but it 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:
+
+.. include:: /config/typethis.rst
.. code-block:: inform
Extend 'ask'
* creature 'for' topic -> AskFor;
-This line will be added to the end of the existing grammar for Ask, so
-it doesn’t override the conventional noun-matching line. ``topic`` is a
-token that roughly means “any input at all”; the value of noun isn't
-important, because it'll be handled by the default case. Now players may
-ask Benny for a tuna sandwich or a good time; they'll get: "I don’t
-think that’s on the menu, sir", which makes Benny a barman with
-attitude.
-
-And that's it; on the slightly surreal note of ASK BENNY FOR A GOOD TIME
-we've taken "Captain Fate" as far as we intend to. The guide is nearly
-done. All that's left is to recap some of the more important issues,
-talk a little more about compilation and debugging, and send you off
-into the big wide world of IF authorship.
+This line will be added to the end of the existing grammar for Ask, so it
+doesn’t override the conventional noun-matching line. ``topic`` is a token
+that roughly means "any input at all"; the value of noun isn't important,
+because it'll be handled by the default case. Now players may ask Benny
+for a tuna sandwich or a good time; they'll get: "I don’t think that’s on
+the menu, sir", which makes Benny a barman with attitude.
+And that's it; on the slightly surreal note of ASK BENNY FOR A GOOD TIME
+we've taken "Captain Fate" as far as we intend to. The guide is nearly
+done. All that's left is to recap some of the more important issues, talk
+a little more about compilation and debugging, and send you off into the
+big wide world of IF authorship.
.. rubric:: Footnotes
.. [#dark]
-
- We're alluding here to the Classical concept of mimesis. In an
- oft-quoted essay from 1996, Roger Giner-Sorolla wrote: "I see
- successful fiction as an imitation or 'mimesis' of reality, be it
- this world's or an alternate world's. Well-written fiction leads the
- reader to temporarily enter and believe in the reality of that world.
- A crime against mimesis is any aspect of an IF game that breaks the
- coherence of its fictional world as a representation of reality."
-
+ We're alluding here to the Classical concept of mimesis. In an
+ oft-quoted essay from 1996, Roger Giner-Sorolla wrote: "I see successful
+ fiction as an imitation or 'mimesis' of reality, be it this world's or
+ an alternate world's. Well-written fiction leads the reader to
+ temporarily enter and believe in the reality of that world. A crime
+ against mimesis is any aspect of an IF game that breaks the coherence of
+ its fictional world as a representation of reality."