From 2a223f38ada318aa468e46210b7f92941816100e Mon Sep 17 00:00:00 2001 From: Glenn Hutchings Date: Wed, 27 Apr 2016 17:59:38 +0100 Subject: [PATCH] Do a bunch of proofreading fixes. --- appendices/f.rst | 18 +++- chapters/02.rst | 8 +- chapters/03.rst | 10 +- chapters/10.rst | 17 ++-- chapters/11.rst | 27 +++-- chapters/12.rst | 37 +++---- chapters/13.rst | 71 +++++++------ chapters/14.rst | 237 +++++++++++++------------------------------ chapters/15.rst | 174 ++++++++++++++++--------------- chapters/16.rst | 98 +++++++++--------- chapters/17.rst | 2 - conf.py | 2 + endnotes.rst | 9 -- index.rst | 5 +- todo.rst | 9 ++ tools/inform.py | 8 +- tools/sphinxpatch.py | 10 ++ 17 files changed, 344 insertions(+), 398 deletions(-) delete mode 100644 endnotes.rst create mode 100644 todo.rst create mode 100644 tools/sphinxpatch.py diff --git a/appendices/f.rst b/appendices/f.rst index 372dc56..c9a90e9 100644 --- a/appendices/f.rst +++ b/appendices/f.rst @@ -155,7 +155,8 @@ Library variables Used by `invent` and `list_together` properties. `keep_silent` - Normally `false`; `true` makes most group 2 actions silent. + Normally `false`; `true` makes most :ref:`group 2 actions + ` silent. `location` The player's current room; unless that's dark, when it contains @@ -207,7 +208,8 @@ Library routines A scored task has been achieved. `AfterRoutines()` - In a group 2 action, controls output of "after" messages. + In a :ref:`group 2 action `, controls output of "after" + messages. `AllowPushDir()` An object can be pushed from one location to another. @@ -229,17 +231,17 @@ Library routines `DrawStatusLine()` Refreshes the status line; happens anyway at end of each turn. -`GetGNAOfObject(obj_id)` +`GetGNAOfObject({obj_id})` Returns gender-number-animation 0..11 of the `{obj_id}`. -`HasLightSource(obj_id)` +`HasLightSource({obj_id})` Returns `true` if the `{obj_id}` has light. `IndirectlyContains({parnt_obj_id,obj_id})` Returns `true` if `{obj_id}` is currently a child or grand-child or great-grand-child... of the `{parent_object}`. -`IsSeeThrough(obj_id)` +`IsSeeThrough({obj_id})` Returns `true` if light can pass through the `{obj_id}`. `Locale({obj_id,"string1","string2"})` @@ -906,6 +908,8 @@ Group 2 actions Group 2 actions usually work, given the right circumstances. +.. tabularcolumns:: |l|p{5in}| + ============= ============================================================= `Close` "`CLOSE [UP]`", "`COVER [UP]`", "`SHUT [UP]`" `Disrobe` "`DISROBE`", "`DOFF`", "`REMOVE`", "`SHED`", "`TAKE OFF`" @@ -971,6 +975,8 @@ Group 3 actions Group 3 actions are by default stubs which output a message and stop at the "before" stage (so there is no "after" stage). +.. tabularcolumns:: |l|p{5in}| + ============= ============================================================= `Answer` "`ANSWER TO`", "`SAY TO`", "`SHOUT TO`", "`SPEAK TO`" @@ -1041,6 +1047,8 @@ Fake actions Fake actions handle some special cases, or represent "real" actions from the viewpoint of the second object. +.. tabularcolumns:: |l|p{5in}| + ================ ======================================================== `LetGo` Generated by `Remove`. `ListMiscellany` Outputs a range of inventory messages. diff --git a/chapters/02.rst b/chapters/02.rst index ee0b5b2..d95eee6 100644 --- a/chapters/02.rst +++ b/chapters/02.rst @@ -316,8 +316,8 @@ doing. There are four parts to the first line: .. note:: On the command line, you sometimes also see a compiler :term:`switch` - such as ``-S``, used for controlling detailed aspects of how the - compiler operates. Rather than do that here, we find it more + such as :option:`-S`, used for controlling detailed aspects of how + the compiler operates. Rather than do that here, we find it more convenient to place any necessary switches at the very top of the source file, as we'll explain in the next chapter. @@ -605,8 +605,8 @@ There are three parts to the second line: .. note:: On the command line, you sometimes also see a compiler :term:`switch` - such as ``-S``, used for controlling detailed aspects of how the - compiler operates. Rather than do that here, we find it more + such as :option:`-S`, used for controlling detailed aspects of how + the compiler operates. Rather than do that here, we find it more convenient to place any necessary switches at the very top of the source file, as we'll explain in the next chapter. diff --git a/chapters/03.rst b/chapters/03.rst index 061810b..0291af1 100644 --- a/chapters/03.rst +++ b/chapters/03.rst @@ -172,11 +172,11 @@ looking at the source file. .. note:: - Actually, the ``-S`` is redundant, since Strict mode is already on by - default. We include it here as a reminder that (a) to turn Strict - mode *off*, you change this setting to ``-~S``, and (b) alphabetic - case matters here: ``-s`` causes a display of compiler statistics (and - ``-~s`` does nothing at all). + Actually, the :option:`-S` is redundant, since Strict mode is already + on by default. We include it here as a reminder that (a) to turn + Strict mode *off*, you change this setting to :option:`-~S`, and (b) + alphabetic case matters here: :option:`-s` causes a display of + compiler statistics (and :option:`-~s` does nothing at all). * Otherwise, when the compiler comes across an exclamation mark, it ignores the rest of the line. If the ``!`` is at the start of a line, the whole diff --git a/chapters/10.rst b/chapters/10.rst index d8b3218..3274de9 100644 --- a/chapters/10.rst +++ b/chapters/10.rst @@ -45,11 +45,11 @@ super-hero made famous by a childhood of comic books: .. pull-quote:: - "Impersonating mild mannered John Covarth, assistant help boy at - an Impersonating insignificant drugstore, you suddenly STOP - when your acute hearing deciphers a stray radio call from the - POLICE. There’s some MADMAN attacking the population in Granary - Park! You must change into your Captain FATE costume fast...!" + "Impersonating mild mannered John Covarth, assistant help boy at an + insignificant drugstore, you suddenly STOP when your acute hearing + deciphers a stray radio call from the POLICE. There’s some MADMAN + attacking the population in Granary Park! You must change into your + Captain FATE costume fast...!" which won't be so easy to do. In this short example, players will win when they manage to change into their super-hero costume and fly away to @@ -443,7 +443,7 @@ something else to describe it: .. note:: - although the text of our guide calls Benny's establishment a "café" + Although the text of our guide calls Benny's establishment a "café" -- note the acute "e" -- the game itself simplifies this to "cafe". We do this for clarity, not because Inform doesn't support accented characters. The *Inform Designer's Manual* explains in detail how to @@ -645,11 +645,12 @@ experience grows. .. todo:: - That "whatever new look" below needs to be italicized and bolded for LaTeX + That "whatever new look" below needs to be italicized and bolded for + LaTeX. .. note:: - going back to our example, an alternative approach would be to set + Going back to our example, an alternative approach would be to set the variable ``player.description`` in the ``Initialise`` routine (as we did with "William Tell") to the "ordinary clothes" string, and then later change it as the need arises. It is a variable, after all, and you diff --git a/chapters/11.rst b/chapters/11.rst index ef71004..ffbc9ae 100644 --- a/chapters/11.rst +++ b/chapters/11.rst @@ -34,7 +34,7 @@ the door seems to be locked. .. admonition:: Cultural Note :class: admonition note - not for the first time, this guide betrays its origins. In + Not for the first time, this guide betrays its origins. In European countries the word "toilet" often refers not only to the white porcelain artefact, but also to the room in which it can be found (also, a "bathroom" is for taking a bath, a "restroom" for @@ -76,7 +76,7 @@ We've mentioned a counter: ], has supporter; -That ``before property``, superficially normal, actually conceals a +That ``before`` property, superficially normal, actually conceals a little surprise. By now you should be entirely comfortable with using an object's ``before`` property to intercept an action directed at that object; for example, if the player types HIT COUNTER then the counter's @@ -104,7 +104,7 @@ action`. .. note:: - in "William Tell" we defined the ``quiver``, way back in + In "William Tell" we defined the ``quiver``, way back in :ref:`possessions`, as an ``open container``. As things stand, the player can put *any* held object, however inappropriate, into it. We could have trapped the Receive action to ensure that arrows are the only acceptable @@ -236,13 +236,13 @@ To code a daemon, you need to do three things: the property is always an embedded routine. #. However, daemons do nothing until you activate them. This is easily - achieved with the call ``StartDaemon(obj_id)``, which may happen + achieved with the call :samp:`StartDaemon({obj_id})`, which may happen anywhere (if you want some object's daemon to be active from the beginning of the game,you can make the call in your Initialise routine). #. Once the daemon has finished its mission (if ever) you may stop it - with the call ``StopDaemon(obj_id)``. + with the call :samp:`StopDaemon({obj_id})`. How does our particular daemon work? The appearance of our hero in full crime-fighting wear will make the customers stare at him and make snarky @@ -353,7 +353,7 @@ normal rules for the other available directions. Then we check whether the player character is wearing the costume, in which case it starts the ``daemon`` of the ``customers`` object. The use -of the local first_time_out property ensures that the condition is +of the local ``first_time_out`` property ensures that the condition is ``true`` only once, so the statement block attached to it runs also once. @@ -491,6 +491,7 @@ it's easy to write a routine as the value of ``short_name``: short_name [; if (location == cafe) print "door to the toilet"; else print "door to the cafe"; + return true; ], description ... @@ -505,22 +506,18 @@ adjectives -- perhaps a shining/flickering/fading/useless lantern. .. note:: - what's displayed if there isn't an external name in an object's header? + What's displayed if there isn't an external name in an object's header? If you've read the section :ref:`compile-as-you-go`, you'll recall that the interpreter simply uses the internal identifier within parentheses; that is, with no external name and no ``short_name`` property, we might - see: - - .. code-block:: inform + see:: You open the (toilet_door). And the same principle applies if we were mistakenly to ``return false`` from this short_name routine: we would get, first, the result of our ``print`` statement, and then the standard rules would display - the internal ID: - - .. code-block:: inform + the internal ID:: You open the door to the toilet(toilet_door). @@ -604,7 +601,9 @@ shouldn’t assume that they want to lock it as well). In all processes there is a library variable called ``keep_silent``, which can be either ``false`` (the normal state) or ``true``; when ``true``, the interpreter does not display the associated message of an -action in progress, so we can avoid things like:: +action in progress, so we can avoid things like: + +.. code-block:: transcript >OPEN DOOR You open the door to the toilet. diff --git a/chapters/12.rst b/chapters/12.rst index d00131f..b22ae93 100644 --- a/chapters/12.rst +++ b/chapters/12.rst @@ -52,7 +52,7 @@ could benefit from the effort. The product of this generosity takes the form of a library extension: the solution neatly packaged as a file that other designers can incorporate into their source code. These files can be found in the IF Archive: go to -``http://mirror.ifarchive.org/indexes/if-archive.html`` and then select +http://mirror.ifarchive.org/indexes/if-archive.html and then select "``.../infocom``", "``.../compilers``", "``.../inform6``", "``.../library``", and "``.../contributions``". All of these files contain Inform code. To use a library extension (also known as a library @@ -107,14 +107,19 @@ instructions: #. Add four lines near the head of the program (before you include ``Parser.h``). - ``Replace MakeMatch;`` - ``Replace Identical;`` - ``Replace NounDomain;`` - ``Replace TryGivenObject;`` + .. code-block:: inform + + Replace MakeMatch; + Replace Identical; + Replace NounDomain; + Replace TryGivenObject; #. Include the ``pname.h`` header just after you include ``Parser.h``. - ``Include "Parser";`` - ``Include "pname";`` + + .. code-block:: inform + + Include "Parser"; + Include "pname"; #. Add ``pname`` properties to those objects which require phrase recognition. @@ -141,7 +146,7 @@ providing replacements for some standard routines. Include "Parser"; Include "pname"; - !... + ... Now our source code is ready to benefit from the library package. How does it work? We have acquired a new property -- ``pname`` -- which can @@ -150,21 +155,17 @@ be added to some of our objects, and which works pretty much like a property where we have a disambiguation problem. Let’s change the relevant lines for the toilet door and the toilet key: -.. todo:: - - Maybe specially highlight the lines using pname? - .. code-block:: inform Object toilet_door with pname '.x' 'red' '.x' 'toilet' 'door', short_name [; - !... + ... Object toilet_key "toilet key" benny with pname '.x' 'toilet' 'key', article "the", - !... + ... while leaving the ``outside_of_toilet`` unchanged: @@ -173,7 +174,7 @@ while leaving the ``outside_of_toilet`` unchanged: Object outside_of_toilet "toilet" cafe with name 'toilet' 'bath' 'rest' 'room' 'bathroom' 'restroom', before [; - !... + ... We are now using a new operator -- ``'.x'`` -- in our ``pname`` word lists. explains @@ -185,7 +186,7 @@ and this makes the dictionary word ``'toilet'`` of lesser importance for these objects, so that at run-time players could refer to the DOOR or TOILET DOOR or the KEY or TOILET KEY -- but not simply to the TOILET -- when referring to either the door or the key. And, by leaving unchanged -the name property of the outside_of_toilet object – where there is also +the name property of the ``outside_of_toilet`` object – where there is also another ``'toilet'`` entry -- the ``pname`` properties will tell the interpreter to discard the key and the door as possible objects to be considered when players refer just to TOILET. Looking at it in terms of @@ -297,7 +298,7 @@ capability), is more local property variables: coffee_not_paid false, ! is Benny waiting to be paid? key_not_returned false, ! is Benny waiting for the key? live [; - !... + ... Now we are ready to tackle the ``Give`` action of the ``life`` property, which deals with commands like GIVE THE KEY TO BENNY (in a moment, we'll @@ -337,7 +338,7 @@ statement as shorthand for: if (noun == costume) { whatever }; if (noun == clothes) { whatever }; - !... + ... We won't let players give away their clothes or their costume (yes, an improbable action, but you never know). The toilet key and the coin are diff --git a/chapters/13.rst b/chapters/13.rst index 16b4283..65df6a6 100644 --- a/chapters/13.rst +++ b/chapters/13.rst @@ -95,7 +95,7 @@ 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``, +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 @@ -216,7 +216,9 @@ 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:: +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,7 +226,9 @@ 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. @@ -281,7 +285,9 @@ a room with the ``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:: +to avoid the default: + +.. code-block:: transcript You switch the light switch on. @@ -294,7 +300,7 @@ in a ``before`` property and redirect it to ``SwitchOn`` and .. 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. @@ -343,7 +349,7 @@ 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 as ``(providing light)`` . @@ -432,12 +438,12 @@ 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 @@ -459,15 +465,15 @@ 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 -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 ``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 +501,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 @@ -544,7 +549,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};` @@ -838,7 +843,7 @@ 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.~"; } ], diff --git a/chapters/14.rst b/chapters/14.rst index fa4f516..b8e12b7 100644 --- a/chapters/14.rst +++ b/chapters/14.rst @@ -2,6 +2,10 @@ Some last lousy points ======================== +.. highlight:: inform + +.. default-role:: samp + .. only:: html .. image:: /images/picF.png @@ -32,13 +36,13 @@ Designer's Manual* provides rounder and more comprehensive coverage. Expressions =========== -In this guide we’ve used the placeholder ``expression`` a few times; +In this guide we’ve used the placeholder `{expression}` a few times; here's roughly what we mean. -* An ``expression`` is a single ``value``, or several ``values`` - combined using ``operators`` and sometimes parentheses ``(...)``. +* An `{expression}` is a single `{value}`, or several `{values}` + combined using `{operators}` and sometimes parentheses ``(...)``. -* Possible ``values`` include: +* Possible `{values}` include: * a literal number (-32768 to 32767) @@ -51,7 +55,7 @@ here's roughly what we mean. * (only in a run-time statement, not in a compile-time directive) the contents of a variable, or the return value from a routine. -* Possible ``operators`` include: +* Possible `{operators}` include: * an arithmetic operator: ``+ - * / % ++`` * a bitwise logical operator: ``& | ~`` @@ -59,7 +63,6 @@ here's roughly what we mean. * an object conditional operator: ``ofclass in notin provides has hasnt`` * a boolean combinational operator: ``&& || ~~`` - Internal IDs ============ @@ -67,8 +70,8 @@ Many of the items which you define in your source file -- objects, variables, routines, etc. -- need to be given a name so that other items can refer to them. We call this name an item's internal identifier (because it's used only within the source file and isn't visible to the -player), and we use the placeholders ``obj_id``, ``var_id``, -``routine_id``, etc. to represent where it's used. An internal ID +player), and we use the placeholders `{obj_id}`, `{var_id}`, +`{routine_id}`, etc. to represent where it's used. An internal ID * can be up to thirty-two characters long @@ -86,19 +89,17 @@ player), and we use the placeholders ``obj_id``, ``var_id``, Statements ========== +.. todo:: + + We might need some custom syntax highlighting here. + A :term:`statement` is an instruction intended for the interpreter, telling it what to do at run-time. It *must* be given in lower-case, and always ends with a semicolon. Some statements, like ``if``, control one or more other statements. We -use the placeholder ``statement_block`` to represent either a single -``statement``, or any number of ``statements`` enclosed in braces: - -.. todo:: - - We might need some custom syntax highlighting here - -.. code-block:: inform +use the placeholder `{statement_block}` to represent either a single +`{statement}`, or any number of `{statements}` enclosed in braces:: statement; @@ -108,9 +109,7 @@ Statements that we've met ------------------------- Our games have used these statements, about half of the Inform -possibilities: - -.. code-block:: inform +possibilities:: give obj_id attribute; give obj_id attribute attribute ... attribute; @@ -156,9 +155,7 @@ Statements that we've not met ----------------------------- Although our example games haven't needed to use them, these looping -statements are sometimes useful: - -.. code-block:: inform +statements are sometimes useful:: break; continue; @@ -171,9 +168,7 @@ statements are sometimes useful: On the other hand, we suggest that you put the following statements on hold for now; they're not immediately relevant to everyday code and have -mostly to do with printing and formatting: - -.. code-block:: inform +mostly to do with printing and formatting:: box font @@ -187,29 +182,28 @@ In particular, avoid using the deprecated jump statement if you possibly can. Print rules ----------- -In ``print`` and ``print_ret`` statements, each ``value`` can be: +In ``print`` and ``print_ret`` statements, each `{value}` can be: -* a numeric ``expression``, displayed as a signed decimal number, +* a numeric `{expression}`, displayed as a signed decimal number, -* a ``"string"``, displayed literally, or +* a `"{string}"`, displayed literally, or * a print rule. You can create your own, or use a standard one, including: .. tabularcolumns:: ll +-------------------------+---------------------------------------------------+ - | ``(a) obj_id`` | the object's name, preceded by "a", "an" or "some"| + | `(a) {obj_id}` | the object's name, preceded by "a", "an" or "some"| +-------------------------+---------------------------------------------------+ - | ``(A) obj_id`` | as ``(a)`` but using "A", "An" or "Some" | + | `(A) {obj_id}` | as ``(a)`` but using "A", "An" or "Some" | +-------------------------+---------------------------------------------------+ - | ``(the) obj_id`` | the object's name, preceded by "the" | + | `(the) {obj_id}` | the object's name, preceded by "the" | +-------------------------+---------------------------------------------------+ - | ``(The) obj_id`` | as ``(the)`` but using "The" | + | `(The) {obj_id}` | as ``(the)`` but using "The" | +-------------------------+---------------------------------------------------+ - | ``(number) expression`` | the numeric expression's value in words | + | `(number) {expression}` | the numeric expression's value in words | +-------------------------+---------------------------------------------------+ - Directives ========== @@ -223,9 +217,7 @@ Directives that we've met We've used all of these directives; note that for ``Class``, ``Extend``, ``Object`` and ``Verb`` the full supported syntax is more sophisticated -than the basic form presented here: - -.. code-block:: inform +than the basic form presented here:: Class class_id with property value, @@ -275,9 +267,7 @@ Directives that we've not met ----------------------------- There's only a handful of useful directives which we haven't needed to -use: - -.. code-block:: inform +use:: Attribute attribute; @@ -289,9 +279,7 @@ use: Statusline score; Statusline time; -but there's a whole load which are of fairly low importance for now: - -.. code-block:: inform +but there's a whole load which are of fairly low importance for now:: Abbreviate Array @@ -328,35 +316,26 @@ by using them within an object definition. You can create and initialise a property in an object's ``with`` segment: -.. code-block:: inform - property, ! set to zero / false property value, ! set to a single value property value value ... value, ! set to a list of values -In each case, the ``value`` is either a compile-time ``expression``, or -an embedded routine: - -.. code-block:: inform +In each case, the `{value}` is either a compile-time `{expression}`, or +an embedded routine:: property expression, property [; statement; statement; ... statement; ], - -You can refer to the value of a property: - -.. code-block:: inform +You can refer to the value of a property:: self.property ! only within that same object obj_id.property ! everywhere -and you can test whether an object definition includes a given property: - -.. code-block:: inform +and you can test whether an object definition includes a given property:: (obj_id provides property) ! is true or false @@ -370,30 +349,22 @@ Inform provides standalone routines and embedded routines. Standalone routines ------------------- -Standalone routines are defined like this: - -.. code-block:: inform +Standalone routines are defined like this:: [ routine_id; statement; statement; ... statement; ]; -and called like this: - -.. code-block:: inform +and called like this:: routine_id() Embedded routines ----------------- -These are embedded as the value of an object's property: - -.. code-block:: inform +These are embedded as the value of an object's property:: property [; statement; statement; ... statement; ], -and are usually called automatically by the library, or manually by: - -.. code-block:: inform +and are usually called automatically by the library, or manually by:: self.property() ! only within that same object @@ -405,9 +376,7 @@ Arguments and local variables Both types of routine support up to fifteen local variables -- variables which can be used only by the statements within the routine, and which are automatically initialised to zero every time that the routine is -called: - -.. code-block:: inform +called:: [ routine_id var_id var_id ... var_id; statement; statement; ... statement; ]; @@ -416,9 +385,7 @@ called: You can pass up to seven arguments to a routine, by listing those arguments within the parentheses when you call the routine. The effect is simply to initialise the matching local variables to the argument -values rather than to zero: - -.. code-block:: inform +values rather than to zero:: routine_id(expression, expression, ... expression) @@ -430,25 +397,19 @@ Return values ------------- Every routine returns a single value, which is supplied either -explicitly by some form of return statement: - -.. code-block:: inform +explicitly by some form of return statement:: [ routine_id; statement; statement; ... return expr; ]; ! returns expr property [; statement; statement; ... return expr; ], ! returns expr -or implicitly when the routine runs out of statements. If none of these -``statements`` is one -- ``return``, ``print_ret``, ``"..."` or -``<<...>>`` -- that causes an explicit return, then: - -.. code-block:: inform +or implicitly when the routine runs out of statements. If none of these +``statements`` is one -- ``return``, ``print_ret``, ``"..."`` or +``<<...>>`` -- that causes an explicit return, then:: [ routine_id; statement; statement; ... statement; ]; -returns ``true`` and - -.. code-block:: inform +returns ``true`` and :: property [; statement; statement; ... statement; ] @@ -459,16 +420,12 @@ left to themselves, Standalone routines return True, Embedded routines return False. Here's an example standalone routine which returns the larger of its two -argument values: - -.. code-block:: inform +argument values:: [ Max a b; if (a > b) return a; else return b; ]; and here are some examples of its use (note that the first example, -though legal, does nothing useful whatsoever): - -.. code-block:: inform +though legal, does nothing useful whatsoever):: Max(x,y); @@ -484,9 +441,7 @@ Library routines versus entry points A library routine is a standard routine, included within the library files, which you can optionally call from your source file if you require the functionality which the routine provides. We've mentioned -these library routines: - -.. code-block:: inform +these library routines:: IndirectlyContains(parent_obj_id, obj_id) @@ -501,17 +456,13 @@ these library routines: By contrast, an entry point routine is a routine which you can provide in your source file, in which case the library calls it at an -appropriate time. We've mentioned these optional entry point routines: - -.. code-block:: inform +appropriate time. We've mentioned these optional entry point routines:: DeathMessage() InScope(actor_obj_id) -And this, the only mandatory one: - -.. code-block:: inform +And this, the only mandatory one:: Initialise() @@ -547,9 +498,7 @@ your code, about making it as readable as you can. This is doubly true if you ever contemplate sharing a library extension with the rest of the community. This example, with the name changed, is -from a file in the Archive: - -.. code-block:: inform +from a file in the Archive:: [xxxx i j; if (j==0) rtrue; @@ -577,9 +526,7 @@ from a file in the Archive: Here's the same routine after a few minutes spent purely on making it more comprehensible; we haven't actually tested that it (still) works, -though that second ``else`` looks suspicious: - -.. code-block:: inform +though that second ``else`` looks suspicious:: [ xxxx i j; if (i in player || i has static or scenery || j == nothing) return true; @@ -606,9 +553,7 @@ Shortcuts There are a few statement shortcuts, some more useful than others, which you'll come across. -* These five lines all do the same thing: - - .. code-block:: inform +* These five lines all do the same thing:: return true; return 1; @@ -616,65 +561,49 @@ you'll come across. rtrue; ]; ! at the end of a standalone routine -* These four lines all do the same thing: - - .. code-block:: inform +* These four lines all do the same thing:: return false; return 0; rfalse; ]; ! at the end of an embedded routine -* These four lines all do the same thing: - - .. code-block:: inform +* These four lines all do the same thing:: print "string"; new_line; return true; print "string^"; return true; print_ret "string"; "string"; -* These lines are the same: - - .. code-block:: inform +* These lines are the same:: print value1; print value2; print value3; print value1, value2, value3; -* These lines are the same: - - .. code-block:: inform +* These lines are the same:: ; return true; <>; -* These lines are also the same: - - .. code-block:: inform +* These lines are also the same:: print "^"; new_line; -* These ``if`` statements are equivalent: - - .. code-block:: inform +* These ``if`` statements are equivalent:: if (MyVar == 1 || MyVar == 3 || MyVar == 7) ... if (MyVar == 1 or 3 or 7) ... -* These ``if`` statements are equivalent as well: - - .. code-block:: inform +* These ``if`` statements are equivalent as well:: if (MyVar ~= 1 && MyVar ~= 3 && MyVar ~= 7) ... if (MyVar ~= 1 or 3 or 7) ... * In an ``if`` statement, the thing in parentheses can be *any* expression; all that matters is its value: zero (false) or anything - else (true). For example, these statements are equivalent: - - .. code-block:: inform + else (true). For example, these statements are equivalent:: if (MyVar ~= false) ... if (~~(MyVar == false)) ... @@ -684,17 +613,13 @@ you'll come across. Note that the following statement specifically tests whether ``MyVar`` contains ``true`` (1), *not* whether its value is anything other than - zero. - - .. code-block:: inform + zero. :: if (MyVar == true) ... * If ``MyVar`` is a variable, the statements ``MyVar++;`` and ``++MyVar;`` work the same as ``MyVar = MyVar + 1;`` For example, - these lines are equivalent: - - .. code-block:: inform + these lines are equivalent:: MyVar = MyVar + 1; if (MyVar == 3) ... if (++MyVar == 3) ... @@ -708,9 +633,7 @@ you'll come across. value. In the example, if ``MyVar`` currently contains 2 then ``++MyVar`` returns 3 and ``MyVar++`` returns 2, even though in both cases the value of ``MyVar`` afterwards is 3. As another example, - this code (from Helga in "William Tell"): - - .. code-block:: inform + this code (from Helga in "William Tell"):: Talk: self.times_spoken_to = self.times_spoken_to + 1; switch (self.times_spoken_to) { @@ -721,9 +644,7 @@ you'll come across. } ], - could have been written more succinctly like this: - - .. code-block:: inform + could have been written more succinctly like this:: Talk: switch (++self.times_spoken_to) { 1: score++; @@ -734,9 +655,7 @@ you'll come across. ], * Similarly, the statements ``MyVar--;`` and ``--MyVar;`` work the same - as ``MyVar = MyVar - 1;`` Again, these lines are equivalent: - - .. code-block:: inform + as ``MyVar = MyVar - 1;`` Again, these lines are equivalent:: MyVar = MyVar - 1; if (MyVar == 7) ... if (--MyVar == 7) ... @@ -768,9 +687,7 @@ on *all* objects. The need to do this is actually quite rare, and is mostly confined to library extensions (for example, the ``pname.h`` extension which we encountered in :doc:`12` gives every object a ``pname`` property and a ``phrase_matched`` attribute). To create them, you would use these -directives near the start of your source file: - -.. code-block:: inform +directives near the start of your source file:: Attribute attribute; @@ -797,9 +714,7 @@ objects which crop up in more than one place, by using their ``found_in`` properties. For example, in "William Tell" we defined twenty-seven objects; omitting those which used ``found_in`` to define their placement at the start of the game, we're left with object -definitions starting like this: - -.. code-block:: inform +definitions starting like this:: Room street "A street in Altdorf" @@ -836,9 +751,7 @@ the last item of header information. There's an alternative object syntax which is available to achieve the same object tree, using "arrows". That is, we could have defined those -parent-and-child objects as: - -.. code-block:: inform +parent-and-child objects as:: Room below_square "Further along the street" Furniture -> stall "fruit and vegetable stall" @@ -873,9 +786,7 @@ example, the ``tree`` and ``governor`` objects are both children of the ``-> ->``, and so on. In "William Tell", that situation doesn't occur; to illustrate how it works, imagine that at the start of the game the potatoes and the other fruit and vegetables where actually *on* the -stall. Then we might have used: - -.. code-block:: inform +stall. Then we might have used:: Room below_square "Further along the street" Furniture -> stall "fruit and vegetable stall" @@ -920,9 +831,7 @@ We went to some lengths, way back in :ref:`things-in-quotes`, to explain the difference between double quotes ``"..."`` (strings to be output) and single quotes ``'...'`` (input tokens -- dictionary words). Perhaps somewhat unfortunately, Inform allows you to blur this clean distinction: -you can use double quotes in name properties and Verb directives: - -.. code-block:: inform +you can use double quotes in name properties and Verb directives:: NPC stallholder "Helga" below_square with name "stallholder" "greengrocer" "monger" "shopkeeper" "merchant" @@ -950,5 +859,3 @@ example, see games using ``Nearby`` directives (denotes parentage, roughly the same as ``->``) and ``near`` conditions (roughly, having the same parent), or with ``" \ "`` controlling line breaks in long ``print`` statements. Try to understand them; try *not* to use them. - - diff --git a/chapters/15.rst b/chapters/15.rst index ad7d85f..ae0eff2 100644 --- a/chapters/15.rst +++ b/chapters/15.rst @@ -33,7 +33,7 @@ inflexible teacher; no moist Bambi eyes are going to save you here. Although the spell made by the compiler is always the same one, you can indicate up to a point how you want the magic to happen. There are a few options to affect the process of compilation; some you define in the -source code, some with ``switches`` and certain commands when you run +source code, some with *switches* and certain commands when you run the program. The compiler will work with some default options if you don’t define any, but you may change these if you need to. Many of these options are provided "just in case" special conditions apply; others are @@ -80,11 +80,10 @@ large. Normally, Inform compiles your source code into a Version 5 file indicates), with a maximum size of 256 Kbytes. If your game is larger than this, you’ll have to compile into Version 8 file (``.z8``), which can grow up to 512 Kbytes (and you do this very simply by setting the -``-v8`` switch; more on that in a minute). It takes a surprising amount +:option:`-v8` switch; more on that in a minute). It takes a surprising amount of code to exceed these limits; you won’t have to worry about game size for the next few months, if ever. - .. rubric:: Non-fatal errors Non-fatal errors are much more common. You'll learn to be friends with: @@ -94,9 +93,7 @@ Non-fatal errors are much more common. You'll learn to be friends with: This is the standard way of reporting a punctuation or syntax mistake. If you type a comma instead of a semicolon, Inform will be looking for something in vain. The good news is that you are pointed to the -offending line of code: - -.. code-block:: transcript +offending line of code:: Tell.inf(76): Error: Expected directive, '[' or class name but found found_in > found_in @@ -118,9 +115,7 @@ after the description string, instead of a comma: Here's a rather misleading message which maybe suggests that things in our source file are in the wrong order, or that some expected -punctuation is missing: - -.. code-block:: transcript +punctuation is missing:: Fate.inf(459): Error: Expected name for new object or its textual short name but found door @@ -179,6 +174,13 @@ string has been printed, and the ``give match ~light`` line will never happen. Inform detects the fault and warns you. Probably the designer's intention was: +.. code-block:: inform + + if (steel_door has open) { + give match ~light; + print_ret "The breeze blows out your lit match."; + } + Compiling *à la carte* ====================== @@ -186,7 +188,7 @@ One of the advantages of Inform is its portability between different systems and machines. Specific usage of the compiler varies accordingly, but some features should be in all environments. To obtain precise information about any particular version, run the compiler with the -``-h1`` switch -- see :ref:`switches`. +:option:`-h1` switch -- see :ref:`switches`. Often the compiler is run with the name of your source file as its only parameter. This tells the compiler to "read this file using Strict mode and @@ -217,7 +219,7 @@ by other people, as you saw when we incorporated ``pname.h`` into our .. note:: - on some machines, a library file is actually called -- for example -- + On some machines, a library file is actually called -- for example -- ``Parser.h``, on others just ``Parser``. The compiler automatically deals with such differences; you can *always* type simply ``Include "Parser";`` in your source file. @@ -265,37 +267,37 @@ vary between machines) would be: :samp:`inform {source_file story_file switches}` -where "``inform``" is the name of the compiler, the -:samp:`{story_file}` is optional (so that you can specify a different -name from the -:samp:`{source_file}`) and the switches are also optional. Note that -switches must be preceded by a hyphen ``-``; if you want to set, for -instance, Strict mode, you'd write ``-S`` , while if you want to -deactivate it, you’d write ``-~S``. The tilde sign can, as elsewhere, be -understood as "not". If you wish to set many switches, just write them -one after another separated by spaces and each with its own hyphen, or -merge them with one hyphen and no spaces: +where "``inform``" is the name of the compiler, the :samp:`{story_file}` is +optional (so that you can specify a different name from the +:samp:`{source_file}`) and the switches are also optional. Note that +switches must be preceded by a hyphen ``-``; if you want to set, for +instance, Strict mode, you'd write :option:`-S` , while if you want to +deactivate it, you’d write :option:`-~S`. The tilde sign can, as elsewhere, +be understood as "not". If you wish to set many switches, just write them +one after another separated by spaces and each with its own hyphen, or +merge them with one hyphen and no spaces:: - :samp:`inform MyGame.inf -S -s -X` + inform MyGame.inf -S -s -X - :samp:`inform MyGame.inf -Ssx` + inform MyGame.inf -Ssx Although there's nothing wrong with this method, it isn't awfully convenient should you need to change the switch settings. A more flexible method is to define the switches at the very start of your -source file, again in either format: +source file, again in either format:: - :samp:`!% -S -s -X` + !% -S -s -X - :samp:`!% -Ssx` + !% -Ssx -Normally, all switches are off by default, except Strict mode (``-S``), -which is on and checks the code for additional mistakes. It's well worth -adding Debug mode (``-D``), thus making the debugging verbs available at -run time. This is the ideal setting while coding, but you should turn -Debug mode off (just remove the ``-D``) when you release your game to -the public. This is fortunately very easy to check, since the game -banner ends with the letter "D" if the game was compiled in Debug mode: +Normally, all switches are off by default, except Strict mode +(:option:`-S`), which is on and checks the code for additional +mistakes. It's well worth adding Debug mode (:option:`-D`), thus making the +debugging verbs available at run time. This is the ideal setting while +coding, but you should turn Debug mode off (just remove the :option:`-D`) +when you release your game to the public. This is fortunately very easy to +check, since the game banner ends with the letter "D" if the game was +compiled in Debug mode: .. code-block:: transcript @@ -307,51 +309,63 @@ banner ends with the letter "D" if the game was compiled in Debug mode: Switches are case sensitive, so you get different effects from ``-x`` and ``-X``. Some of the more useful switches are: -:samp:`-~S` - Set compiler Strict mode off. This deactivates some additional error - checking features when it reads your source file. Strict mode is on by - default. - -:samp:`-v5 -v8` - Compile to this version of story file. Versions 5 (on by default) and - 8 are the only ones you should ever care about; they produce, - respectively, story files with the extensions .z5 and .z8 . Version 5 - was the Advanced Infocom design, and is the default produced by - Inform. This is the version you'll normally be using, which allows - file sizes up to 256 Kbytes. If your game grows beyond that size, - you'll need to compile to the Version 8 story file, which is very - similar to Version 5 but allows a 512 Kbytes file size. - -:samp:`-D -X` - Include respectively the debugging verbs and the Infix debugger in the - story file (see :doc:`16`). - -:samp:`-h1 -h2` - Display help information about the compiler. ``-h1`` produces - information about file naming, and ``-h2`` about the available - switches. - -:samp:`-n -j` - ``-n`` displays the number of declared attributes, properties and - actions. ``-j`` lists objects as they are being read and constructed - in the story file. - -:samp:`-s` - Offer game statistics. This provides a lot of information about your - game, including the number of objects, verbs, dictionary entries, - memory usage, etc., while at the same time indicating the maximum - allowed for each entry. This can be useful to check whether you are - nearing the limits of Inform. - -:samp:`-r` - Record all the text of the game into a temporary file, useful to check - all your descriptions and messages by running them through a spelling - checker. - -If you run the compiler with the ``-h2`` switch, you’ll find that there -are many more switches than these, offering mostly advanced or obscure -features which we consider to be of little interest to beginners. -However, feel free to try whatever switches catch your eye; nothing you -try here will affect your source file, which is strictly read-only as -far as the compiler is concerned. +.. option:: -S +.. option:: -~S + + Set compiler Strict mode on or off, respectively. Strict mode activates + some additional error checking features when it reads your source file. + Strict mode is on by default. + +.. option:: -v5 +.. option:: -v8 + + Compile to this version of story file. Versions 5 (on by default) and + 8 are the only ones you should ever care about; they produce, + respectively, story files with the extensions .z5 and .z8. Version 5 + was the Advanced Infocom design, and is the default produced by + Inform. This is the version you'll normally be using, which allows + file sizes up to 256 Kbytes. If your game grows beyond that size, + you'll need to compile to the Version 8 story file, which is very + similar to Version 5 but allows a 512 Kbytes file size. + +.. option:: -D +.. option:: -X + + Include respectively the debugging verbs and the Infix debugger in the + story file (see :doc:`16`). + +.. option:: -h1 +.. option:: -h2 + + Display help information about the compiler. :option:`-h1` produces + innformation about file naming, and :option:`-h2` about the available + switches. + +.. option:: -n +.. option:: -j + + :option:`-n` displays the number of declared attributes, properties and + actions. :option:`-j` lists objects as they are being read and constructed + in the story file. + +.. option:: -s +.. option:: -~s + + Offer game statistics (or not). This provides a lot of information about + your game, including the number of objects, verbs, dictionary entries, + memory usage, etc., while at the same time indicating the maximum + allowed for each entry. This can be useful to check whether you are + nearing the limits of Inform. + +.. option:: -r + + Record all the text of the game into a temporary file, useful to check + all your descriptions and messages by running them through a spelling + checker. +If you run the compiler with the :option:`-h2` switch, you’ll find that +there are many more switches than these, offering mostly advanced or +obscure features which we consider to be of little interest to beginners. +However, feel free to try whatever switches catch your eye; nothing you try +here will affect your source file, which is strictly read-only as far as +the compiler is concerned. diff --git a/chapters/16.rst b/chapters/16.rst index 6d358e0..a255484 100644 --- a/chapters/16.rst +++ b/chapters/16.rst @@ -1,6 +1,6 @@ -=================== -Debugging your game -=================== +===================== + Debugging your game +===================== .. only:: html @@ -58,11 +58,10 @@ always pays off in the end.) To help you out in this daunting task, Inform has a stock of special actions: the debugging verbs. They become available at run-time when the -source file is compiled in :term:`Debug mode` (``-D switch``). When you are -ready to release your game, you’ll have to recompile, switching off Debug -to avoid allowing the players to benefit from the debugging verbs. We'll -cover briefly a few of these actions, and tell you what they do. - +source file is compiled in :term:`Debug mode` (:option:`-D` switch). When +you are ready to release your game, you’ll have to recompile, switching off +Debug to avoid allowing the players to benefit from the debugging verbs. +We'll cover briefly a few of these actions, and tell you what they do. Command lists ============= @@ -288,16 +287,16 @@ ABSTRACT *object* TO *object* ``container``, a ``supporter`` , or something ``animate``. -Infix: the harlot's perogative -============================== +Infix: the harlot's prerogative +=============================== -The basic debugging verbs are fairly versatile, easy to use, and don't -consume a lot of memory. Occasionally though, you'll meet a bug which -you simply can't catch using regular techniques, and that’s when you -might want to investigate the Infix debugger. You'll need to compile -using the ``-X`` switch, and you'll then be able to monitor and modify -almost all of your game’s data and objects. For instance, you can use -";" to inspect -- and change -- a variable: +The basic debugging verbs are fairly versatile, easy to use, and don't +consume a lot of memory. Occasionally though, you'll meet a bug which you +simply can't catch using regular techniques, and that’s when you might want +to investigate the Infix debugger. You'll need to compile using the +:option:`-X` switch, and you'll then be able to monitor and modify almost +all of your game’s data and objects. For instance, you can use ";" to +inspect -- and change -- a variable: .. code-block:: transcript @@ -372,7 +371,12 @@ change: "OK, Herr Tell, now you're in real trouble. ... -.. todo:: "Herr" above is italicized. Was that a mistake in the original text? +.. todo:: + + "Herr" above is italicized. Was that a mistake in the original text? + + Update: I don't think so. In 08.rst, lines 465 and 516, "Herr" is + explicitly underlined (which probably appears italicized on output). Infix is quite complex -- there are more commands than those we have shown you -- so while it's good to have available, it's not really a @@ -384,7 +388,6 @@ to make permanent amendments, you still need to edit the source file. You won't need it often, but Infix can sometimes provide quick answers to tricky problems. - No matter what ============== @@ -420,7 +423,7 @@ then wrote: * Benny will force the player back into the cafe even when the key is dropped in the café, or put on the counter (in Benny's plain sight!). -Of course, the code we've offered you in this edition takes care of +Of course, the code we've offered you in *this* edition takes care of those embarrassing issues, but it might very well happen that a few more undetected absurdities pop up from now on. @@ -437,32 +440,29 @@ The IF community offers some beta-testing resources, or you can always ask in RAIF for kind souls willing to have a go at your game. Remember the golden rules: - * **Expect no mercy**. Although it hurts, a merciless approach is what - you need at this time; much better to discover your errors and - oversights now, before you release the game more widely. And don't - forget to acknowledge your testers' assistance somewhere within the - game. - - * **Never say never**. If your testers suggest that the game should - respond better to an attempted action, don't automatically respond - with "No one's going to try that!" They already have, and will again - -- be grateful for your testers' devious minds and twisted psyches. - Although a normal player won't try all of those oddball things, - every player is bound to try at least one, and their enjoyment will - be greater, the reality enhanced, if the game "understands". - - * **Ask for more**. Don't treat your testers simply as validators of - your programming skills, but rather as reviewers of your - storytelling abilities. Encourage them to comment on how well the - pieces fit together, and to make suggestions -- small or radical -- - for improvement; don't necessarily reject good ideas just because - implementing them "will take too long". For example: "the scene in - the Tower of London doesn't somehow seem to belong in an Arabian - Nights game", or "having to solve three puzzles in a row just to - discover the plate of sheep's eyes is a little over the top", or - "this five-room trek across the desert really is a bit dull; - perhaps you could add a quicksand or something to liven it up?", or - "the character of the eunuch in the harem seems to be lacking in - something". That is, view the testers collectively not as simple - spell-checkers, but rather as collaborative editors on your latest - novel. +* **Expect no mercy**. Although it hurts, a merciless approach is what you + need at this time; much better to discover your errors and oversights + now, before you release the game more widely. And don't forget to + acknowledge your testers' assistance somewhere within the game. + +* **Never say never**. If your testers suggest that the game should + respond better to an attempted action, don't automatically respond with + "No one's going to try that!" They already have, and will again -- be + grateful for your testers' devious minds and twisted psyches. Although a + normal player won't try *all* of those oddball things, every player is + bound to try at least *one*, and their enjoyment will be greater, the + reality enhanced, if the game "understands". + +* **Ask for more**. Don't treat your testers simply as validators of your + programming skills, but rather as reviewers of your storytelling + abilities. Encourage them to comment on how well the pieces fit together, + and to make suggestions -- small or radical -- for improvement; don't + necessarily reject good ideas just because implementing them "will take + too long". For example: "the scene in the Tower of London doesn't somehow + seem to belong in an Arabian Nights game", or "having to solve three + puzzles in a row just to discover the plate of sheep's eyes is a little + over the top", or "this five-room trek across the desert really is a bit + dull; perhaps you could add a quicksand or something to liven it up?", or + "the character of the eunuch in the harem seems to be lacking in + something". That is, view the testers collectively not as simple + spell-checkers, but rather as collaborative editors on your latest novel. diff --git a/chapters/17.rst b/chapters/17.rst index f0b148c..c4a69d1 100644 --- a/chapters/17.rst +++ b/chapters/17.rst @@ -10,7 +10,6 @@ -- The Continental Op in Dashiell Hammett's *Red Harvest*. - .. only:: html .. image:: /images/picJ.png @@ -151,7 +150,6 @@ September to keep an eye open for the Interactive Fiction Competition And, who knows? It might be that next year we’ll all be smashed by *your* entry. - .. todo:: This signoff should be aligned to the right side. *Sonja and Roger* diff --git a/conf.py b/conf.py index 1621a52..956d4bc 100644 --- a/conf.py +++ b/conf.py @@ -22,6 +22,8 @@ import codecs # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, ".") +import tools.sphinxpatch + from tools.inform import InformLexer from tools.transcript import TranscriptLexer diff --git a/endnotes.rst b/endnotes.rst deleted file mode 100644 index ff786a3..0000000 --- a/endnotes.rst +++ /dev/null @@ -1,9 +0,0 @@ -==================== - About this version -==================== - -This version of the IBG is converted from the 3rd edition PDF file. It's a -work-in-progress. Here's a partial list of stuff still to do, with -references to their places in the text: - -.. todolist:: diff --git a/index.rst b/index.rst index 20eeac8..f2b668a 100644 --- a/index.rst +++ b/index.rst @@ -9,6 +9,7 @@ copyright history + todo .. toctree:: :maxdepth: 1 @@ -41,7 +42,3 @@ * :ref:`genindex` * :ref:`search` - - .. toctree:: - - endnotes diff --git a/todo.rst b/todo.rst new file mode 100644 index 0000000..dcce9d3 --- /dev/null +++ b/todo.rst @@ -0,0 +1,9 @@ +============ + TO-DO list +============ + +This version of the IBG is converted from the 3rd edition PDF file. It's +currently a work-in-progress. Here's a partial list of things still to +address, with references to their places in the text: + +.. todolist:: diff --git a/tools/inform.py b/tools/inform.py index 94b4b03..73b0d0d 100644 --- a/tools/inform.py +++ b/tools/inform.py @@ -44,7 +44,9 @@ properties = ["n_to", "s_to", "e_to", "w_to", "ne_to", "se_to", "nw_to", "time_left", "time_out", "when_closed", "when_open", "when_on", "when_off", "with_key"] -keywords = ["box", "break", "continue", "do", "else", "font off", "font on", +extension_properties = ["pname"] + +keywords = ["box", "break", "continue", "do", "else", "font", "for", "give", "has", "hasnt", "if", "in", "inversion", "jump", "move", "new_line", "notin", "objectloop", "ofclass", "or", "print", "print_ret", "provides", "quit", "read", "remove", @@ -80,7 +82,7 @@ class InformLexer(RegexLexer): (r'\\', Text), (r'=', Operator), (r"[A-Za-z_,]+:", Name.Label), - (r"<<\S+>>", Name.Label), + (r"<.+?>", Name.Label), (wordlist(objects), Name.Class), (wordlist(keywords), Token.Keyword.Reserved), @@ -89,6 +91,8 @@ class InformLexer(RegexLexer): (wordlist(attributes), Name.Attribute), (wordlist(constants), Name.Constant), + (wordlist(extension_properties), Name.Builtin), + (r'[a-zA-Z_][a-zA-Z0-9_.]*', Name), (r'(\d+\.?\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float), (r'\d+', Number.Integer), diff --git a/tools/sphinxpatch.py b/tools/sphinxpatch.py new file mode 100644 index 0000000..44013e6 --- /dev/null +++ b/tools/sphinxpatch.py @@ -0,0 +1,10 @@ +""" +Various monkey-patches for sphinx. +""" + +# Tweak Sphinx domain option regexp to add ~ for Inform options. +import re +import sphinx.domains.std as std + +std.option_desc_re = re.compile(r'((?:/|--|-|\+)?[-?@~#_a-zA-Z0-9]+)(=?\s*.*)') + -- 2.31.1