From fb8b7c14f10733e913e2b87f9a82e5b44c0dc7be Mon Sep 17 00:00:00 2001 From: Glenn Hutchings Date: Thu, 16 Jun 2016 21:04:46 +0100 Subject: [PATCH] Add special RST roles for the Inform entities. --- appendices/c.rst | 8 +- appendices/f.rst | 937 ++++++++++++++++++++++++++++++++++------------- appendices/g.rst | 14 +- chapters/02.rst | 3 + chapters/03.rst | 116 +++--- chapters/04.rst | 37 +- chapters/05.rst | 119 +++--- chapters/06.rst | 104 +++--- chapters/07.rst | 171 ++++----- chapters/08.rst | 62 ++-- chapters/09.rst | 131 +++---- chapters/10.rst | 60 +-- chapters/11.rst | 110 +++--- chapters/12.rst | 53 +-- chapters/13.rst | 74 ++-- chapters/14.rst | 19 +- chapters/15.rst | 2 +- chapters/16.rst | 8 +- conf.py | 3 + config/defs.rst | 20 + 20 files changed, 1265 insertions(+), 786 deletions(-) diff --git a/appendices/c.rst b/appendices/c.rst index 947fa49..b3277c2 100644 --- a/appendices/c.rst +++ b/appendices/c.rst @@ -94,8 +94,8 @@ you do, though, you'll get this:: > Whoops! We've fallen foul of Inform's rule saying that every room must -have a ``description`` property, to be displayed by the interpreter when -you enter that room. Our ``street`` stub hasn't got a ``description``, +have a :prop:`description` property, to be displayed by the interpreter when +you enter that room. Our ``street`` stub hasn't got a :prop:`description`, so although the game compiles successfully, it still causes an error to be reported at run-time. @@ -111,7 +111,7 @@ class, thus: By doing this, we ensure that *every* room has a description of some form; normally we'd override this default value with something meaningful -- "The narrow street runs north towards the town square..." -and so on -- by including a ``description`` property in the object's +and so on -- by including a :prop:`description` property in the object's definition. However, in a stub object used only for testing, a default description is sufficient (and less trouble):: @@ -138,7 +138,7 @@ external names with our ``street`` , ``bow`` and ``quiver`` stubs, the compiler has provided some for us -- ``(street)`` , ``(bow)`` and ``(quiver)`` -- simply by adding parentheses around the internal IDs which we used. And, because our ``bow`` and ``quiver`` stubs have no -``name`` properties, we can't actually refer to those objects when +:prop:`name` properties, we can't actually refer to those objects when playing the game. Neither of these points would be acceptable in a finished game, but for testing purposes at this early stage -- they'll do. diff --git a/appendices/f.rst b/appendices/f.rst index 0dc8e64..dd513c0 100644 --- a/appendices/f.rst +++ b/appendices/f.rst @@ -21,11 +21,13 @@ properties and attributes, the verb grammars and actions. Library objects =============== -`compass` - A `container` object holding the twelve direction objects `d_obj e_obj - in_obj n_obj ne_obj nw_obj out_obj s_obj se_obj sw_obj u_obj w_obj`. +:obj:`compass` + A :attr:`container` object holding the twelve direction objects + :obj:`d_obj`, :obj:`e_obj`, :obj:`in_obj`, :obj:`n_obj`, :obj:`ne_obj`, + :obj:`nw_obj`, :obj:`out_obj`, :obj:`s_obj`, :obj:`se_obj`, + :obj:`sw_obj`, :obj:`u_obj`, :obj:`w_obj`. -`LibraryMessages` +:obj:`LibraryMessages` If defined (between Includes of `Parser` and `VerbLib`), changes standard library messages: @@ -42,20 +44,20 @@ Library objects | `...` | `];` -`selfobj` - The default player object. Avoid: use instead the `player` variable, - which usually refers to `selfobj`. +:obj:`selfobj` + The default player object. Avoid: use instead the :var:`player` + variable, which usually refers to :obj:`selfobj`. -`thedark` - A pseudo-room which becomes the `location` when there is no light +:obj:`thedark` + A pseudo-room which becomes the :var:`location` when there is no light (although the player object is not moved there). Library constants ================= -In addition to the standard constants `true` (1), `false` (0) and `nothing` -(0), the Library defines `NULL` (-1) for an `{action}`, `{property}` or -`{pronoun}` whose current value is undefined. +In addition to the standard constants :const:`true` (1), :const:`false` (0) +and :const:`nothing` (0), the Library defines :const:`NULL` (-1) for an +`{action}`, `{property}` or `{pronoun}` whose current value is undefined. `LIBRARY_PARSER`, `LIBRARY_ENGLISH`, `LIBRARY_VERBLIB` and `LIBRARY_GRAMMAR` are defined to mark the end of inclusion of `Parser.h`, @@ -125,67 +127,121 @@ Some constants control features rather than represent values. `WITHOUT_DIRECTIONS` De-activates standard compass directions (bar "`IN`" and "`OUT`"). Place - alternative directions in the `compass`. + alternative directions in the :obj:`compass`. Library variables ================= -`action` +.. index:: + pair: action; library variable + +:var:`action` The current `{action}`. -`actor` +.. index:: + pair: actor; library variable + +:var:`actor` The target of an instruction: the player, or an NPC. -`deadflag` +.. index:: + pair: deadflag; library variable + +:var:`deadflag` Normally 0: 1 indicates a regular death, 2 indicates that the player has won, 3 or more denotes a user-defined end. -`inventory_stage` - Used by `invent` and `list_together` properties. +.. index:: + pair: inventory_stage; library variable + +:var:`inventory_stage` + Used by :prop:`invent` and :prop:`list_together` properties. + +.. index:: + pair: keep_silent; library variable -`keep_silent` - Normally `false`; `true` makes most :ref:`group 2 actions +:var:`keep_silent` + Normally :const:`false`; :const:`true` makes most :ref:`group 2 actions ` silent. -`location` +.. index:: + pair: location; library variable + +:var:`location` The player's current room; unless that's dark, when it contains - `thedark`, `real_location` contains the room. + :obj:`thedark`, :var:`real_location` contains the room. + +.. index:: + pair: notify_mode; library variable -`notify_mode` - Normally `true`: `false` remains silent when score changes. +:var:`notify_mode` + Normally :const:`true`: :const:`false` remains silent when score changes. -`noun` +.. index:: + pair: noun; library variable + +:var:`noun` The primary focus object for the current action. -`player` +.. index:: + pair: player; library variable + +:var:`player` The object acting on behalf of the human player. -`real_location` +.. index:: + pair: real_location; library variable + +:var:`real_location` The player's current room when in the dark. -`score` +.. index:: + pair: score; library variable + +:var:`score` The current score. -`second` +.. index:: + pair: second; library variable + +:var:`second` The secondary focus object for the current action. -`self` +.. index:: + pair: self; library variable + +:var:`self` The object which received a message. (Note: a run-time variable, not a compile-time constant.) -`sender` +.. index:: + pair: sender; library variable + +:var:`sender` The object which sent a message (or `nothing`). -`task_scores` +.. index:: + pair: task_scores; library variable + +:var:`task_scores` A byte array holding scores for the task scoring system. -`the_time` +.. index:: + pair: the_time; library variable + +:var:`the_time` The game's clock, in minutes 0..1439 since midnight. -`turns` +.. index:: + pair: turns; library variable + +:var:`turns` The game's turn counter. -`wn` +.. index:: + pair: wn; library variable + +:var:`wn` The input stream word number, counting from 1. .. _library-routines: @@ -193,112 +249,198 @@ Library variables Library routines ================ +.. index:: + pair: Achieved; library routine + `Achieved({expr})` A scored task has been achieved. +.. index:: + pair: AfterRoutines; library routine + `AfterRoutines()` In a :ref:`group 2 action `, controls output of "after" messages. +.. index:: + pair: AllowPushDir; library routine + `AllowPushDir()` An object can be pushed from one location to another. +.. index:: + pair: Banner; library routine + `Banner()` Prints the game banner. +.. index:: + pair: ChangePlayer; library routine + `ChangePlayer({obj_id,flag})` Player assumes the persona of the `{obj_id}`. If the optional `{flag}` - is `true`, room descriptions include "(as `{object}`)". + is :const:`true`, room descriptions include "(as `{object}`)". + +.. index:: + pair: CommonAncestor; library routine `CommonAncestor({obj_id1,obj_id2})` Returns the nearest object which has a parental relationship to both `{obj_ids}`, or `nothing`. +.. index:: + pair: DictionaryLookup; library routine + `DictionaryLookup({byte_array,length})` Returns address of word in dictionary, or 0 if not found. +.. index:: + pair: DrawStatusLine; library routine + `DrawStatusLine()` Refreshes the status line; happens anyway at end of each turn. +.. index:: + pair: GetGNAOfObject; library routine + `GetGNAOfObject({obj_id})` Returns gender-number-animation 0..11 of the `{obj_id}`. +.. index:: + pair: HasLightSource; library routine + `HasLightSource({obj_id})` - Returns `true` if the `{obj_id}` has light. + Returns :const:`true` if the `{obj_id}` has light. + +.. index:: + pair: IndirectlyContains; library routine `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}`. + Returns :const:`true` if `{obj_id}` is currently a child or grand-child + or great-grand-child... of the `{parent_object}`. + +.. index:: + pair: IsSeeThrough; library routine `IsSeeThrough({obj_id})` - Returns `true` if light can pass through the `{obj_id}`. + Returns :const:`true` if light can pass through the `{obj_id}`. + +.. index:: + pair: Locale; library routine `Locale({obj_id,"string1","string2"})` Describes the contents of `{obj_id}`, and returns their number. After objects with own paragraphs, the rest are listed preceded by `{string1}` or `{string2}`. +.. index:: + pair: LoopOverScope; library routine + `LoopOverScope({routine_id,actor})` Calls `{routine_id}({obj_id})` for each `{obj_id}` in scope. If the optional `{actor}` is supplied, that defines the scope. +.. index:: + pair: MoveFloatingObjects; library routine + `MoveFloatingObjects()` Adjusts positions of game's `found_in` objects. +.. index:: + pair: NextWord; library routine + `NextWord()` - Returns the next dictionary word in the input stream, incrementing `wn` - by one. Returns `false` if the word is not in the dictionary, or if the - input stream is exhausted. + Returns the next dictionary word in the input stream, incrementing + :var:`wn` by one. Returns :const:`false` if the word is not in the + dictionary, or if the input stream is exhausted. + +.. index:: + pair: NextWordStopped; library routine `NextWordStopped()` - Returns the next dictionary word in the input stream, incrementing `wn` - by one. Returns `false` if the word is not in the dictionary, -1 if the - input stream is exhausted. + Returns the next dictionary word in the input stream, incrementing + :var:`wn` by one. Returns :const:`false` if the word is not in the + dictionary, -1 if the input stream is exhausted. + +.. index:: + pair: NounDomain; library routine `NounDomain({obj_id1,obj_id2,type})` Performs object parsing; see also `ParseToken()`. +.. index:: + pair: ObjectIsUntouchable; library routine + `ObjectIsUntouchable({obj_id,flag})` Tests whether there is a barrier - a container object which is not open - - between player and `{obj_id}`. Unless the optional `{flag}` is `true`, - outputs "You can't because ... is in the way". Returns `true` is a - barrier is found, otherwise `false`. + between player and `{obj_id}`. Unless the optional `{flag}` is + :const:`true`, outputs "You can't because ... is in the way". Returns + :const:`true` is a barrier is found, otherwise :const:`false`. + +.. index:: + pair: OffersLight; library routine `OffersLight({obj_id})` - Returns `true` if the `{obj_id}` offers light. + Returns :const:`true` if the `{obj_id}` offers light. + +.. index:: + pair: ParseToken; library routine `ParseToken({type,value})` Performs general parsing; see also `NounDomain()`. +.. index:: + pair: PlaceInScope; library routine + `PlaceInScope({obj_id})` - Used in an `add_to_scope` property or `scope=` token to put the + Used in an :prop:`add_to_scope` property or `scope=` token to put the `{obj_id}` into scope for the parser. +.. index:: + pair: PlayerTo; library routine + `PlayerTo({obj_id,flag})` Moves the player to `{obj_id}`. Prints its description unless optional `{flag}` is 1 (no description) or 2 (as if walked in). +.. index:: + pair: PrintOrRun; library routine + `PrintOrRun({obj_id,property,flag})` If `{obj_id.property}` is a string, output it (followed by a newline - unless optional `{flag}` is `true`), and return `true`. If it's a - routine, run it and return what the routine returns. + unless optional `{flag}` is :const:`true`), and return :const:`true`. If + it's a routine, run it and return what the routine returns. + +.. index:: + pair: PronounNotice; library routine `PronounNotice({obj_id})` Associates an appropriate pronoun with the `{obj_id}`. +.. index:: + pair: PronounValue; library routine + `PronounValue('{pronoun}')` Returns the object to which '`it`' (or '`him`', '`her`', '`them`') - currently refers, or `nothing`. + currently refers, or :const:`nothing`. + +.. index:: + pair: ScopeWithin; library routine `ScopeWithin({obj_id})` - Used in an `add_to_scope` property or `scope=` token to put the contents - of the `{obj_id}` in scope for the parser. + Used in an :prop:`add_to_scope` property or `scope=` token to put the + contents of the `{obj_id}` in scope for the parser. + +.. index:: + pair: SetPronoun; library routine `SetPronoun('{pronoun}',{obj_id})` Defines the `{obj_id}` to which a given pronoun refers. -`SetTime({expr1,expr2})` +.. index:: + pair: SetTime; library routine +`SetTime({expr1,expr2})` Sets `the_time` to `{expr1}` (in mins 0..1439 since midnight), running at `{expr2}` - @@ -306,53 +448,94 @@ Library routines | -ve: `{-expr2}` turns take one minute; | zero: time stands still. +.. index:: + pair: StartDaemon; library routine + `StartDaemon({obj_id})` Starts the `{obj_id}`\'s daemon. +.. index:: + pair: StartTimer; library routine + `StartTimer({obj_id,expr})` - Starts the `{obj_id}`\'s timer, initialising its `time_left` to `{expr}`. - The object's `time_out` property will be called after that number of - turns have elapsed. + Starts the `{obj_id}`\'s timer, initialising its :prop:`time_left` to + `{expr}`. The object's :prop:`time_out` property will be called after + that number of turns have elapsed. + +.. index:: + pair: StopDaemon; library routine `StopDaemon({obj_id})` Stops the `{obj_id}`\'s daemon. +.. index:: + pair: StopTimer; library routine + `StopTimer({obj_id})` Stops the `{obj_id}`\'s timer. +.. index:: + pair: TestScope; library routine + `TestScope({obj_id,actor})` - Returns `true` if the `{obj_id}` is in scope, otherwise `false`. If the - optional `{actor}` is supplied, that defines the scope. + Returns :const:`true` if the `{obj_id}` is in scope, otherwise + :const:`false`. If the optional `{actor}` is supplied, that defines the + scope. + +.. index:: + pair: TryNumber; library routine `TryNumber({expr})` Parses word `{expr}` in the input stream as a number, recognising decimals, also English words one..twenty. Returns the number 1..10000, or -1000 if the parse fails. +.. index:: + pair: UnsignedCompare; library routine + `UnsignedCompare({expr1,expr2})` Returns -1 if `{expr1}` is less than `{expr2}`, 0 if `{expr1}` equals `{expr2}`, and 1 if `{expr1}` is greater than `{expr2}`. Both expressions are unsigned, in the range 0..65535. +.. index:: + pair: WordAddress; library routine + `WordAddress({expr})` Returns a byte array containing the raw text of word `{expr}` in the input stream. +.. index:: + pair: WordInProperty; library routine + `WordInProperty({word,obj_id,property})` - Returns `true` if the dictionary `{word}` is listed in the `{property}` - values for the `{obj_id}`. + Returns :const:`true` if the dictionary `{word}` is listed in the + `{property}` values for the `{obj_id}`. + +.. index:: + pair: WordLength; library routine `WordLength({expr})` Returns the length of word `{expr}` in the input stream. +.. index:: + pair: WriteListFrom; library routine + `WriteListFrom({obj_id,expr})` Outputs a list of `{obj_id}` and its siblings, in the given style, an `{expr}` formed by adding any of: `ALWAYS_BIT`, `CONCEAL_BIT`, `DEFART_BIT`, `ENGLISH_BIT`, `FULLINV_BIT`, `INDENT_BIT`, `ISARE_BIT`, `NEWLINE_BIT`, `PARTINV_BIT`, `RECURSE_BIT`, `TERSE_BIT`, `WORKFLAG_BIT`. +.. index:: + pair: YesOrNo; library routine + `YesOrNo()` - Returns `true` if the player types "`YES`", `false` for "`NO`". + Returns :const:`true` if the player types "`YES`", :const:`false` for + "`NO`". + +.. index:: + pair: ZRegion; library routine `ZRegion({arg})` Returns the type of its `{arg}` : 3 for a string address, 2 for a routine @@ -364,8 +547,8 @@ Object properties ================= Where the `value` of a property can be a routine, several formats are -possible (but remember: embedded "`]`" returns `false`, standalone "`]`" -returns `true`): +possible (but remember: embedded "`]`" returns :const:`false`, standalone +"`]`" returns :const:`true`): | `{property} [; {stmt}; {stmt}; ... ]` | `{property} [; return {routine_id}(); ]` @@ -378,12 +561,18 @@ for the `Object` normally overrides the value inherited from the `Class`. However, if the property is additive then both values apply, with the Object's value being considered first. -`add_to_scope` +.. index:: + pair: add_to_scope; library property + +:prop:`add_to_scope` For an object: additional objects which follow it in and out of scope. The `{value}` can be a space-separated list of `{obj_ids}`, or a routine which invokes `PlaceInScope()` or `ScopeWithin()` to specify objects. -`after` |ADD| +.. index:: + pair: after; library property + +:prop:`after` |ADD| For an object: receives every `{action}` and `{fake_action}` for which this is the `{noun}`. For a room: receives every `{action}` which occurs here. @@ -391,150 +580,215 @@ Object's value being considered first. The `{value}` is a routine of structure similar to a `switch` statement, having cases for the appropriate `{actions}` (and an optional `default` as well); it is invoked after the action has happened, but before the - player has been informed. The routine should return `false` to continue, - telling the player what has happened, or `true` to stop processing the - action and produce no further output. + player has been informed. The routine should return :const:`false` to + continue, telling the player what has happened, or :const:`true` to stop + processing the action and produce no further output. + +.. index:: + pair: article; library property -`article` +:prop:`article` For an object: the object's indefinite article - the default is automatically "a", "an" or "some". The `{value}` can be a string, or a routine which outputs a string. -`articles` +.. index:: + pair: articles; library property + +:prop:`articles` For a non-English object: its definite and indefinite articles. The `{value}` is an array of strings. -`before` |ADD| +.. index:: + pair: before; library property + +:prop:`before` |ADD| For an object: receives every `{action}` and `{fake_action}` for which this is the `{noun}`. For a room: receives every action which occurs here. The `{value}` is a routine invoked before the action has happened. See - `after`. + :prop:`after`. + +.. index:: + pair: cant_go; library property -`cant_go` +:prop:`cant_go` For a room: the message when the player attempts an impossible exit. The `{value}` can be a string, or a routine which outputs a string. -`capacity` - For a `container` or `supporter` object: the number of objects which can - be placed in or on it - the default is 100. +.. index:: + pair: capacity; library property - For the player: the number which can be carried - `selfobj` has an +:prop:`capacity` + For a :attr:`container` or :attr:`supporter` object: the number of + objects which can be placed in or on it - the default is 100. + + For the player: the number which can be carried - :obj:`selfobj` has an initial capacity of `MAX_CARRIED`. The `{value}` can be a number, or a routine which returns a number. -`d_to` +.. index:: + pair: d_to; library property + +:prop:`d_to` For a room: a possible exit. The `{value}` can be - * `false` (the default): not an exit; + * :const:`false` (the default): not an exit; * a string: output to explain why this is not an exit; * a `{room}`: the exit leads to this room; - * a `door` object: the exit leads through this door; - * a routine which should return `false`, a string, a `{room}`, a `door` - object, or `true` to signify "not an exit" and produce no further - output. + * a :obj:`door` object: the exit leads through this door; + * a routine which should return :const:`false`, a string, a `{room}`, a + :obj:`door` object, or :const:`true` to signify "not an exit" and + produce no further output. -`daemon` +.. index:: + pair: daemon; library property + +:prop:`daemon` The `{value}` is a routine which can be activated by `StartDaemon({obj_id})` and which then runs once each turn until deactivated by `StopDaemon({obj_id})`. -`describe` |ADD| +.. index:: + pair: describe; library property + +:prop:`describe` |ADD| For an object: called before the object's description is output. For a room: called before the room's (long) description is output. - The `{value}` is a routine which should return `false` to continue, - outputting the usual description, or `true` to stop processing and + The `{value}` is a routine which should return :const:`false` to continue, + outputting the usual description, or :const:`true` to stop processing and produce no further output. -`description` +.. index:: + pair: description; library property + +:prop:`description` For an object: its description (output by `Examine`). For a room: its long description (output by `Look`). The `{value}` can be a string, or a routine which outputs a string. -`door_dir` - For a `compass` object (`d_obj`, `e_obj`, ...): the direction in which an - attempt to move to this object actually leads. +.. index:: + pair: door_dir; library property + +:prop:`door_dir` + For a :obj:`compass` object (:obj:`d_obj`, :obj:`e_obj`, ...): the + direction in which an attempt to move to this object actually leads. + + For a :obj:`door` object: the direction in which this door leads. - For a `door` object: the direction in which this door leads. + The `{value}` can be a directional property (:prop:`d_to`, :prop:`e_to`, + \...), or a routine which returns such a property. - The `{value}` can be a directional property (`d_to`, `e_to`, ...), or a - routine which returns such a property. +.. index:: + pair: door_to; library property -`door_to` +:prop:`door_to` For a `door` object: where it leads. The value can be - * `false` (the default): leads nowhere; + * :const:`false` (the default): leads nowhere; * a string: output to explain why door leads nowhere; * a `{room}`: the door leads to this room; - * a routine which should return `false`, a string, a `{room}`, or `true` - to signify "leads nowhere" without producing any output. + * a routine which should return :const:`false`, a string, a `{room}`, or + :const:`true` to signify "leads nowhere" without producing any output. + +.. index:: + pair: e_to; library property + +:prop:`e_to` + See :prop:`d_to`. -`e_to` - See `d_to`. +.. index:: + pair: each_turn; library property -`each_turn` |ADD| +:prop:`each_turn` |ADD| Invoked at the end of each turn (after all appropriate daemons and timers) whenever the object is in scope. The `{value}` can be a string, or a routine. -`found_in` +.. index:: + pair: found_in; library property + +:prop:`found_in` For an object: the rooms where this object can be found, unless it has - the `absent` attribute. The `{value}` can be + the :attr:`absent` attribute. The `{value}` can be * a space-separated list of `{rooms}` (where this object can be found) or `{obj_ids}` (whose locations are tracked by this object); - * a routine which should return `true` if this object can be found in the - current location, otherwise `false`. + * a routine which should return :const:`true` if this object can be found + in the current location, otherwise :const:`false`. + +.. index:: + pair: grammar; library property + +:prop:`grammar` + For an :attr:`animate` or :attr:`talkable` object: the `{value}` is a + routine called when the parser knows that this object is being addressed, + but has yet to test the grammar. The routine should return + :const:`false` to continue, :const::const:`true` to indicate that the + routine has parsed the entire command, or a dictionary word ('`word`' or + -'`word`'). + +.. index:: + pair: in_to; library property -`grammar` - For an `animate` or `talkable` object: the `{value}` is a routine called - when the parser knows that this object is being addressed, but has yet to - test the grammar. The routine should return `false` to continue, `true` - to indicate that the routine has parsed the entire command, or a - dictionary word ('`word`' or -'`word`'). +:prop:`in_to` + See :prop:`d_to`. -`in_to` - See `d_to`. +.. index:: + pair: initial; library property -`initial` +:prop:`initial` For an object: its description before being picked up. For a room: its description when the player enters the room. The `{value}` can be a string, or a routine which outputs a string. -`inside_description` +.. index:: + pair: inside_description; library property + +:prop:`inside_description` For an `enterable` object: its description, output as part of the room description when the player is inside the object. The `{value}` can be a string, or a routine which outputs a string. -`invent` +.. index:: + pair: invent; library property + +:prop:`invent` For an object: the `{value}` is a routine for outputting the object's inventory listing, which is called twice. On the first call nothing has - been output; `inventory_stage` has the value 1, and the routine should - return `false` to continue, or `true` to stop processing and produce no - further output. On the second call the object's indefinite article and - short name have been output, but not any subsidiary information; - `inventory_stage` has the value 2, and the routine should return `false` - to continue, or `true` to stop processing and produce no further output. - -`life` |ADD| + been output; :var:`inventory_stage` has the value 1, and the routine + should return :const:`false` to continue, or :const:`true` to stop + processing and produce no further output. On the second call the + object's indefinite article and short name have been output, but not any + subsidiary information; :var:`inventory_stage` has the value 2, and the + routine should return :const:`false` to continue, or :const:`true` to + stop processing and produce no further output. + +.. index:: + pair: life; library property + +:prop:`life` |ADD| For an `animate` object: receives person-to-person actions (`Answer`, `Ask`, `Attack`, `Give`, `Kiss`, `Order`, `Show`, `Tell`, `ThrowAt` and `WakeOther`) for which this is the `{noun}`. The `{value}` is a routine of structure similar to a `switch` statement, having cases for the appropriate `{actions}` (and an optional default as well). The routine - should return `false` to continue, telling the player what has happened, - or `true` to stop processing the action and produce no further output. + should return :const:`false` to continue, telling the player what has + happened, or :const:`true` to stop processing the action and produce no + further output. -`list_together` +.. index:: + pair: list_together; library property +:prop:`list_together` For an object: groups related objects when outputting an inventory or room contents list. The `{value}` can be @@ -542,16 +796,22 @@ Object's value being considered first. * a `{string}`: all objects having this value are grouped as a count of the string; * a routine which is called twice. On the first call nothing has been - output; `inventory_stage` has the value 1, and the routine should - return `false` to continue, or `true` to stop processing and produce no - further output. On the second call the list has been output; - `inventory_stage` has the value 2, and there is no test on the return - value. + output; :var:`inventory_stage` has the value 1, and the routine should + return :const:`false` to continue, or :const::const:`true` to stop + processing and produce no further output. On the second call the list + has been output; :var:`inventory_stage` has the value 2, and there is + no test on the return value. + +.. index:: + pair: n_to; library property -`n_to` - See `d_to`. +:prop:`n_to` + See :prop:`d_to`. -`name` |ADD| +.. index:: + pair: name; library property + +:prop:`name` |ADD| Defines a space-separated list of words which are added to the Inform dictionary. Each word can be supplied in apostrophes '...' or quotes "..."; in all other cases only words in apostrophes update the @@ -561,201 +821,366 @@ Object's value being considered first. For a room: outputs "does not need to be referred to". -`ne_to` - See `d_to`. +.. index:: + pair: ne_to; library property + +:prop:`ne_to` + See :prop:`d_to`. -`number` +.. index:: + pair: number; library property + +:prop:`number` For an object or room: the `{value}` is a general-purpose variable freely - available for use by the program. A `player` object must provide (but - not use) this variable. + available for use by the program. A :var:`player` object must provide + (but not use) this variable. + +.. index:: + pair: nw_to; library property + +:prop:`nw_to` + See :prop:`d_to`. + +.. index:: + pair: orders; library property -`nw_to` - See `d_to`. +:prop:`orders` |ADD| + For an :attr:`animate` or :attr:`talkable` object: the `{value}` is a + routine called to carry out the player's orders. The routine should + return :const:`false` to continue, or :const:`true` to stop processing + the action and produce no further output. + +.. index:: + pair: out_to; library property -`orders` |ADD| - For an `animate` or `talkable` object: the `{value}` is a routine called - to carry out the player's orders. The routine should return `false` to - continue, or `true` to stop processing the action and produce no further - output. +:prop:`out_to` + See :prop:`d_to`. -`out_to` - See `d_to`. +.. index:: + pair: parse_name; library property -`parse_name` +:prop:`parse_name` For an object: the `{value}` is a routine called to parse an object's name. The routine should return zero if the text makes no sense, -1 to cause the parser to resume, or the positive number of words matched. -`plural` +.. index:: + pair: plural; library property + +:prop:`plural` For an object: its plural form, when in the presence of others like it. The `{value}` can be a string, or a routine which outputs a string. -`react_after` +.. index:: + pair: react_after; library property + +:prop:`react_after` For an object: detects nearby actions - those which take place when this object is in scope. The `{value}` is a routine invoked after the action - has happened, but before the player has been informed. See `after`. + has happened, but before the player has been informed. See :prop:`after`. + +.. index:: + pair: react_before; library property -`react_before` +:prop:`react_before` For an object: detects nearby actions - those which take place when this object is in scope. The `{value}` is a routine invoked before the action - has happened. See `after`. + has happened. See :prop:`after`. -`s_to` +.. index:: + pair: s_to; library property -`se_to` - See `d_to`. +:prop:`s_to` + See :prop:`d_to`. -`short_name` +.. index:: + pair: se_to; library property + +:prop:`se_to` + See :prop:`d_to`. + +.. index:: + pair: short_name; library property + +:prop:`short_name` For an object: an alternative or extended short name. The `{value}` can be a string, or a routine which outputs a string. The routine should - return `false` to continue by outputting the object's *actual* short name - (from the head of the object definition), or `true` to stop processing - the action and produce no further output. + return :const:`false` to continue by outputting the object's *actual* + short name (from the head of the object definition), or :const:`true` to + stop processing the action and produce no further output. -`short_name_indef` +.. index:: + pair: short_name_indef; library property + +:prop:`short_name_indef` For a non-English object: the short name when preceded by an indefinite object. The `{value}` can be a string, or a routine which outputs a string. -`sw_to` - See `d_to`. +.. index:: + pair: sw_to; library property + +:prop:`sw_to` + See :prop:`d_to`. + +.. index:: + pair: time_left; library property -`time_left` +:prop:`time_left` For a timer object: the `{value}` is a variable to hold the number of turns left until this object's timer - activated and initialised by `StartTimer({obj_id})` - counts down to zero and invokes the object's `time_out` property. -`time_out` +.. index:: + pair: time_out; library property + +:prop:`time_out` For a timer object: the `{value}` is a routine which is run when the - object's `time_left` value - initialised by `StartTimer({obj_id})`, and - not in the meantime cancelled by `StopTimer({obj_id})` - counts down to - zero. + object's :prop:`time_left` value - initialised by `StartTimer({obj_id})`, + and not in the meantime cancelled by `StopTimer({obj_id})` - counts down + to zero. + +.. index:: + pair: u_to; library property + +:prop:`u_to` + See :prop:`d_to`. + +.. index:: + pair: w_to; library property + +:prop:`w_to` + See :prop:`d_to`. + +.. index:: + pair: when_closed; library property -`u_to` +:prop:`when_closed` -`w_to` - See `d_to`. +.. index:: + pair: when_open; library property -`when_closed` +:prop:`when_open` + For a :attr:`container` or :attr:`door` object: used when including this + object in a room's long description. The `{value}` can be a string, or a + routine which outputs a string. + +.. index:: + pair: when_off; library property + +:prop:`when_off` -`when_open` - For a `container` or `door` object: used when including this object in a +.. index:: + pair: when_on; library property + +:prop:`when_on` + For a :attr:`switchable` object: used when including this object in a room's long description. The `{value}` can be a string, or a routine which outputs a string. -`when_off` - -`when_on` - For a `switchable` object: used when including this object in a room's - long description. The `{value}` can be a string, or a routine which - outputs a string. +.. index:: + pair: with_key; library property -`with_key` - For a `lockable` object: the `{obj_id}` (generally some kind of key) - needed to lock and unlock the object, or `nothing` if no key fits. +:prop:`with_key` + For a :attr:`lockable` object: the `{obj_id}` (generally some kind of + key) needed to lock and unlock the object, or :const:`nothing` if no key + fits. .. _object-attrs: Object attributes ================= -`absent` - For a floating object (one with a `found_in` property, which can - appear in many rooms): is no longer there. +.. index:: + pair: absent; library attribute + +:attr:`absent` + For a floating object (one with a :prop:`found_in` property, which can + appear in many rooms): is no longer there. + +.. index:: + pair: animate; library attribute + +:attr:`animate` + For an object: is a living creature. + +.. index:: + pair: clothing; library attribute + +:attr:`clothing` + For an object: can be worn. + +.. index:: + pair: concealed; library attribute + +:attr:`concealed` + For an object: is present but hidden from view. + +.. index:: + pair: container; library attribute + +:attr:`container` + For an object: other objects can be put in (but not on) it. + +.. index:: + pair: door; library attribute + +:attr:`door` + For an object: is a door or bridge between rooms. + +.. index:: + pair: edible; library attribute + +:attr:`edible` + For an object: can be eaten. + +.. index:: + pair: enterable; library attribute + +:attr:`enterable` + For an object: can be entered. + +.. index:: + pair: female; library attribute + +:attr:`female` + For an :attr:`animate` object: is female. + +.. index:: + pair: general; library attribute + +:attr:`general` + For an object or room: a general-purpose flag. + +.. index:: + pair: light; library attribute + +:attr:`light` + For an object or room: is giving off light. + +.. index:: + pair: lockable; library attribute + +:attr:`lockable` + For an object: can be locked; see the :prop:`with_key` property. + +.. index:: + pair: locked; library attribute + +:attr:`locked` + For an object: can't be opened. + +.. index:: + pair: male; library attribute + +:attr:`male` + For an :attr:`animate` object: is male. + +.. index:: + pair: moved; library attribute + +:attr:`moved` + For an object: is being, or has been, taken by the player. + +.. index:: + pair: neuter; library attribute + +:attr:`neuter` + For an :attr:`animate` object: is neither male nor female. -`animate` - For an object: is a living creature. +.. index:: + pair: on; library attribute -`clothing` - For an object: can be worn. +:attr:`on` + For a :attr:`switchable` object: is switched on. -`concealed` - For an object: is present but hidden from view. +.. index:: + pair: open; library attribute -`container` - For an object: other objects can be put in (but not on) it. +:attr:`open` + For a :attr:`container` or door object: is open. -`door` - For an object: is a door or bridge between rooms. +.. index:: + pair: openable; library attribute -`edible` - For an object: can be eaten. +:attr:`openable` + For a :attr:`container` or :attr:`door` object: can be opened. -`enterable` - For an object: can be entered. +.. index:: + pair: pluralname; library attribute -`female` - For an `animate` object: is female. +:attr:`pluralname` + For an object: is plural. -`general` - For an object or room: a general-purpose flag. +.. index:: + pair: proper; library attribute -`light` - For an object or room: is giving off light. +:attr:`proper` + For an object: the short name is a proper noun, therefore not to be + preceded by "The" or "the". -`lockable` - For an object: can be locked; see the `with_key` property. +.. index:: + pair: scenery; library attribute -`locked` - For an object: can't be opened. +:attr:`scenery` + For an object: can't be taken; is not listed in a room description. -`male` - For an `animate` object: is male. +.. index:: + pair: scored; library attribute -`moved` - For an object: is being, or has been, taken by the player. +:attr:`scored` + For an object: awards `OBJECT_SCORE` points when taken for the first + time. For a room: awards `ROOM_SCORE` points when visited for the + first time. -`neuter` - For an `animate` object: is neither male nor female. +.. index:: + pair: static; library attribute -`on` - For a `switchable` object: is switched on. +:attr:`static` + For an object: can't be taken. -`open` - For a `container` or door object: is open. +.. index:: + pair: supporter; library attribute -`openable` - For a `container` or `door` object: can be opened. +:attr:`supporter` + For an object: other objects can be put on (but not in) it. -`pluralname` - For an object: is plural. +.. index:: + pair: switchable; library attribute -`proper` - For an object: the short name is a proper noun, therefore not to be - preceded by "The" or "the". +:attr:`switchable` + For an object: can be switched off or on. -`scenery` - For an object: can't be taken; is not listed in a room description. +.. index:: + pair: talkable; library attribute -`scored` - For an object: awards `OBJECT_SCORE` points when taken for the first - time. For a room: awards `ROOM_SCORE` points when visited for the - first time. +:attr:`talkable` + For an object: can be addressed in "object, do this" style. -`static` - For an object: can't be taken. +.. index:: + pair: transparent; library attribute -`supporter` - For an object: other objects can be put on (but not in) it. +:attr:`transparent` + For a :attr:`container` object: objects inside it are visible. -`switchable` - For an object: can be switched off or on. +.. index:: + pair: visited; library attribute -`talkable` - For an object: can be addressed in "object, do this" style. +:attr:`visited` + For a room: is being, or has been, visited by the player. -`transparent` - For a `container` object: objects inside it are visible. +.. index:: + pair: workflag; library attribute -`visited` - For a room: is being, or has been, visited by the player. +:attr:`workflag` + Temporary internal flag, also available to the program. -`workflag` - Temporary internal flag, also available to the program. +.. index:: + pair: worn; library attribute -`worn` - For a `clothing` object: is being worn. +:attr:`worn` + For a :attr:`clothing` object: is being worn. .. _entry-points: @@ -775,7 +1200,7 @@ These routines, if you supply them, are called when shown. `BeforeParsing()` The parser has input some text, set up the buffer and parse tables, and - initialised `wn` to 1. + initialised :var:`wn` to 1. `ChooseObjects({object,flag})` Parser has found "`ALL`" or an ambiguous noun phrase and decided that diff --git a/appendices/g.rst b/appendices/g.rst index a9c1641..dbb7df6 100644 --- a/appendices/g.rst +++ b/appendices/g.rst @@ -20,10 +20,10 @@ words and phrases. The generated effect of the player's input, usually by the `parser` but also occasionally by the designer's code. It refers to a single task to be processed by Inform, such as DROP KETTLE, and it's stored - in four numbers: one each for the action itself and the ``actor`` + in four numbers: one each for the action itself and the :var:`actor` object who is to perform it (the player or an `NPC`), one for the - ``noun`` -- or direct object, if present -- and a fourth for the - ``second`` noun -- if it exists, for example the "POT" in THROW + :var:`noun` -- or direct object, if present -- and a fourth for the + :var:`second` noun -- if it exists, for example the "POT" in THROW KETTLE AT POT. See also `fake action`. alpha-testing @@ -52,7 +52,7 @@ words and phrases. The designer may test from any other part of the program *if* an object *has* a certain attribute, *give* an attribute to an object or take it away as need arises. For instance, the attribute - ``container`` states that the object is capable of having other + :attr:`container` states that the object is capable of having other objects placed inside it. avatar @@ -126,7 +126,7 @@ words and phrases. dictionary word A word written in single quotes '...' within the `source file`, usually (but not exclusively) as one of the values assigned to an - object's ``name`` property. All such words are stored in the + object's :prop:`name` property. All such words are stored in the `dictionary`, which is consulted by the `parser` when attempting to make sense of a player's command. Only the first nine characters are significant (thus ``'cardiogram'`` and ``'cardiograph'`` are @@ -151,7 +151,7 @@ words and phrases. embedded routine A routine that is defined in the body of an object, as the value of one of its `properties`. Unlike a `standalone routine`, an embedded - routine doesn't have a name of its own, and returns ``false`` if + routine doesn't have a name of its own, and returns `false` if execution reaches the terminating marker ``]``. entry point @@ -338,7 +338,7 @@ words and phrases. standalone routine A routine which is not part of an object. Unlike an `embedded - routine`, it must provide a name of its own, and it returns ``true`` + routine`, it must provide a name of its own, and it returns `true` when execution reaches the terminating marker ``]``. statement diff --git a/chapters/02.rst b/chapters/02.rst index 950db12..af3f045 100644 --- a/chapters/02.rst +++ b/chapters/02.rst @@ -348,6 +348,9 @@ the file -- and it compiles there and then. You can also run the interpreter with similar ease. The convenience of doing this far outweighs the small amount of time needed to obtain and configure TextPad. +.. index:: + single: Apple Macintosh + .. _inform-apple: Inform on an Apple Macintosh (running OS X) diff --git a/chapters/03.rst b/chapters/03.rst index dfd8dd4..4fe5e33 100644 --- a/chapters/03.rst +++ b/chapters/03.rst @@ -35,7 +35,8 @@ Creating a basic source file The first task is to create an Inform source file template. Every game that we design will start out like this. Follow these steps: -#. Create an ``Inform\Games\Heidi`` folder (maybe by copying ``Inform\Games\MyGame1``). +#. Create an ``Inform\Games\Heidi`` folder (maybe by copying + ``Inform\Games\MyGame1``). .. note:: @@ -331,27 +332,27 @@ Again, we can infer some general principles from these four examples: * A keyword ``with`` follows, which simply tells the compiler what to expect next. -* The word ``description``, introducing another piece of text which gives - more detail about the object: in the case of a room, it's the appearance - of the surrounding environment when the player character is in that room. - The textual description is given in double quotes, and is followed by a - comma. +* The word :prop:`description`, introducing another piece of text which + gives more detail about the object: in the case of a room, it's the + appearance of the surrounding environment when the player character is in + that room. The textual description is given in double quotes, and is + followed by a comma. * Near the end, the keyword ``has`` appears, which again tells the compiler to expect a certain kind of information. -* The word ``light`` says that this object is a source of illumination, and - that therefore the player character can see what's happening here. There - has to be at least one light source in every room (unless you want the - player to be told that "It's pitch dark and you can't see a thing"); most - commonly, that light source is the room itself. +* The word :attr:`light` says that this object is a source of illumination, + and that therefore the player character can see what's happening here. + There has to be at least one light source in every room (unless you want + the player to be told that "It's pitch dark and you can't see a thing"); + most commonly, that light source is the room itself. A smidgeon of background may help set this into context (there's more in the next chapter). An object can have both :term:`properties` (introduced by the keyword ``with``) and :term:`attributes` (written after the word -``has``). A property has both a name (like ``description``) and a value -(like the character string "``You stand outside a cottage. The forest -stretches east.``"); an attribute has merely a name. +``has``). A property has both a name (like :prop:`description`) and a +value (like the character string "``You stand outside a cottage. The +forest stretches east.``"); an attribute has merely a name. In a little while, when you play this game, you'll observe that it starts like this: @@ -444,20 +445,20 @@ We've made two changes to the room objects. cottage), and the second defines a connection ``forest`` → ``clearing`` which heads off to the northeast. - Inform provides for eight "horizontal" connections (``n_to``, ``ne_to``, - ``e_to``, ``se_to``, ``s_to``, ``sw_to``, ``w_to``, ``nw_to``) two - "vertical" ones (``u_to``, ``d_to``) and two specials ``in_to``, and - ``out_to``. You'll see some of these used for the remaining inter-room - connections. + Inform provides for eight "horizontal" connections (:prop:`n_to`, + :prop:`ne_to`, :prop:`e_to`, :prop:`se_to`, :prop:`s_to`, :prop:`sw_to`, + :prop:`w_to`, :prop:`nw_to`) two "vertical" ones (:prop:`u_to`, + :prop:`d_to`) and two specials :prop:`in_to`, and :prop:`out_to`. You'll + see some of these used for the remaining inter-room connections. There's one last detail to attend to before we can test what we've done. You'll recollect that our story begins with Heidi standing in front of her -cottage. We need to tell the interpreter that ``before_cottage`` is the room -where the game starts, and we do this in the ``Initialise`` routine:: +cottage. We need to tell the interpreter that ``before_cottage`` is the +room where the game starts, and we do this in the ``Initialise`` routine:: [ Initialise; location = before_cottage; ]; -``location`` is a :term:`variable`, part of the library, which tells the +:var:`location` is a :term:`variable`, part of the library, which tells the interpreter in which room the player character currently is. Here, we're saying that, at the start of the game, the player character is in the ``before_cottage`` room. @@ -556,9 +557,9 @@ rooms we defined previously: a one-word internal identifier (``bird``, (``baby bird``, ``bird's nest``). They both have some descriptive detail: for a room this is printed when the player first enters, or when she types LOOK; for other objects it's printed when she EXAMINEs that object. What -they *don't* have are connections (``e_to``, ``w_to``, etc. apply only to -rooms) or ``light`` (it's not necessary -- the rooms ensure that light is -available). +they *don't* have are connections (:prop:`e_to`, :prop:`w_to`, etc. apply +only to rooms) or :attr:`light` (it's not necessary -- the rooms ensure +that light is available). When the game is running, the player will want to refer to these two objects, saying for instance EXAMINE THE BABY BIRD or PICK UP THE NEST. @@ -580,7 +581,7 @@ line to each definition: name 'bird^s' 'nest' 'twigs' 'moss', has ; -The ``name`` introduces a list in single quotes '...'. We call each of +The :prop:`name` introduces a list in single quotes '...'. We call each of those quoted things a :term:`dictionary word`, and we do mean "word", not "phrase" (``'baby'``\ ``'bird'`` rather than ``'baby bird'``); you can't uses spaces, commas or periods *in* dictionary words, though there's a @@ -593,6 +594,9 @@ that she means; if she mentions NEST, BIRD'S NEST or MOSS, it's the will politely say that it doesn't understand what on earth she's talking about. +.. index:: + single: apostrophes + .. note:: You'll notice the use of ``'bird^s'`` to define the dictionary word @@ -607,18 +611,18 @@ about. apostrophe, and the compiler then treats ``bird's`` as a dictionary word. -You may be wondering why we need a list of ``name`` words for the bird and -its nest, yet we didn't when we defined the rooms? It's because the player -can't interact with a room in the same way as with other objects; for -example, she doesn't need to say EXAMINE THE FOREST -- just being there and -typing LOOK is sufficient. +You may be wondering why we need a list of :prop:`name` words for the bird +and its nest, yet we didn't when we defined the rooms? It's because the +player can't interact with a room in the same way as with other objects; +for example, she doesn't need to say EXAMINE THE FOREST -- just being there +and typing LOOK is sufficient. The bird's definition is complete, but there's an additional complexity with the nest: we need to be able to put the bird into it. We do this by -labelling the nest as a ``container`` -- able to hold other objects -- so -that the player can type PUT (or INSERT) BIRD IN (or INTO) NEST. -Furthermore, we label it as ``open``; this prevents the interpreter from -asking us to open it before putting in the bird. +labelling the nest as a :attr:`container` -- able to hold other objects -- +so that the player can type PUT (or INSERT) BIRD IN (or INTO) NEST. +Furthermore, we label it as :attr:`open`; this prevents the interpreter +from asking us to open it before putting in the bird. .. code-block:: inform @@ -725,11 +729,11 @@ player character supposedly "climbs". We'd better define it: name 'tall' 'sycamore' 'tree' 'stout' 'proud', has scenery; -Everything there should be familiar, apart from that ``scenery`` at the +Everything there should be familiar, apart from that :attr:`scenery` at the end. We've already mentioned the tree in the description of the forest clearing, so we don't want the interpreter adding "You can see a tall sycamore tree here" afterwards, as it does for the bird and the nest. By -labelling the tree as ``scenery`` we suppress that, and also prevent it +labelling the tree as :attr:`scenery` we suppress that, and also prevent it from being picked up by the player character. One final object: the branch at the top of the tree. Again, not many surprises in this definition: @@ -740,14 +744,14 @@ at the top of the tree. Again, not many surprises in this definition: name 'wide' 'firm' 'flat' 'bough' 'branch', has static supporter; -The only new things are those two labels. ``static`` is similar to -``scenery``: it prevents the branch from being picked up by the player -character, but *doesn't* suppress mention of it when describing the -setting. And ``supporter`` is rather like the ``container`` that we -used for the nest, except that this time the player character can put -other objects *onto* the branch. (In passing, we'll mention that an -object can't normally be both a ``container`` *and* a ``supporter``.) -And so here are our objects again: +The only new things are those two labels. :attr:`static` is similar to +:attr:`scenery`: it prevents the branch from being picked up by the player +character, but *doesn't* suppress mention of it when describing the +setting. And :attr:`supporter` is rather like the :attr:`container` that +we used for the nest, except that this time the player character can put +other objects *onto* the branch. (In passing, we'll mention that an object +can't normally be both a :attr:`container` *and* a :attr:`supporter`.) And +so here are our objects again: .. code-block:: inform @@ -830,8 +834,8 @@ adding a line near the top of the file: The value of ``MAX_CARRIED`` limits the number of objects that the player character can be holding at any one time; by setting it to 1, we're saying that she can carry the bird or the nest, but not both. However, the limit -ignores the contents of ``container`` or ``supporter`` objects, so the nest -with the bird inside it is still counted as one object. +ignores the contents of :attr:`container` or :attr:`supporter` objects, so +the nest with the bird inside it is still counted as one object. The other change is slightly more complex and more important: there's currently no way to "win" the game! The goal is for the player character @@ -854,16 +858,16 @@ is one way of making it happen: several new concepts all at once. Later in the guide, we'll explain those concepts more clearly, so you can just skip this bit if you want. - The variable ``deadflag``, part of the library, is normally 0. If you set - its value to 2, the interpreter notices and ends the game with "You have - won". The statement:: + The variable :var:`deadflag`, part of the library, is normally 0. If + you set its value to 2, the interpreter notices and ends the game with + "You have won". The statement:: if (nest in branch) deadflag = 2; should be read as: "Test whether the ``nest`` is currently in the - ``branch`` (if the branch is a ``container``) or on it (if the - ``branch`` is a supporter); if it is, set the value of ``deadflag`` to - 2; if it isn't, do nothing." The surrounding part:: + ``branch`` (if the branch is a :attr:`container`) or on it (if the + ``branch`` is a supporter); if it is, set the value of :var:`deadflag` + to 2; if it isn't, do nothing." The surrounding part:: each_turn [; ... ], @@ -879,14 +883,14 @@ is one way of making it happen: ``clearing``, so nothing happens. * Also at the end of each turn, the interpreter checks the value of - ``deadflag``. Usually it's 0, so nothing happens. + :var:`deadflag`. Usually it's 0, so nothing happens. * Finally the player character puts the ``nest`` on the ``branch``. "Aha!" says the interpreter (to itself, of course), and sets the - value of ``deadflag`` to 2. + value of :var:`deadflag` to 2. * Immediately afterwards, (another part of) the interpreter checks and - finds that the value of ``deadflag`` has changed to 2, which means + finds that the value of :var:`deadflag` has changed to 2, which means that the game is successfully completed; so, it says to the player, "you've won!" diff --git a/chapters/04.rst b/chapters/04.rst index e6af20c..51454ab 100644 --- a/chapters/04.rst +++ b/chapters/04.rst @@ -68,12 +68,12 @@ but you can change it at any time. For example, we used the statement:: location = before_cottage; -to reset the value of the ``location`` variable to the +to reset the value of the :var:`location` variable to the ``before_cottage`` object, and we wrote:: if (nest in branch) deadflag = 2; -to reset the value of the ``deadflag`` variable to 2. +to reset the value of the :var:`deadflag` variable to 2. Later, we'll talk about the :term:`local variable` (see :ref:`routines`) and about using object properties as variables (see :ref:`objects`). @@ -144,8 +144,8 @@ An object header comprises up to three items, all optional: ... The ``tree`` starts like this; the only real difference is that, because - the player character can't move a ``scenery`` object, it's always going - to be in the ``clearing``:: + the player character can't move a :attr:`scenery` object, it's always + going to be in the ``clearing``:: Object tree "tall sycamore tree" clearing ... @@ -184,20 +184,21 @@ Here are examples of the properties that we've come across so far:: By happy coincidence, those examples also demonstrate most of the different types of value which can be assigned to a property. The value associated -with the ``description`` property in this particular example is a string of -characters in double quotes; the value associated with this ``e_to`` -property is the internal identity of an object; the ``name`` property is a -bit unusual -- its value is a list of dictionary words, each in single -quotes; the ``each_turn`` property has a value which is an :term:`embedded -routine` (see :ref:`embedded-routines`). The only other type of value -which is commonly found is a simple number; for example:: +with the :prop:`description` property in this particular example is a +string of characters in double quotes; the value associated with this +:prop:`e_to` property is the internal identity of an object; the +:prop:`name` property is a bit unusual -- its value is a list of dictionary +words, each in single quotes; the :prop:`each_turn` property has a value +which is an :term:`embedded routine` (see :ref:`embedded-routines`). The +only other type of value which is commonly found is a simple number; for +example:: capacity 10, In all, the library defines around forty-eight standard properties -- like -``name`` and ``each_turn`` -- which you can associate with your objects; -there's a complete list in :ref:`object-props`. And in :doc:`08` we show -you how to invent your own property variables. +:prop:`name` and :prop:`each_turn` -- which you can associate with your +objects; there's a complete list in :ref:`object-props`. And in :doc:`08` +we show you how to invent your own property variables. Object attributes ----------------- @@ -413,7 +414,7 @@ which could equally have been defined thus:: Constant Headline "^A simple Inform example^by Roger Firth and Sonja Kesserich.^"; -and as the value of an object ``description`` property:: +and as the value of an object :prop:`description` property:: description "Too young to fly, the nestling tweets helplessly.", @@ -435,7 +436,7 @@ finds all the words, and they seem to represent a sensible course of action, that's what happens next. So far, we've seen dictionary words used as the values of an object -``name`` property:: +:prop:`name` property:: name 'bird^s' 'nest' 'twigs' 'moss', @@ -465,7 +466,7 @@ encountered only a few. We saw:: which is an example of an :term:`assignment` statement, so-called because the equals sign ``=`` assigns a new value (the internal ID of our -``before_cottage`` room) to a variable (the global variable ``location`` +``before_cottage`` room) to a variable (the global variable :var:`location` which is part of the library). Later we saw:: if (nest in branch) deadflag = 2; @@ -486,7 +487,7 @@ interpreter executes that statement: it performs an assignment:: deadflag = 2; -which changes the value of the library variable ``deadflag`` from its +which changes the value of the library variable :var:`deadflag` from its current value to 2. Incidentally, ``if`` statements are often written on two lines, with the "controlled" statement indented. This makes it easier to read, but doesn't change the way that it works:: diff --git a/chapters/05.rst b/chapters/05.rst index 873d6a0..aabd40d 100644 --- a/chapters/05.rst +++ b/chapters/05.rst @@ -74,7 +74,7 @@ how we do it: We'll go through this a step at a time: -#. We've added a new ``before`` property to our bird object. The +#. We've added a new :prop:`before` property to our bird object. The interpreter looks at the property *before* attempting to perform any action which is directed specifically at this object:: @@ -118,8 +118,8 @@ We'll go through this a step at a time: > The use of the ``return true`` statement probably needs a bit more -explanation. An object's ``before`` property traps an action aimed at that -object right at the start, before the interpreter has started to do +explanation. An object's :prop:`before` property traps an action aimed at +that object right at the start, before the interpreter has started to do anything. That's the point at which the statements in the embedded routine are executed. If the last of those statements is ``return true`` then the interpreter assumes that the action has been dealt with by those @@ -160,8 +160,8 @@ again and again. Entering the cottage ==================== -At the start of the game the player character stands "outside a cottage", which -might lead her to believe that she can go inside: +At the start of the game the player character stands "outside a cottage", +which might lead her to believe that she can go inside: .. code-block:: transcript @@ -186,14 +186,14 @@ change: cant_go "The only path lies to the east.", has light; -The ``in_to`` property would normally link to another room, in the same way -as the ``e_to`` property contain the internal ID of the ``forest`` object. -However, if instead you set its value to be a string, the interpreter -displays that string when the player tries the IN direction. Other -- -unspecified -- directions like NORTH and UP still elicit the standard "You -can't go that way" response, but we can change that too, by supplying a -``cant_go`` property whose value is a suitable string. We then get this -friendlier behaviour: +The :prop:`in_to` property would normally link to another room, in the same +way as the :prop:`e_to` property contain the internal ID of the ``forest`` +object. However, if instead you set its value to be a string, the +interpreter displays that string when the player tries the IN direction. +Other -- unspecified -- directions like NORTH and UP still elicit the +standard "You can't go that way" response, but we can change that too, by +supplying a :prop:`cant_go` property whose value is a suitable string. We +then get this friendlier behaviour: .. code-block:: transcript @@ -215,7 +215,7 @@ There's another issue here; since we haven't actually implemented an object to represent the cottage, a perfectly reasonable EXAMINE COTTAGE command receives the obviously nonsensical reply "You can't see any such thing". That's easy to fix; we can add a new ``cottage`` object, making it a piece -of ``scenery`` just like the ``tree``: +of :attr:`scenery` just like the ``tree``: .. code-block:: inform @@ -251,7 +251,7 @@ solution we adopt is similar as well: ], has scenery; -We use a ``before`` property to intercept the ``Enter`` action applied to +We use a :prop:`before` property to intercept the ``Enter`` action applied to the cottage object, so that we can display a more appropriate message. This time, however, we've done it using one statement rather than two. It turns out that the sequence "``print`` a string which ends with a newline @@ -275,7 +275,7 @@ Climbing the tree In the clearing, holding the nest and looking at the tree, the player is meant to type UP. Just as likely, though, she'll try CLIMB TREE (which currently gives the completely misleading response "I don't think much is -to be achieved by that"). Yet another opportunity to use a ``before`` +to be achieved by that"). Yet another opportunity to use a :prop:`before` property, but now with a difference. .. code-block:: inform @@ -300,6 +300,9 @@ fortunately all of that complexity is hidden: there's a standard :term:`library routine` to do the job, not one that we've written, but one that's provided as part of the Inform system. +.. index:: + single: arguments (of a routine) + You'll remember that, when we first mentioned routines (see :ref:`standalone-routines`), we used the example of ``Initialise()`` and said that "the routine's name followed by opening and closing parentheses @@ -357,9 +360,9 @@ far, but instead for every ``Drop`` which takes place in our troublesome Let's again take it a step at a time: -#. We've added a new ``after`` property to our ``top_of_tree`` object. The - interpreter looks at the property *subsequent to* performing any action in - this room:: +#. We've added a new :prop:`after` property to our ``top_of_tree`` object. + The interpreter looks at the property *subsequent to* performing any + action in this room:: after [; ... ], @@ -379,14 +382,14 @@ Let's again take it a step at a time: move noun to clearing; - which takes the object which has just been moved from the ``player`` + which takes the object which has just been moved from the :var:`player` object to the ``top_of_tree`` object (by the successful ``Drop`` action) and moves it again so that its parent becomes the ``clearing`` object. - That ``noun`` is a library variable that always contains the internal ID - of the object which is the target of the current action. If the player - types DROP NEST, ``noun`` contains the internal ID of the ``nest`` - object; if she types DROP NESTLING then ``noun`` contains the internal - ID of the ``bird`` object. Second, we execute:: + That :var:`noun` is a library variable that always contains the internal + ID of the object which is the target of the current action. If the + player types DROP NEST, :var:`noun` contains the internal ID of the + ``nest`` object; if she types DROP NESTLING then :var:`noun` contains + the internal ID of the ``bird`` object. Second, we execute:: return false; @@ -437,7 +440,7 @@ what's just happened, you could use this alternative solution: has light; The ``print_ret`` statement does two things for us: displays a more -informative message, and returns ``true`` to tell the interpreter that +informative message, and returns :const:`true` to tell the interpreter that there's no need to let the player know what's happened -- we've handled that ourselves. @@ -465,8 +468,8 @@ The extended ``if`` statement:: should now be read as: "Test whether the ``bird`` is currently in (or on) the ``nest``, *and* whether the ``nest`` is currently on (or in) the -``branch``; if both parts are ``true``, set the value of ``deadflag`` to 2; -otherwise, do nothing". +``branch``; if both parts are :const:`true`, set the value of +:var:`deadflag` to 2; otherwise, do nothing". Summing up ========== @@ -484,30 +487,30 @@ The new topics that we've encountered here include these: Object properties ----------------- -Objects can have a ``before`` property -- if there is one, the interpreter -looks at it *before* performing an action which in some way involves that -object. Similarly, you can provide an ``after`` property, which the -interpreter looks at *after* performing an action but before telling the -player what's happened. Both ``before`` and ``after`` properties can be -used not only with tangible objects like the ``bird``, ``cottage`` and -``tree`` (when they intercept actions aimed at that particular object) but -also with rooms (when they intercept actions aimed at any object in that -room). - -The value of each ``before`` and ``after`` property is an embedded routine. -If such a routine ends with ``return false``, the interpreter then carries -on with the next stage of the action which has been intercepted; if it ends -with ``return true``, the interpreter does nothing further for that action. -By combining these possibilities, you can supplement the work done by a -standard action with statements of your own, or you can replace a standard -action completely. +Objects can have a :prop:`before` property -- if there is one, the +interpreter looks at it *before* performing an action which in some way +involves that object. Similarly, you can provide an :prop:`after` +property, which the interpreter looks at *after* performing an action but +before telling the player what's happened. Both :prop:`before` and +:prop:`after` properties can be used not only with tangible objects like +the ``bird``, ``cottage`` and ``tree`` (when they intercept actions aimed +at that particular object) but also with rooms (when they intercept actions +aimed at any object in that room). + +The value of each :prop:`before` and :prop:`after` property is an embedded +routine. If such a routine ends with ``return false``, the interpreter +then carries on with the next stage of the action which has been +intercepted; if it ends with ``return true``, the interpreter does nothing +further for that action. By combining these possibilities, you can +supplement the work done by a standard action with statements of your own, +or you can replace a standard action completely. Previously, we've seen connection properties used with the internal ID of the room to which they lead. In this chapter, we showed that the value could also be a string (explaining why movement in that direction isn't -possible). Here are examples of both, and also of the ``cant_go`` property -which provides just such an explanation for *all* connections that aren't -explicitly listed:: +possible). Here are examples of both, and also of the :prop:`cant_go` +property which provides just such an explanation for *all* connections that +aren't explicitly listed:: e_to forest, in_to "It's such a lovely day -- much too nice to go inside.", @@ -524,6 +527,9 @@ certain common tasks if you require them; there's a list in player character from her current room to another one -- not necessarily adjacent to the first room. +.. index:: + single: arguments (of a routine) + When calling ``PlayerTo``, we had to tell the library which room is the destination. We did this by supplying that room's internal ID within parentheses, thus:: @@ -591,10 +597,13 @@ lead to ``Drop``. This makes life much easier for the designer; although Inform defines quite a lot of actions, there are many fewer than there are ways of expressing those same actions using English verbs. +.. index:: + pair: action; library variable + Each action is represented internally by a number, and the value of the -current action is stored in a library variable called, erm, ``action``. -Two more variables are also useful here: ``noun`` holds the internal ID of -the object which is the focus of the action, and ``second`` holds the +current action is stored in a library variable called, erm, :var:`action`. +Two more variables are also useful here: :var:`noun` holds the internal ID +of the object which is the focus of the action, and :var:`second` holds the internal ID of the secondary object (if there is one). Here are some examples of these: @@ -609,10 +618,10 @@ DROP THE NEST Drop nest nothing PUT NEST ON BRANCH PutOn nest branch =============================== ====== ======= ======= -The value ``nothing`` is a built-in constant (like ``true`` and ``false``) -which means, well, there isn't any object to refer to. There's a list of -standard library actions in :ref:`group-1-actions`, :ref:`group-2-actions` -and :ref:`group-3-actions`. +The value ``nothing`` is a built-in constant (like :const:`true` and +:const:`false`) which means, well, there isn't any object to refer to. +There's a list of standard library actions in :ref:`group-1-actions`, +:ref:`group-2-actions` and :ref:`group-3-actions`. We've now reached the end of our first game. In these three chapters we've shown you the basic principles on which almost all games are based, and diff --git a/chapters/06.rst b/chapters/06.rst index 495b8d4..603663d 100644 --- a/chapters/06.rst +++ b/chapters/06.rst @@ -121,8 +121,8 @@ pieces: Constant MAX_SCORE = 3; * The ``Initialise`` routine that we wrote last time contained only one - statement, to set the player's initial ``location``. We do that here as - well, but we also do some other stuff. + statement, to set the player's initial :var:`location`. We do that here + as well, but we also do some other stuff. * The first thing is to assign 2 to the library variable ``lookmode``. Inform's default mode for displaying room descriptions is BRIEF (a @@ -155,16 +155,16 @@ pieces: Why not do that with the player? Because the object which represents the player is defined by the library (rather than as part of our - game), and actually has an internal ID of ``selfobj``; ``player`` is a - variable whose value is that identifier. Rather than worry all about - this, it's easier to use the ``move`` statements. + game), and actually has an internal ID of ``selfobj``; :var:`player` + is a variable whose value is that identifier. Rather than worry all + about this, it's easier to use the ``move`` statements. There's one other task associated with the quiver; it's an article of clothing which Wilhelm is "wearing", a state denoted by the attribute - ``worn``. Normally the interpreter would apply this automatically, while - handling a command like WEAR QUIVER, but since we've moved the quiver - ourselves, we also need to set the quiver's ``worn`` attribute. The - ``give`` statement does the job:: + :attr:`worn`. Normally the interpreter would apply this automatically, + while handling a command like WEAR QUIVER, but since we've moved the + quiver ourselves, we also need to set the quiver's :attr:`worn` + attribute. The ``give`` statement does the job:: give quiver worn; @@ -173,18 +173,18 @@ pieces: uses ``~`` to mean "not".) * If the player types EXAMINE ME, the interpreter displays the - ``description`` property of the ``player`` object. The default value is - "As good-looking as ever", a bit of a cliché in the world of Inform - games. It's easy to change, though, once you realise that, since the - properties of an object are variables, you can assign new values to them - just as you'd assign new values to ``location`` and ``lookmode``. The - only problem is getting the syntax right; you can't say just:: + :prop:`description` property of the :var:`player` object. The default + value is "As good-looking as ever", a bit of a cliché in the world of + Inform games. It's easy to change, though, once you realise that, since + the properties of an object are variables, you can assign new values to + them just as you'd assign new values to :var:`location` and ``lookmode``. + The only problem is getting the syntax right; you can't say just:: description = "You wear the traditional clothing of a Swiss mountaineer."; because there are dozens of objects in the game, each with its own - ``description`` property; you need to be a little more explicit. Here's - what to type:: + :prop:`description` property; you need to be a little more explicit. + Here's what to type:: player.description = "You wear the traditional clothing of a Swiss mountaineer."; @@ -221,7 +221,7 @@ like this:: ... -and we explained that just about *every* room needs that ``light`` +and we explained that just about *every* room needs that :attr:`light` attribute, or else the player would be literally in the dark. It's a bit of a nuisance having to specify that same attribute each time; what would be neater would be to say that *all* rooms are illuminated. So we can @@ -252,7 +252,7 @@ We've done four things: language all along. #. We've furthermore said that every object which we define using ``Room`` - is automatically going to have the ``light`` attribute. + is automatically going to have the :attr:`light` attribute. #. We've changed the way in which we define the four room objects, by starting them with our specialised word ``Room``. The remainder of the @@ -260,17 +260,17 @@ We've done four things: properties, the block of attributes and the final semicolon -- remains the same; except that: -#. We don't need to explicitly include the ``light`` attribute each time; - every ``Room`` object has it automatically. +#. We don't need to explicitly include the :attr:`light` attribute each + time; every ``Room`` object has it automatically. A :term:`class` is a family of closely related objects, all of which behave in the same way. Any properties defined for the class, and any attributes defined for the class, are automatically given to objects which you specify as belonging to that class; this process of acquisition just by being a member of a class is called :term:`inheritance`. In our example, we've -defined a ``Room`` class with a ``light`` attribute, and then we've +defined a ``Room`` class with a :attr:`light` attribute, and then we've specified four objects each of which is a member of that class, and each of -which gets given a ``light`` attribute as a result of that membership. +which gets given a :attr:`light` attribute as a result of that membership. Why have we gone to this trouble? Three main reasons: @@ -296,7 +296,7 @@ be defining object classes whenever it makes sense (which is generally when two or more objects are meant to behave in exactly the same way). You may be wondering: suppose I want to define a room which for some reason -*doesn't* have ``light``; can I still use the ``Room`` class? Sure you +*doesn't* have :attr:`light`; can I still use the ``Room`` class? Sure you can:: Room cellar "Gloomy cellar" @@ -311,7 +311,7 @@ what's in it. In fact, for any object both the block of properties and the block of attributes are optional and can be omitted if there's nothing to be -specified. Now that the ``light`` attribute is being provided +specified. Now that the :attr:`light` attribute is being provided automatically and there aren't any other attributes to set, the word ``has`` can be left out. Here's the class again:: @@ -355,10 +355,10 @@ that the player might think to EXAMINE them:: ], has scenery; -All objects of this class inherit the ``scenery`` attribute, so they're -excluded from room descriptions. Also, there's a ``before`` property; one -that's more complex than our previous efforts. You'll remember that the -first ``before`` we met looked like this:: +All objects of this class inherit the :attr:`scenery` attribute, so they're +excluded from room descriptions. Also, there's a :prop:`before` property; +one that's more complex than our previous efforts. You'll remember that +the first :prop:`before` we met looked like this:: before [; Listen: @@ -366,16 +366,16 @@ first ``before`` we met looked like this:: return true; ], -The role of that original ``before`` was to intercept ``Listen`` actions, -while leaving all others well alone. The role of the ``before`` in the -``Prop`` class is broader: to intercept (a) ``Examine`` actions, and (b) -all the rest. If the action is ``Examine``, then the ``return false`` -statement means that the action carries on. If the action is ``default`` --- none of those explicitly listed, which in this instance means *every* -action apart from ``Examine`` -- then the ``print_ret`` statement is -executed, after which the interpreter does nothing further. So, a ``Prop`` -object can be EXAMINEd, but any other action addressed to it results in a -"no need to worry" message. +The role of that original :prop:`before` was to intercept ``Listen`` +actions, while leaving all others well alone. The role of the +:prop:`before` in the ``Prop`` class is broader: to intercept (a) +``Examine`` actions, and (b) all the rest. If the action is ``Examine``, +then the ``return false`` statement means that the action carries on. If +the action is ``default`` -- none of those explicitly listed, which in this +instance means *every* action apart from ``Examine`` -- then the +``print_ret`` statement is executed, after which the interpreter does +nothing further. So, a ``Prop`` object can be EXAMINEd, but any other +action addressed to it results in a "no need to worry" message. That message is also more involved than anything we've so far displayed. The statement which produces it is:: @@ -410,10 +410,10 @@ The interesting things that this statement demonstrates are: display the following object's internal ID, is called a :term:`print rule`. -* There's a library variable ``self`` which always contains the internal ID - of the current object, and is really convenient when using a ``Class``. - By using this variable in our ``print_ret`` statement, we ensure that the - message contains the name of the appropriate object. +* There's a library variable :var:`self` which always contains the internal + ID of the current object, and is really convenient when using a + ``Class``. By using this variable in our ``print_ret`` statement, we + ensure that the message contains the name of the appropriate object. Let's see an example of this in action; here's a ``Prop`` object from "William Tell":: @@ -424,9 +424,9 @@ Let's see an example of this in action; here's a ``Prop`` object from ... If players type EXAMINE GATE, they'll see "The large wooden gate..."; if -they type CLOSE GATE then the gate's ``before`` property will step in and -display "You don't need to worry about the south gate", neatly picking up -the name of the object from the ``self`` variable. +they type CLOSE GATE then the gate's :prop:`before` property will step in +and display "You don't need to worry about the south gate", neatly picking +up the name of the object from the :var:`self` variable. The reason for doing all this, rather than just creating a simple scenery object like Heidi's ``tree`` and ``cottage``, is to support EXAMINE for @@ -438,11 +438,11 @@ A class for furniture The last class for now -- we'll talk about the ``Arrow`` and ``NPC`` classes in the next chapter -- is for furniture-like objects. If you label -an object with the ``static`` attribute, an attempt to TAKE it results in -"That's fixed in place" -- acceptable in the case of Heidi's branch object -(which is indeed supposed to be part of the tree), less so for items which -are simply large and heavy. This ``Furniture`` class might sometimes be -more appropriate:: +an object with the :attr:`static` attribute, an attempt to TAKE it results +in "That's fixed in place" -- acceptable in the case of Heidi's branch +object (which is indeed supposed to be part of the tree), less so for items +which are simply large and heavy. This ``Furniture`` class might sometimes +be more appropriate:: Class Furniture with before [; @@ -452,7 +452,7 @@ more appropriate:: has static supporter; Its structure is similar to that of our ``Prop`` class: some appropriate -attributes, and a ``before`` property to trap actions directed at it. +attributes, and a :prop:`before` property to trap actions directed at it. Again, we display a message which is "personalised" for the object concerned by using a ``(The) self`` print rule. This time we're intercepting four actions; we *could* have written the property like this:: diff --git a/chapters/07.rst b/chapters/07.rst index 619f16f..c7a8ad0 100644 --- a/chapters/07.rst +++ b/chapters/07.rst @@ -41,16 +41,16 @@ This is the street room, the location where the game starts:: "The crowd, pressing north towards the square, makes that impossible."; -We're using our new ``Room`` class, so there's no need for a ``light`` -attribute. The ``n_to`` and ``s_to`` properties, whose values are an -internal ID and a string respectively, are techniques we've used before. -The only innovation is that the ``description`` property has an embedded -routine as its value. +We're using our new ``Room`` class, so there's no need for a :attr:`light` +attribute. The :prop:`n_to` and :prop:`s_to` properties, whose values are +an internal ID and a string respectively, are techniques we've used before. +The only innovation is that the :prop:`description` property has an +embedded routine as its value. The first thing in that routine is a ``print`` statement, displaying details of the street surroundings. If that was all that we wanted to do, -we could have supplied those details by making the ``description`` value a -string; that is, these two examples behave identically:: +we could have supplied those details by making the :prop:`description` +value a string; that is, these two examples behave identically:: description [; print "The narrow street runs north towards the town square. @@ -85,7 +85,7 @@ The line of dialogue is produced by the ``print`` statement, the ``print`` statement is controlled by the ``if`` statement, and the ``if`` statement is performing the test ``self hasnt visited``. In detail: -* ``visited`` is an attribute, but not one that you'd normally give to an +* :attr:`visited` is an attribute, but not one that you'd normally give to an object yourself. It's automatically applied to a room object by the interpreter, but only after that room has been visited for the first time by the player. @@ -97,20 +97,20 @@ is performing the test ``self hasnt visited``. In detail: if object :samp:`{X}` currently does not have attribute :samp:`{Y}`, false if it does. -* ``self``, which we met in the previous chapter, is that useful variable +* :var:`self`, which we met in the previous chapter, is that useful variable which, within an object, always refers to that object. Since we're using it in the middle of the ``street`` object, that's what it refers to. So, putting it all together, ``self hasnt visited`` is true (and therefore the ``print`` statement is executed) only while the ``street`` object has -*not* got a ``visited`` attribute. Because the interpreter automatically -gives rooms a ``visited`` attribute as soon as the player has been there -once, this test will be true only for one turn. Therefore, the line of -dialogue will be displayed only once: the first time the player visits the -street, at the very start of the game. - -Although the primary importance of ``self`` is within class definitions, it -can also be convenient to use it simply within an object. Why didn't we +*not* got a :attr:`visited` attribute. Because the interpreter +automatically gives rooms a :attr:`visited` attribute as soon as the player +has been there once, this test will be true only for one turn. Therefore, +the line of dialogue will be displayed only once: the first time the player +visits the street, at the very start of the game. + +Although the primary importance of :var:`self` is within class definitions, +it can also be convenient to use it simply within an object. Why didn't we just write this? :: if (street hasnt visited) @@ -118,7 +118,7 @@ just write this? :: ~or you'll get lost among all these people.~^"; It's true that the effect is identical, but there are a couple of good -reasons for using ``self``. One: it's an aid to understanding your code +reasons for using :var:`self`. One: it's an aid to understanding your code days or weeks after writing it. If you read the line ``if (street hasnt visited)``, you need to think for a @@ -131,7 +131,7 @@ code is useful in different situations (say, you want to repeat the mechanics of the street description in another room). Rather than writing everything from scratch, you'll typically use copy-and-paste to repeat the routine, and then all you have to do is compose the appropriate descriptive -strings for the new room. If you've used ``self``, the line ``if (self +strings for the new room. If you've used :var:`self`, the line ``if (self hasnt visited)`` is still good; if you've written instead ``if (street hasnt visited)``, you'll have to change that as well. Worse, if you *forget* to change it, the game will still work -- but not in the way you'd @@ -185,21 +185,21 @@ for this:: :samp:`{external_names}`, because these are used by the ``Prop`` class's ``print_ret ... (the) self`` statement. -You'll see a couple of new attributes: ``animate`` marks an object as being -"alive", while ``pluralname`` specifies that its external name is plural -rather than singular. The interpreter uses these attributes to ensure that -messages about such objects are grammatical and appropriate (for example, -it will now refer to "some merchants" rather than "a merchants"). Because -the library handles so many situations automatically, it's hard to be sure -exactly what messages players may trigger; the best approach is to play -safe and always give an object the relevant set of attributes, even when, -as here, they probably won't be needed. - -You'll also see a new ``found_in`` property, which specifies the rooms -- -and only the rooms; ``found_in`` shouldn't be used to place objects inside -containers or supporters -- where this object is to appear. The stalls, -for example, can be EXAMINEd both in the street and below the square, so we -*could* have created a ``Prop`` object in each room:: +You'll see a couple of new attributes: :attr:`animate` marks an object as +being "alive", while :attr:`pluralname` specifies that its external name is +plural rather than singular. The interpreter uses these attributes to +ensure that messages about such objects are grammatical and appropriate +(for example, it will now refer to "some merchants" rather than "a +merchants"). Because the library handles so many situations automatically, +it's hard to be sure exactly what messages players may trigger; the best +approach is to play safe and always give an object the relevant set of +attributes, even when, as here, they probably won't be needed. + +You'll also see a new :prop:`found_in` property, which specifies the rooms +-- and only the rooms; :prop:`found_in` shouldn't be used to place objects +inside containers or supporters -- where this object is to appear. The +stalls, for example, can be EXAMINEd both in the street and below the +square, so we *could* have created a ``Prop`` object in each room:: Prop "assorted stalls" street with name 'assorted' 'stalls', @@ -211,15 +211,16 @@ for example, can be EXAMINEd both in the street and below the square, so we description "Food, clothing, mountain gear; the usual stuff.", has pluralname; -but ``found_in`` does the same job more neatly -- there's only one object, -but it appears in both the ``street`` and ``below_square`` rooms while the -player's there. The local people are even more ubiquitous. In this case -the ``found_in`` value is an embedded routine rather than a list of rooms; -such a routine would generally test the value of the current location and -``return true`` if it wants to be present here, or ``false`` if not. Since -we'd like the local people *always* to be present, in every room, we -``return true`` without bothering to examine ``location``. It's as though -we'd written any of these, but simpler and less error prone:: +but :prop:`found_in` does the same job more neatly -- there's only one +object, but it appears in both the ``street`` and ``below_square`` rooms +while the player's there. The local people are even more ubiquitous. In +this case the :prop:`found_in` value is an embedded routine rather than a +list of rooms; such a routine would generally test the value of the current +location and ``return true`` if it wants to be present here, or +:const:`false` if not. Since we'd like the local people *always* to be +present, in every room, we ``return true`` without bothering to examine +:var:`location`. It's as though we'd written any of these, but simpler and +less error prone:: Prop "local people" with name 'people' 'folk' 'local' 'crowd', @@ -286,10 +287,11 @@ well define Wilhelm's bow and arrows:: Both of these are straightforward objects, with the ``Drop``, ``Give`` and ``ThrowAt`` actions being intercepted to ensure that Wilhelm is never -without them. The ``clothing`` attribute makes its first appearance, +without them. The :attr:`clothing` attribute makes its first appearance, marking both the quiver and the bow as capable of being worn (as the result of a WEAR BOW command, for instance); you'll remember that our -``Initialise`` routine goes on to add a ``worn`` attribute to the quiver. +``Initialise`` routine goes on to add a :attr:`worn` attribute to the +quiver. An empty quiver is pretty useless, so here's the class used to define Wilhelm's stock of arrows. This class has some unusual features:: @@ -336,8 +338,8 @@ listing them individually in this clumsy fashion: The interpreter will do this for us if our objects are "indistinguishable", best achieved by making them members of a class which includes both -``name`` and ``plural`` properties. We define the actual arrows very -simply, like this:: +:prop:`name` and :prop:`plural` properties. We define the actual arrows +very simply, like this:: Arrow "arrow" quiver; Arrow "arrow" quiver; @@ -367,17 +369,17 @@ There are two other properties not seen previously:: article "an", plural "arrows", -The ``article`` property lets you define the object's indefinite article -- -usually something like "a", "an" or "some" -- instead of letting the -library assign one automatically. It's a belt-and-braces (OK, +The :prop:`article` property lets you define the object's indefinite +article -- usually something like "a", "an" or "some" -- instead of letting +the library assign one automatically. It's a belt-and-braces (OK, belt-and-suspenders) precaution: because "arrow" starts with a vowel, we need to display "an arrow" not "a arrow". Most interpreters automatically get this right, but just to be on the safe side, we explicitly define the -appropriate word. And the ``plural`` property defines the word to be used -when lumping several of these objects together, as in the "three arrows" -inventory listing. The interpreter can't just automatically slap an "s" on -the end; the plural of "slice of cake", for example, isn't "slice of -cakes". +appropriate word. And the :prop:`plural` property defines the word to be +used when lumping several of these objects together, as in the "three +arrows" inventory listing. The interpreter can't just automatically slap +an "s" on the end; the plural of "slice of cake", for example, isn't "slice +of cakes". Moving further along the street =============================== @@ -413,7 +415,7 @@ No surprises there, nor in most of the supporting scenery objects. :: description "Fine locally grown produce.", has pluralname; -The only new thing here is the ``before`` property of the fruit'n'veg +The only new thing here is the :prop:`before` property of the fruit'n'veg stall. The stall's description -- lots of items on a table -- may suggest to players that they can SEARCH through the produce, maybe finding a lucky beetroot or something else interesting. No such luck -- and we might as @@ -431,22 +433,23 @@ statement does the job:: Having diverted the ``Search`` action into an ``Examine`` action, we must tell the interpreter that it doesn't need to do anything else, because we've handled the action ourselves. We've done that before -- using -``return true`` -- and so a first stab at the ``before`` action looks like -this:: +``return true`` -- and so a first stab at the :prop:`before` action looks +like this:: before [; Search: ; return true; ], The two-statement sequence ``<...>; return true`` is so common that there's a single statement shortcut: ``<<...>>``. Also, for exactly the same -reason as before, our code is clearer if we use ``self`` instead of +reason as before, our code is clearer if we use :var:`self` instead of ``stall``. So this is how the property finally stands:: before [; Search: <>; ], A couple of final observations before we leave this topic. The example -here is of an action (``Examine``) applied to an object (``self``, though -``stall`` or ``noun`` would also work at this point). You can also use the -``<...>`` and ``<<...>>`` statements for actions which affect no objects:: +here is of an action (``Examine``) applied to an object (:var:`self`, +though ``stall`` or :var:`noun` would also work at this point). You can +also use the ``<...>`` and ``<<...>>`` statements for actions which affect +no objects:: <>; @@ -479,20 +482,20 @@ principles; here's the class upon which we base our NPCs:: ], has animate; -The most important thing here is the ``animate`` attribute -- that's what -defines an object as an NPC, and causes the interpreter to treat it a +The most important thing here is the :attr:`animate` attribute -- that's +what defines an object as an NPC, and causes the interpreter to treat it a little differently -- for example, TAKE HELGA results in "I don't suppose Helga would care for that". -The ``animate`` attribute also brings into play nine extra actions which -can be applied only to animate objects: ``Answer``, ``Ask``, ``Order`` and -``Tell`` are all associated with speech, and ``Attack``, ``Kiss``, -``Show``, ``ThrowAt`` and ``WakeOther`` are associated with non-verbal -interaction. Additionally, a new ``life`` property -- very similar to -``before`` -- can be defined to intercept them. Here we use it to trap -speech-related commands such as ASK HELGA ABOUT APPLE and TELL WALTER ABOUT -BABIES, telling players that in this game we've implemented only a simpler -TALK verb (which we describe in :ref:`verbs`). +The :attr:`animate` attribute also brings into play nine extra actions +which can be applied only to animate objects: ``Answer``, ``Ask``, +``Order`` and ``Tell`` are all associated with speech, and ``Attack``, +``Kiss``, ``Show``, ``ThrowAt`` and ``WakeOther`` are associated with +non-verbal interaction. Additionally, a new :prop:`life` property -- very +similar to :prop:`before` -- can be defined to intercept them. Here we use +it to trap speech-related commands such as ASK HELGA ABOUT APPLE and TELL +WALTER ABOUT BABIES, telling players that in this game we've implemented +only a simpler TALK verb (which we describe in :ref:`verbs`). Based on the NPC class we've created, here's Helga:: @@ -527,20 +530,20 @@ Based on the NPC class we've created, here's Helga:: ], has female proper; -The new attributes are ``female`` -- because we want the interpreter to -refer to Helga with the appropriate pronouns -- and ``proper``. The latter -signifies that this object's external name is a proper noun, and so +The new attributes are :attr:`female` -- because we want the interpreter to +refer to Helga with the appropriate pronouns -- and :attr:`proper`. The +latter signifies that this object's external name is a proper noun, and so references to it should not be preceded by "a" or "the": you wouldn't want to display "You can see a Helga here" or "I don't suppose the Helga would -care for that". You may notice the library variable ``score`` being +care for that". You may notice the library variable :var:`score` being incremented. This variable holds the number of points that the player has scored; when it changes like this, the interpreter tells the player that "Your score has just gone up by one point". -There are also ``life`` and ``times_spoken_to`` properties (which we'll -talk about in :doc:`09`) and an ``initial`` property. +There are also :prop:`life` and :prop:`times_spoken_to` properties (which +we'll talk about in :doc:`09`) and an :prop:`initial` property. -``initial`` is used when the interpreter is describing a room and listing +:prop:`initial` is used when the interpreter is describing a room and listing the objects initial you can see there. If we *didn't* define it, you'd get this: @@ -556,11 +559,11 @@ this: > but we want to introduce Helga in a more interactive manner, and that's -what the ``initial`` property is for: it replaces the standard "You can see +what the :prop:`initial` property is for: it replaces the standard "You can see *object* here" with a tailored message of your own design. The value of an -``initial`` property can be either a string which is to be displayed or, as +:prop:`initial` property can be either a string which is to be displayed or, as here, an embedded routine. This one is pretty similar to the -``description`` property that we defined for the street: something that's +:prop:`description` property that we defined for the street: something that's *always* printed (Helga pauses...) and something that's printed only on the first occasion ("Hello, Wilhelm, it's a fine day... "): @@ -583,7 +586,7 @@ But it's not quite the same as the street's description routine. First, we need a slightly different ``if`` test: ``self hasnt visited`` works fine for a room object, but this routine is part of an object *in* a room; instead we could use either ``below_square hasnt visited`` or (better) -``location hasnt visited`` -- since ``location`` is the library variable +``location hasnt visited`` -- since :var:`location` is the library variable that refers to the room where the player currently is. And second, some curly braces ``{...}`` have appeared: why? diff --git a/chapters/08.rst b/chapters/08.rst index 2cfec9b..c71f5bd 100644 --- a/chapters/08.rst +++ b/chapters/08.rst @@ -65,11 +65,11 @@ It's all pretty standard stuff: just a ``Room`` and two ``Prop``\s. The players can't EXAMINE it from this room (technically, it's "not in scope"). However, since we're pretending that Wilhelm can see the whole of the square from where he's standing, we need to provide a dummy hat on a pole, -``found_in`` both this room and the north side of the square, even if it's +:prop:`found_in` both this room and the north side of the square, even if it's "too far away" for a detailed description. In fact, it's "too far away" for anything. We've replaced the standard -``before`` action for the ``Prop`` class (which permits ``Examine``, but +:prop:`before` action for the ``Prop`` class (which permits ``Examine``, but rejects other actions with "You don't need to worry about...") with one rejecting *all* actions. Since Wilhelm's hatred of the vogt's activities is central to our plot, a message saying "You don't need to worry about the @@ -80,7 +80,7 @@ there, but they don't do much. Their most interesting characteristic is probably that they trap two actions -- ``FireAt`` and ``Talk`` -- which are *not* part of the library, but instead new actions that we've defined specially for this game. We'll talk about those actions in :ref:`verbs`, -at which time the role of this ``before`` property will make more sense. +at which time the role of this :prop:`before` property will make more sense. The middle of the square ======================== @@ -137,19 +137,19 @@ and the pole:: The room will need some more work in a minute, but the pole object is complete (note that we've simplified matters slightly by making one object represent both the pole and the hat which it supports). It mentions a -property which we've not met before: ``has_been_saluted``. What a +property which we've not met before: :prop:`has_been_saluted`. What a remarkable coincidence: the library provides a property with a name that's exactly right for our game; surely not? -No, of course not. ``has_been_saluted`` isn't a standard library property; -it's one that we've just invented. Notice how easily we did it -- we -simply included the line:: +No, of course not. :prop:`has_been_saluted` isn't a standard library +property; it's one that we've just invented. Notice how easily we did it +-- we simply included the line:: has_been_saluted false, in the object definition and voilà, we've added our own home-made property, -and initialised it to ``false``. To switch the state of the property, we -can simply write:: +and initialised it to :const:`false`. To switch the state of the property, +we can simply write:: pole.has_been_saluted = true; pole.has_been_saluted = false; @@ -180,16 +180,16 @@ assigns a value to a variable. Compare these examples: * - ``score = 10;`` - ``score == 10;`` - * - assigns the value 10 to ``score`` - - does nothing; ``score`` is unchanged + * - assigns the value 10 to :var:`score` + - does nothing; :var:`score` is unchanged * - ``if (score == 10) ...`` - ``if (score = 10) ...`` - * - executes the next statement only if the value of ``score`` is 10 - - assigns 10 to ``score``, then always executes the next statement -- + * - executes the next statement only if the value of :var:`score` is 10 + - assigns 10 to :var:`score`, then always executes the next statement -- because ``score = 10`` evaluates to 10, which is treated as - ``true``, so the test is always ``true`` + :const:`true`, so the test is always :const:`true` Defining a new property variable which, instead of applying to every object in the game (as do the standard library properties), is specific only to a @@ -210,7 +210,7 @@ that the salute was "gratefully" received. Back to the ``mid_square`` room. We've said that we need to detect Wilhelm trying to leave this room, which we can do by trapping the ``Go`` action in -a ``before`` property. Let's sketch the coding we'll need:: +a :prop:`before` property. Let's sketch the coding we'll need:: before [; Go: @@ -222,14 +222,14 @@ We can easily trap the ``Go`` action, but which direction is he moving? Well, it turns out that the interpreter turns a command of GO SOUTH (or just SOUTH) into an action of ``Go`` applied to an object ``s_obj``. This object is defined by the library; so why isn't it called just "``south``"? -Well, because we already have another kind of south, the property ``s_to`` +Well, because we already have another kind of south, the property :prop:`s_to` used to say what lies in a southerly direction when defining a room. To -avoid confusing them, ``s_to`` means "south to" and ``s_obj`` means "south +avoid confusing them, :prop:`s_to` means "south to" and ``s_obj`` means "south when the player types it as the object of a verb". The identity of the object which is the target of the current action is -stored in the ``noun`` variable, so we can write the statement ``if (noun -== s_obj)`` to test whether the contents of the ``noun`` variable are equal +stored in the :var:`noun` variable, so we can write the statement ``if (noun +== s_obj)`` to test whether the contents of the :var:`noun` variable are equal to the ID of the ``s_obj`` object -- and, if so, Wilhelm is trying to move south. Another similar statement tests whether he's trying to move north, and that's all that we're interested in; we can let other movements take @@ -321,15 +321,15 @@ memory, he'll completely forget Wilhelm if our hero should move away from the pole. To do all this, we've added a new property and two statements. The -property is ``warnings_count``, and its value will count how many times +property is :prop:`warnings_count`, and its value will count how many times Wilhelm has tried to go north without saluting the pole: 0 initially, 1 after his first warning, 2 after his second warning, 3 when the soldier's -patience finally runs out. The property ``warnings_count`` isn't a -standard library property; like the pole's ``has_been_saluted`` property, -it's one that we've created to meet a specific need. +patience finally runs out. The property :prop:`warnings_count` isn't a +standard library property; like the pole's :prop:`has_been_saluted` +property, it's one that we've created to meet a specific need. Our first statement is ``self.warnings_count = 0``, which resets the value -of the ``warnings_count`` property of the current object -- the +of the :prop:`warnings_count` property of the current object -- the ``mid_square`` room -- to 0. The second statement is ``pole.has_been_saluted = false``, which signifies that the pole has not be saluted. That's it: the soldier's memory is erased, and Wilhelm's actions @@ -546,14 +546,14 @@ very likely, but good game design is about predicting the unpredictable. :: ], s_to "You hardly feel like going through all that again."; -There's one new feature in this room: the value of the ``n_to`` property is +There's one new feature in this room: the value of the :prop:`n_to` property is a routine, which the interpreter runs when Wilhelm tries to exit the square northwards. All that the routine does is set the value of the library -variable ``deadflag`` to 3, print a confirmation message, and ``return +variable :var:`deadflag` to 3, print a confirmation message, and ``return true``, thus ending the action. -At this point, the interpreter notices that ``deadflag`` is no longer zero, -and terminates the game. In fact, the interpreter checks ``deadflag`` at +At this point, the interpreter notices that :var:`deadflag` is no longer zero, +and terminates the game. In fact, the interpreter checks :var:`deadflag` at the end of every turn; these are the values that it's expecting to find: * 0 -- this is the normal state; the game continues. @@ -564,7 +564,7 @@ the end of every turn; these are the values that it's expecting to find: :term:`entry point` routine called ``DeathMessage`` -- which we must provide -- where we can define our own tailored "end messages". -In this game, we never set ``deadflag`` to 1, but we do use values of 2 +In this game, we never set :var:`deadflag` to 1, but we do use values of 2 and 3. So we'd better define a ``DeathMessage`` routine to tell players what they've done:: @@ -573,7 +573,7 @@ what they've done:: Our game has only one customised ending, so the simple ``DeathMessage`` routine we've written is sufficient for our purposes. Were you to conceive multiple endings for a game, you could specify suitable messages by -checking for the current value of the ``deadflag`` variable:: +checking for the current value of the :var:`deadflag` variable:: [ DeathMessage; if (deadflag == 3) print "You leave Scarlett O'Hara for good"; @@ -582,7 +582,7 @@ checking for the current value of the ``deadflag`` variable:: ... ]; -Of course, you must assign the appropriate value to ``deadflag`` at the +Of course, you must assign the appropriate value to :var:`deadflag` at the point when the game arrives at each of those possible endings. We've nearly finished. In the concluding chapter of this game, we'll talk diff --git a/chapters/09.rst b/chapters/09.rst index 24b04dc..83d9f8d 100644 --- a/chapters/09.rst +++ b/chapters/09.rst @@ -53,24 +53,27 @@ has only one feature of interest:: ], has scenery; -The tree's ``before`` property is intercepting a ``FireAt`` action, which +The tree's :prop:`before` property is intercepting a ``FireAt`` action, which we'll define in a few moments. This action is the result of a command like SHOOT AT TREE WITH BOW -- we could simulate it with the statement ``<>`` -- and it needs extra care to ensure that the -``second`` object is a feasible weapon. To deal with silly commands like -SHOOT AT TREE WITH HELGA, we must test that ``second`` is the bow, one of +:var:`second` object is a feasible weapon. To deal with silly commands like +SHOOT AT TREE WITH HELGA, we must test that :var:`second` is the bow, one of the arrows, or ``nothing`` (from just SHOOT AT TREE). Since this is quite a complex test, and one that we'll be making in several places, it's sensible to write a routine to do the job. Which we'll do shortly -- but first, a general introduction to working with routines. +.. index:: + single: arguments (of a routine) + .. _working-with-routines: A diversion: working with routines ================================== A standalone routine, like the familiar routines embedded as the value of a -property such as ``before`` or ``each_turn``, is simply a set of statements +property such as :prop:`before` or :prop:`each_turn`, is simply a set of statements to be executed. The major differences are in content, in timing, and in the default return value: @@ -86,8 +89,8 @@ the default return value: * If an embedded routine executes all of its statements and reaches the final ``];`` without encountering some form of ``return`` statement, it - returns the value ``false``. In the same circumstances, a standalone - routine returns the value ``true``. There's a good reason for this + returns the value :const:`false`. In the same circumstances, a standalone + routine returns the value :const:`true`. There's a good reason for this difference -- it usually turns out to be the natural default behaviour -- but it can sometimes baffle newcomers. To avoid confusion, we've always included explicit ``return`` statements in our routines. @@ -110,7 +113,7 @@ look at some simple examples; first consider these unexciting foodstuffs:: description "It doesn't look at all appetising.", ... -The ``description``\s are identical: perhaps we could display them using a +The :prop:`description`\s are identical: perhaps we could display them using a routine? :: [ Inedible; print_ret "It doesn't look at all appetising."; ]; @@ -133,7 +136,7 @@ wherever we need to. Here's another simple example showing how, by returning a value, a routine can report back to the piece of code which called it. We've once or twice used the test ``if (self has visited) ...``; we could create a routine -which performs that same check and then returns ``true`` or ``false`` to +which performs that same check and then returns :const:`true` or :const:`false` to indicate what it discovered:: [ BeenHereBefore; @@ -153,7 +156,7 @@ we *could* write another routine to perform that check:: ]; However, the two routines are very similar; the only difference is the name -of the variable -- ``self`` or ``location`` -- which is being checked. A +of the variable -- :var:`self` or :var:`location` -- which is being checked. A better approach might be to rework our ``BeenHereBefore`` routine so that it does both jobs, but we somehow need to tell it which variable's value is to be checked. That's easy: we design the routine so that it expects an @@ -167,17 +170,17 @@ to be checked. That's easy: we design the routine so that it expects an Notice that the argument's name is one that we've invented to be descriptive of its content; it doesn't matter if we define it as "``x``", "``this_room``" or "``hubba_hubba``". Whatever its name, the argument acts -as a placeholder for a value (here, one of the variables ``self`` or -``location``) which we must supply when calling the routine:: +as a placeholder for a value (here, one of the variables :var:`self` or +:var:`location`) which we must supply when calling the routine:: if (BeenToBefore(self) == true) ... if (BeenToBefore(location) == true) ... -In the first line, we supply ``self`` as the routine's argument. The +In the first line, we supply :var:`self` as the routine's argument. The routine doesn't care where the argument came from; it just sees a value which it knows as ``this_room``, and which it then uses to test for the -``visited`` attribute. On the second line we supply ``location`` as the +:attr:`visited` attribute. On the second line we supply :var:`location` as the argument, but the routine just sees another value in its ``this_room`` variable. ``this_room`` is called a :term:`local variable` of the ``BeenToBefore`` routine, one that must be set to a suitable value each @@ -192,7 +195,7 @@ Remember that: write a ``return``, ``rtrue`` or ``rfalse`` statement, or because execution reaches the ``]`` marking the routine's end. -#. All routines return a value, which can be ``true``, or ``false``, or any +#. All routines return a value, which can be :const:`true`, or :const:`false`, or any other number. This value is determined by the ``return``, ``rtrue`` or ``rfalse`` statement, or by the the ``]`` marking the routine's end (in which case the default STEF rule applies: Standalone routines return @@ -211,7 +214,7 @@ Remember that: you always *have* to use it; you can simply ignore the value if you want to. The ``TooFarAway`` routine that we showed you earlier in this chapter contains a ``print_ret`` statement and so always returns - ``true``, but we didn't take any notice; the sole purpose of the routine + :const:`true`, but we didn't take any notice; the sole purpose of the routine was to display some text. Compare this with the ``BeenToBefore`` routine, which does nothing *except* return a value; if we'd ignored that, then calling the routine would have been a waste of time. @@ -273,12 +276,12 @@ The result is that we ask three questions: Is ``o`` the ``bow`` object? which is a member of the ``Arrow`` class? What this means is that the value returned by the call ``BowOrArrow(bow)`` -is ``true``, while the value returned by the call ``BowOrArrow(tree)`` is -``false``. Or, more generally, the value returned by the call -``BowOrArrow(second)`` will be either ``true`` or ``false``, depending on +is :const:`true`, while the value returned by the call ``BowOrArrow(tree)`` is +:const:`false`. Or, more generally, the value returned by the call +``BowOrArrow(second)`` will be either :const:`true` or :const:`false`, depending on the characteristics of the object defined by the value of the variable -``second``. So, we can write this set of statements in an object's -``before`` property:: +:var:`second`. So, we can write this set of statements in an object's +:prop:`before` property:: if (BowOrArrow(second) == true) { This object deals with having an arrow fired at it @@ -287,13 +290,13 @@ the characteristics of the object defined by the value of the variable and the effect is either -* ``second`` is a weapon: ``BowOrArrow`` displays nothing and returns a - value of ``true``, the ``if`` statement reacts to that value and executes +* :var:`second` is a weapon: ``BowOrArrow`` displays nothing and returns a + value of :const:`true`, the ``if`` statement reacts to that value and executes the following statements to produce an appropriate response to the fast-approaching arrow; or -* ``second`` isn't a weapon: ``BowOrArrow`` displays a standard "don't be - silly" message and returns a value of ``false``, the ``if`` statement +* :var:`second` isn't a weapon: ``BowOrArrow`` displays a standard "don't be + silly" message and returns a value of :const:`false`, the ``if`` statement reacts to that value and ignores the following statements. Then * in both cases, the ``return true`` statement terminates the object's @@ -301,7 +304,7 @@ and the effect is either That whole ``BowOrArrow()`` bit was rather complex, but the rest of the ``FireAt`` action is straightforward. Once the tree has determined that -it's being shot at by something sensible, it can just set ``deadflag`` to 3 +it's being shot at by something sensible, it can just set :var:`deadflag` to 3 -- the "You have screwed up" ending, display a message, and be done. Gessler the governor @@ -346,7 +349,7 @@ There's nothing in Gessler's definition that we haven't already encountered:: ], has male; -Like most NPCs, Gessler has a ``life`` property which deals with actions +Like most NPCs, Gessler has a :prop:`life` property which deals with actions applicable only to animate objects. This one responds merely to ``Talk`` (as in TALK TO THE GOVERNOR). @@ -400,17 +403,17 @@ Walter:: found_in [; return true; ], has male proper scenery transparent; -His attributes are ``male`` (he's your son, after all), ``proper`` (so the -interpreter doesn't mention "the your son"), ``scenery`` (so he's not -listed in every room description), and ``transparent`` (because you see -right through him). No, that's wrong: a ``transparent`` object isn't made +His attributes are :attr:`male` (he's your son, after all), :attr:`proper` (so the +interpreter doesn't mention "the your son"), :attr:`scenery` (so he's not +listed in every room description), and :attr:`transparent` (because you see +right through him). No, that's wrong: a :attr:`transparent` object isn't made of glass; it's one whose possessions are visible to you. We've done that because we'd still like to be able to EXAMINE APPLE even when Walter is -carrying it. Without the ``transparent`` attribute, it would be as though +carrying it. Without the :attr:`transparent` attribute, it would be as though the apple was in his pocket or otherwise out of sight; the interpreter would reply "You can't see any such thing". -Walter has a ``found_in`` property which automatically moves him to the +Walter has a :prop:`found_in` property which automatically moves him to the player's location on each turn. We can get away with this because in such a short and simple game, he does indeed follow you everywhere. In a more realistic model world, NPCs often move around independently, but we don't @@ -421,14 +424,14 @@ that is, is the player (and hence Walter) currently in that room? The events in the marketplace are such that specialised responses are more appropriate there than our standard ones. -Walter's ``life`` property responds to ``Give`` (as in GIVE APPLE TO +Walter's :prop:`life` property responds to ``Give`` (as in GIVE APPLE TO WALTER) and Talk (as in TALK TO YOUR SON); during ``Give``, we increment -the library variable ``score``, thus rewarding the player's generous good -nature. His ``before`` property is perhaps a little confusing. It's +the library variable :var:`score`, thus rewarding the player's generous good +nature. His :prop:`before` property is perhaps a little confusing. It's saying: #. The ``Examine``, ``Listen``, ``Salute`` and ``Talk`` actions are always - available (a ``Talk`` action then gets passed to Walter's ``life`` + available (a ``Talk`` action then gets passed to Walter's :prop:`life` property). #. The ``FireAt`` action is permitted in the ``marketplace``, albeit with @@ -438,8 +441,8 @@ saying: #. All other actions are prevented in the ``marketplace``, and allowed to run their standard course (thanks to the ``return false``) elsewhere. -The apple's moment of glory has arrived! Its ``before`` property responds -to the ``FireAt`` action by setting ``deadflag`` to 2. When that happens, +The apple's moment of glory has arrived! Its :prop:`before` property responds +to the ``FireAt`` action by setting :var:`deadflag` to 2. When that happens, the game is over; the player has won. :: Object apple "apple" @@ -510,7 +513,7 @@ prepared to accept:: * noun -> Untie; and we need a routine to handle the action in the default situation (where -the action isn't intercepted by an object's ``before`` property). :: +the action isn't intercepted by an object's :prop:`before` property). :: [ UntieSub; print_ret "You really shouldn't try that."; ]; @@ -522,7 +525,7 @@ The grammar is less complex than it perhaps at first appears: #. The asterisk ``*`` indicates the start of a pattern defining what word(s) might follow the verb. -#. In this example, there's only one pattern: the "``noun``" token +#. In this example, there's only one pattern: the ":var:`noun`" token represents an object which is currently in scope -- in the same room as the player. @@ -566,12 +569,12 @@ We can illustrate how this works in the Altdorf street: The illustration shows four attempted usages of the new action. In the first, the player omits to mention an object; the interpreter knows (from -that ``noun`` in the grammar which implies that the action needs a direct +that :var:`noun` in the grammar which implies that the action needs a direct object) that something is missing, so it issues a helpful prompt. In the second, the player mentions an object that isn't in scope (in fact, there's no dog anywhere in the game, but the interpreter isn't about to give *that* away to the player). In the third, the object is in scope, but its -``before`` property intercepts the ``Untie`` action (and indeed, since this +:prop:`before` property intercepts the ``Untie`` action (and indeed, since this object is of the class ``Prop``, all actions apart from ``Examine``) to display a customised rejection message. Finally, the fourth usage refers to an object which *doesn't* intercept the action, so the interpreter calls @@ -582,7 +585,7 @@ The principles presented here are those that you should generally employ: write a generic action handler which either refuses to do anything (see, for example SQUASH or HIT), or performs the action without affecting the state of the model world (see, for example, JUMP or WAVE); then, intercept -that non-action (generally using a ``before`` property) for those objects +that non-action (generally using a :prop:`before` property) for those objects which might make a legitimate target for the action, and instead provide a more specific response, either performing or rejecting the action. @@ -601,7 +604,7 @@ the hat on the pole. Here's the default action handler:: You'll notice that this is slightly more intelligent than our ``Untie`` handler, since it produces different responses depending on whether the -object being saluted -- stored in the ``noun`` variable -- is ``animate`` +object being saluted -- stored in the :var:`noun` variable -- is :attr:`animate` or not. But it's basically doing the same job. And here's the grammar:: Verb 'bow' 'nod' 'kowtow' 'genuflect' @@ -734,27 +737,27 @@ semicolon in all of the grammar, right at the very end. The first two statements in ``FireAtSub`` deal with the first line of grammar: FIRE (or SHOOT, or AIM) by itself. If the player types just that, -both ``noun`` and ``second`` will contain ``nothing``, so we reject the +both :var:`noun` and :var:`second` will contain ``nothing``, so we reject the attempt with the "at random?" message. Otherwise, we've got at least a -``noun`` value, and possibly a ``second`` value also, so we make our -standard check that ``second`` is something that can be fired, and then +:var:`noun` value, and possibly a :var:`second` value also, so we make our +standard check that :var:`second` is something that can be fired, and then reject the attempt with the "Unthinkable!" message. There are a couple of reasons why you might find this grammar a bit tricky. -The first is that on some lines the word ``noun`` appears twice: you need -to remember that in this context ``noun`` is a parsing token which matches +The first is that on some lines the word :var:`noun` appears twice: you need +to remember that in this context :var:`noun` is a parsing token which matches any single object visible to the player. Thus, the line:: * 'at' noun 'with' noun -> FireAt is matching FIRE AT :samp:`{some_visible_target}` WITH :samp:`{some_visible_weapon}`; perhaps confusingly, the value of the target -object is then stored in variable ``noun``, and the value of the weapon -object in variable ``second``. +object is then stored in variable :var:`noun`, and the value of the weapon +object in variable :var:`second`. The second difficulty may be the final grammar line. Whereas on the -preceding lines, the first ``noun`` matches a target object and the second -``noun``, if present, matches a weapon object, that final line matches FIRE +preceding lines, the first :var:`noun` matches a target object and the second +:var:`noun`, if present, matches a weapon object, that final line matches FIRE :samp:`{some_visible_weapon}` AT :samp:`{some_visible_target}` -- the two objects are mentioned in the wrong sequence. If we did nothing, our ``FireAtSub`` would get pretty confused at this point, but we can swap the @@ -785,9 +788,9 @@ curious), and does three things: #. Deals with TALK TO ME or TALK TO MYSELF. -#. Checks (a) whether the creature being talked to has a ``life`` +#. Checks (a) whether the creature being talked to has a :prop:`life` property, (b) whether that property is prepared to process a ``Talk`` - action, and (c) if the ``Talk`` processing returns ``true``. If all + action, and (c) if the ``Talk`` processing returns :const:`true`. If all three checks succeed then ``TalkSub`` need do nothing more; if one or more of them fails then ``TalkSub`` simply... @@ -804,10 +807,10 @@ curious), and does three things: That second condition ``(RunLife(noun,##Talk) ~= false)`` is a bit of a stumbling block, since it uses ``RunLife`` -- an undocumented internal library routine -- to offer the ``Talk`` action to the NPC's - ``life`` property. We've decided to use it in exactly the same way + :prop:`life` property. We've decided to use it in exactly the same way as the ``Tell`` action does, without worrying too much about how it - works (though it looks as though ``RunLife`` returns some ``true`` - value if the ``life`` property has intercepted the action, ``false`` + works (though it looks as though ``RunLife`` returns some :const:`true` + value if the :prop:`life` property has intercepted the action, :const:`false` if it hasn't). The ``~=`` operator means "not equal to". The grammar is straightforward:: @@ -855,12 +858,12 @@ And Helga's is the most sophisticated (though that isn't saying much):: } ], -This handler uses Helga's ``times_spoken_to`` property -- not a library -property, it's one that we invented, like the ``mid_square.warnings_count`` -and ``pole.has_been_saluted`` properties -- to keep track of what's been -said, permitting two snatches of conversation (and awarding a point) before -falling back on the embarrassing silences implied by "You can't think of -anything to say". +This handler uses Helga's :prop:`times_spoken_to` property -- not a library +property, it's one that we invented, like the +:prop:`mid_square.warnings_count` and :prop:`pole.has_been_saluted` +properties -- to keep track of what's been said, permitting two snatches of +conversation (and awarding a point) before falling back on the embarrassing +silences implied by "You can't think of anything to say". That's the end of our little fable; you'll find a transcript and the full source in :doc:`/appendices/c`. And now, it's time to meet -- Captain diff --git a/chapters/10.rst b/chapters/10.rst index 0d51d8a..6c785f9 100644 --- a/chapters/10.rst +++ b/chapters/10.rst @@ -149,11 +149,11 @@ Tell", which defines the maximum number of points to be scored, we now see two more constants: ``OBJECT_SCORE`` and ``ROOM_SCORE``. There are several scoring systems predefined in Inform. In "William Tell" we've seen how you can manually add (or subtract) points by changing the value -of the variable ``score``. Another approach is to award points to +of the variable :var:`score`. Another approach is to award points to players on the first occasion that they (a) enter a particular room, or (b) pick up a particular object. To define that a room or object is indeed “particular”, all you have to do is give it the attribute -``scored``; the library take cares of the rest. The predefined scores +:attr:`scored`; the library take cares of the rest. The predefined scores are five points for finally reached rooms and four points for wondrous acquisition of objects. With the constants ``OBJECT_SCORE`` and ``ROOM_SCORE`` we can change those defaults; for the sake of example, @@ -197,7 +197,7 @@ has been displayed on the screen -- we should use the explicit ``print`` statement instead. You'll notice that -- unusually for a room -- our ``street`` object has -a ``name`` property: +a :prop:`name` property: .. code-block:: inform @@ -212,14 +212,14 @@ EXAMINE CITY here, the interpreter will reply "That's not something you need to refer to in order to SAVE the day", rather than the misleading "You can't see any such thing". We mostly prefer to deal with such scenic words using classes like ``Prop`` and ``Furniture``, but -sometimes a room's ``name`` property is a quick and convenient solution. +sometimes a room's :prop:`name` property is a quick and convenient solution. In this game, we provide a class named ``Appliance`` to take care of furniture and unmovable objects. You’ll notice that the starting room we have defined has no connections yet. The description mentions a phone booth and a café, so we might want to code those. While the café will be a normal room, it would seem logical that the phone booth is actually a -big box on the sidewalk; therefore we define a ``container`` set in the +big box on the sidewalk; therefore we define a :attr:`container` set in the street, which players may enter: .. code-block:: inform @@ -243,20 +243,20 @@ street, which players may enter: has enterable container open; What's interesting are the attributes at the end of the definition. -You'll recall from Heidi's ``nest`` object that a ``container`` is an +You'll recall from Heidi's ``nest`` object that a :attr:`container` is an object capable of having other objects placed in it. If we make -something ``enterable``, players count as one of those objects, so that +something :attr:`enterable`, players count as one of those objects, so that they may squeeze inside. Finally, ``containers`` are, by default, -supposed to be closed. You can make them ``openable`` if you wish +supposed to be closed. You can make them :attr:`openable` if you wish players to be able to OPEN and CLOSE them at will, but this doesn't seem appropriate behaviour for a public cabin -- it would become tedious to have to type OPEN BOOTH and CLOSE BOOTH when these actions provide -nothing special -- so we add instead the attribute ``open`` (as we did +nothing special -- so we add instead the attribute :attr:`open` (as we did with the nest), telling the interpreter that the container is open from the word go. Players aren't aware of our design, of course; they may indeed try to OPEN and CLOSE the booth, so we trap those actions in a -``before`` property which just tells them that these are not relevant -options. The ``after`` property gives a customised message to override +:prop:`before` property which just tells them that these are not relevant +options. The :prop:`after` property gives a customised message to override the library’s default for commands like ENTER BOOTH or GO INSIDE BOOTH. Since in the street's description we have told players that the phone @@ -284,7 +284,7 @@ Players may type EXIT or OUT while they are inside an enterable container and the interpreter will oblige but, again, they might type NORTH. This is a problem, since we are actually in the street (albeit inside the booth) and to the north we have the café. We may provide for -this condition in the room's ``before`` property: +this condition in the room's :prop:`before` property: .. code-block:: inform @@ -307,7 +307,7 @@ player to try something else: Now everything seems to be fine, except for a tiny detail. We've said that, while in the booth, the player character’s location is still the -``street`` room, regardless of being inside a ``container``; if players +``street`` room, regardless of being inside a :attr:`container`; if players chanced to type LOOK, they'd get: .. code-block:: transcript @@ -319,15 +319,15 @@ chanced to type LOOK, they'd get: Hardly an adequate description while *inside* the booth. There are several ways to fix the problem, depending on the result you wish to -achieve. The library provides a property called ``inside_description`` +achieve. The library provides a property called :prop:`inside_description` which you can utilise with enterable containers. It works pretty much -like the normal ``description`` property, but it gets printed only when +like the normal :prop:`description` property, but it gets printed only when the player is inside the container. The library makes use of this property in a very clever way, because for every LOOK action it checks whether we can see outside the container: if the container has the -``transparent`` attribute set, or if it happens to be ``open``, the -library displays the normal ``description`` of the room first and then -the ``inside_description`` of the container. If the library decides we +:attr:`transparent` attribute set, or if it happens to be :attr:`open`, the +library displays the normal :prop:`description` of the room first and then +the :prop:`inside_description` of the container. If the library decides we can’t see outside the container, only the inside_description is displayed. Take for instance the following (simplified) example: @@ -371,8 +371,8 @@ If now the player closes the box and LOOKs: In our case, however, we don't wish the description of the street to be displayed at all (even if a caller is supposedly able to see the street while inside a booth). The problem is that we have made the booth an -``open`` container, so the street's description would be displayed every -time. There is another solution. We can make the ``description`` +:attr:`open` container, so the street's description would be displayed every +time. There is another solution. We can make the :prop:`description` property of the ``street`` room a bit more complex, and change its value: instead of a string, we write an embedded routine. Here's the (almost) finished room: @@ -437,6 +437,8 @@ something else to describe it: ], has enterable proper; +.. index:: accented characters + .. note:: Although the text of our guide calls Benny's establishment a "café" -- @@ -449,7 +451,7 @@ something else to describe it: The town's favourite for a quick snack, Benny's café has a 50's ROCKETSHIP look. - by defining the ``description`` property as any of these: + by defining the :prop:`description` property as any of these: .. code-block:: inform @@ -471,21 +473,21 @@ something else to describe it: Unlike the sidewalk object, we offer more than a mere description. Since the player may try ENTER CAFE as a reasonable way of access -- which would have confused the interpreter immensely -- we take the opportunity -of making this object also ``enterable``, and we cheat a little. The -attribute ``enterable`` has permitted the verb ENTER to be applied to -this object, but this is not a ``container``; we want the player to be -sent into the *real* café room instead. The ``before`` property handles +of making this object also :attr:`enterable`, and we cheat a little. The +attribute :attr:`enterable` has permitted the verb ENTER to be applied to +this object, but this is not a :attr:`container`; we want the player to be +sent into the *real* café room instead. The :prop:`before` property handles this, intercepting the action, displaying a message and teleporting the player into the café. We ``return true`` to inform the interpreter that we have taken care of the ``Enter`` action ourselves, so it can stop right there. As a final detail, note that we now have two ways of going into the -café: the ``n_to`` property of the ``street`` room and the ``Enter`` +café: the :prop:`n_to` property of the ``street`` room and the ``Enter`` action of the ``outside_of_cafe`` object. A perfectionist might point out that it would be neater to handle the actual movement of the player in just one place of our code, because this helps clarity. To achieve -this, we redirect the street's ``n_to`` property thus: +this, we redirect the street's :prop:`n_to` property thus: .. code-block:: inform @@ -517,7 +519,7 @@ a normal gaming situation; each displays an all-purpose message, sufficiently non-committal, and that's it. Of course, if your game includes a magic portal that will reveal itself only if the player lets rip with a snatch of Wagner, you may intercept the ``Sing`` action in a -``before`` property and alter its default, pretty useless behaviour. If +:prop:`before` property and alter its default, pretty useless behaviour. If not, it's "Your singing is abominable" for you. All actions, useful or not, have a stock of messages associated with them @@ -572,7 +574,7 @@ use of the ``LibraryMessages`` object. If you provide it, the ``LibraryMessages`` object must be defined *between* the inclusion of ``Parser`` and ``VerbLib`` (it won't work otherwise and you’ll get a compiler error). The object contains a single -property -- ``before`` -- which intercepts display of the default +property -- :prop:`before` -- which intercepts display of the default messages that you want to change. An attempt to SING, for example, will now result in "Alas! That is not one of your many superpowers" being displayed. diff --git a/chapters/11.rst b/chapters/11.rst index 2a7cd8f..499f75b 100644 --- a/chapters/11.rst +++ b/chapters/11.rst @@ -72,18 +72,18 @@ We've mentioned a counter: ], has supporter; -That ``before`` property, superficially normal, actually conceals a +That :prop:`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's :prop:`before` property to intercept an action directed at that object; for example, if the player types HIT COUNTER then the counter's -``before`` property is potentially able to intercept the resulting +:prop:`before` property is potentially able to intercept the resulting Attack action. However, the command PUT KEY ON COUNTER generates *two* actions. First, a PutOn action is offered to the key (effectively saying, do you want to be placed on top of the counter?); that’s the normal bit. And then the surprise: a Receive action is offered to the counter (effectively saying, are you happy to have the key placed on -you?) Both actions have the same opportunity of returning ``false`` to -let the action continue, ``true`` to prevent it. +you?) Both actions have the same opportunity of returning :const:`false` to +let the action continue, :const:`true` to prevent it. .. todo:: @@ -193,27 +193,27 @@ to our hero’s performance. Let's go step by step. Our hero enters the café dressed as John Covarth, but will eventually manage to change clothes in the toilet, and he'll have to cross back through the café to reach the street and win the -game. The customers' ``description`` takes into consideration which +game. The customers' :prop:`description` takes into consideration which outfit the player character is wearing. -In "William Tell" we’ve seen a brief manifestation of the ``life`` -property, but here we'll extend it a little. As we explained, ``life`` +In "William Tell" we’ve seen a brief manifestation of the :prop:`life` +property, but here we'll extend it a little. As we explained, :prop:`life` lets you intercept those actions particular to animate objects. Here we trap ``Attack`` and ``Kiss`` to offer some customised messages for these actions when applied to the customers. Also, we avoid conversation by intercepting ``Ask``, ``Tell`` and ``Answer`` in order just to produce a message which depends on the player character's attire. -One other feature of ``animate`` objects is the possibility of giving +One other feature of :attr:`animate` objects is the possibility of giving them orders: BILL, SHAKE THE SPEAR or ANNIE, GET YOUR GUN . These -actions are dealt with in the ``orders`` property and, as with the -``life`` property, the embedded routine can become quite complex if you +actions are dealt with in the :prop:`orders` property and, as with the +:prop:`life` property, the embedded routine can become quite complex if you want your NPCs to behave in an interesting way. In this case, we don't need the customers to perform tasks for us, so instead we provide a simple rejection message, just in case the player tries to order people around. -Which leaves us with the ``daemon`` bit. A daemon is a property normally +Which leaves us with the :prop:`daemon` bit. A daemon is a property normally used to perform some timed or repetitive action without the need of the player’s direct interaction; for example, machines which work by themselves, animals that move on their own, or people going about their @@ -307,7 +307,7 @@ to change only in the toilet; (b) we won’t let players change back into street clothes; and (c) once players manage to step into the street thus dressed, the game is won. So, we can safely assume that if players enter the café in their Captain’s outfit, they’ll be coming from the toilet. -As a consequence of all this, we add an ``after`` property to the café +As a consequence of all this, we add an :prop:`after` property to the café room object: .. code-block:: inform @@ -330,10 +330,10 @@ There are two useful techniques to detect when the player is entering or leaving a room. We'll later see in detail how to deal with a player trying to go away and how to avoid it if need be. For now, let’s just mention that, in both cases, you have to intercept the ``Go`` action in -a room object; if you trap it in a ``before`` property, you’re checking -for departure from the room; if you trap it in an ``after`` property, +a room object; if you trap it in a :prop:`before` property, you’re checking +for departure from the room; if you trap it in an :prop:`after` property, you’re checking for arrivals into the room. Right now we wish to know if -the player just came from the toilet, so we use an ``after`` property. +the player just came from the toilet, so we use an :prop:`after` property. The first line: @@ -348,9 +348,9 @@ connecting rooms without cardinal logic); the interpreter will apply 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 +which case it starts the :prop:`daemon` of the ``customers`` object. The use of the local ``first_time_out`` property ensures that the condition is -``true`` only once, so the statement block attached to it runs also +:const:`true` only once, so the statement block attached to it runs also once. We've finished with the customers in the café. Now, we have the toilet @@ -378,25 +378,25 @@ first code a simple door: We find this door in the café. We must specify the direction in which the door leads and, as we have mentioned in the café's description, that -would be to the north. That’s what the ``door_dir`` property is for, and +would be to the north. That’s what the :prop:`door_dir` property is for, and in this case it takes the value of the north direction property -``n_to``. Then we must tell Inform the identity of the room to be found -behind the door, hence the ``door_to`` property, which takes the value +:prop:`n_to`. Then we must tell Inform the identity of the room to be found +behind the door, hence the :prop:`door_to` property, which takes the value of the toilet room -- to be defined later. Remember the café's connection to the north, ``n_to toilet_door``? Thanks to it, Inform will -know that the door is in the way, and thanks to the ``door_to`` +know that the door is in the way, and thanks to the :prop:`door_to` property, what lies beyond. -Doors *must* have the attribute ``door``, but beyond that we have a +Doors *must* have the attribute :attr:`door`, but beyond that we have a stock of options to help us define exactly what kind of door we are -dealing with. As for containers, doors can be ``openable`` (which +dealing with. As for containers, doors can be :attr:`openable` (which activates the verbs OPEN and CLOSE so that they can be applied to this object) and, since by default they are closed, you can give them the -attribute ``open`` if you wish otherwise. Additionally, doors can be -``lockable`` (which sets up the LOCK/UNLOCK verbs) and you can make them -``locked`` to override their default unlocked status. The verbs LOCK +attribute :attr:`open` if you wish otherwise. Additionally, doors can be +:attr:`lockable` (which sets up the LOCK/UNLOCK verbs) and you can make them +:attr:`locked` to override their default unlocked status. The verbs LOCK and UNLOCK are expecting some kind of key object to operate the door. -This must be defined using the ``with_key`` property, whose value should +This must be defined using the :prop:`with_key` property, whose value should be the internal ID of the key; in our example, the soon-to-be-defined ``toilet_key`` . If you don't supply this property, players won't be able to lock or unlock the door. @@ -445,12 +445,12 @@ properties: with_key toilet_key, has scenery door openable lockable locked; -First of all, the door now needs a ``found_in`` property, since it's -going to be located both in the café and the toilet. The ``description`` +First of all, the door now needs a :prop:`found_in` property, since it's +going to be located both in the café and the toilet. The :prop:`description` checks which side of the door we are looking at – testing the current -value of the variable ``location``, which holds the room the player is +value of the variable :var:`location`, which holds the room the player is in -- because we have a scribbled note stuck on one side, but not on the -other. And the ``door_dir`` and ``door_to`` properties must use the same +other. And the :prop:`door_dir` and :prop:`door_to` properties must use the same trick, because we travel north from the café into the toilet, but south from the toilet into the café. @@ -474,11 +474,11 @@ coded thus: Object toilet_door with short_name "toilet door", -``short_name`` is a property that supplies the external name of an +:prop:`short_name` is a property that supplies the external name of an object, either as a string or an embedded routine. Normally, objects retain the same external name throughout the game -- and the header information method is perfect in that case -- but if it needs to change, -it's easy to write a routine as the value of ``short_name``: +it's easy to write a routine as the value of :prop:`short_name`: .. code-block:: inform @@ -494,9 +494,9 @@ it's easy to write a routine as the value of ``short_name``: Notice the ``return true`` at the end of the routine. You''ll recall that the standard rule says "return false to carry on, true to take over -and stop normal execution”. In the case of ``short_name``, "carry on" +and stop normal execution”. In the case of :prop:`short_name`, "carry on" means "and now display the external name from the header information", -which is sometimes handy; for instance, you could write a ``short_name`` +which is sometimes handy; for instance, you could write a :prop:`short_name` routine to prefix an object's external name with one of a range of adjectives -- perhaps a shining/flickering/fading/useless lantern. @@ -505,7 +505,7 @@ adjectives -- perhaps a shining/flickering/fading/useless lantern. 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 + that is, with no external name and no :prop:`short_name` property, we might see:: You open the (toilet_door). @@ -538,7 +538,7 @@ exciting can the crossing of an ordinary door be, after all? If a few lines of code can make the life of the player easier, it's worth a shot. Let's provide a few improvements to our toilet door in -``before`` and ``after`` properties: +:prop:`before` and :prop:`after` properties: .. code-block:: inform @@ -591,12 +591,12 @@ shouldn’t assume that they want to lock it as well). locked, something went wrong, so we ``return false`` to display the standard message for an unsuccessful unlocking. Otherwise, the door is now unlocked, so we inform the player that we are opening the door and - redirect the action to actually open it, returning ``true`` to + redirect the action to actually open it, returning :const:`true` to suppress the standard message. -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 +In all processes there is a library variable called :var:`keep_silent`, +which can be either :const:`false` (the normal state) or :const:`true`; when +:const:`true`, the interpreter does not display the associated message of an action in progress, so we can avoid things like: .. code-block:: transcript @@ -605,10 +605,10 @@ action in progress, so we can avoid things like: You open the door to the toilet. You unlock the door to the toilet and open it. -Although we want to set ``keep_silent`` to ``true`` for the duration of +Although we want to set :var:`keep_silent` to :const:`true` for the duration of our extra processing, we need to reset it afterwards. In a case like this, good design practice is to preserve its initial value (which was -probably ``false``, but you should avoid risky assumptions); we use a +probably :const:`false`, but you should avoid risky assumptions); we use a local variable ``ks`` to remember that initial setting so that we can safely restore it afterwards. You’ll remember that a local variable in a standalone routine is declared between the routine’s name and the @@ -634,16 +634,16 @@ assign it thus: ks = keep_silent; -we are actually making ``ks`` equal to whatever value ``keep_silent`` -has (either ``true`` or ``false``; we actually don't care). We then set -``keep_silent`` to ``true``, make the desired silent actions, and we +we are actually making ``ks`` equal to whatever value :var:`keep_silent` +has (either :const:`true` or :const:`false`; we actually don't care). We then set +:var:`keep_silent` to :const:`true`, make the desired silent actions, and we assign: .. code-block:: inform keep_silent = ks; -which restores the value originally stored in ``ks`` to ``keep_silent``. +which restores the value originally stored in ``ks`` to :var:`keep_silent`. The effect is that we manage to leave it as it was before we tampered with it. @@ -732,13 +732,13 @@ While Benny has the key, there's logically no way to examine it (or perform any other action involving it), but we want to prevent the interpreter from objecting that ``You can't see any such thing``. We've made the ``toilet_key`` a child of the ``benny`` object, and you can see -that Benny's got a ``transparent`` attribute; this means that the key is +that Benny's got a :attr:`transparent` attribute; this means that the key is in scope, and enables the player to refer to it without the interpreter -complaining. Because Benny also has an ``animate`` attribute, the +complaining. Because Benny also has an :attr:`animate` attribute, the interpreter would normally intercept a TAKE KEY action with "That seems to belong to Benny"; however, the same wouldn't apply to other commands like TOUCH KEY and TASTE KEY . So, to prevent any interaction with the -key while it’s in Benny’s pockets, we define a ``before`` property. +key while it’s in Benny’s pockets, we define a :prop:`before` property. .. code-block:: inform @@ -750,7 +750,7 @@ key while it’s in Benny’s pockets, we define a ``before`` property. "Benny is trusting you to look after that key."; ]; -All of the ``before`` properties that we've so far created have contained +All of the :prop:`before` properties that we've so far created have contained one or more labels specifying the actions which they are to intercept; you'll remember that in "William Tell" we introduced the ``default`` action (see :ref:`props-class`) to mean "any value not already catered @@ -761,7 +761,7 @@ a polite refusal; if the player has it then we prevent careless disposal; otherwise, the action continues unhindered. (In fact, the hat-on-a-pole ``Prop`` introduced in :ref:`south-side` had -this all-exclusive ``before`` property: +this all-exclusive :prop:`before` property: .. code-block:: inform @@ -773,12 +773,12 @@ this all-exclusive ``before`` property: It would have behaved exactly the same if we'd omitted the ``default`` label, as we do here for Benny's key.) -Another small innovation here: the ``invent`` library property (we +Another small innovation here: the :prop:`invent` library property (we didn’t make it up) which enables you to control how objects appear in inventory listings, overriding the default. Left to itself, the interpreter simply displays the object’s external name, preceded either by a standard article like "a" or "some", or one specifically defined in -the object's ``article`` property. Here we replace "the toilet key" with +the object's :prop:`article` property. Here we replace "the toilet key" with one of two more helpful descriptions, making it a most valuable object in the eyes of John Covarth, and something to be despised haughtily by Captain Fate once it's of no further use to him. diff --git a/chapters/12.rst b/chapters/12.rst index f7009c6..0260f67 100644 --- a/chapters/12.rst +++ b/chapters/12.rst @@ -20,7 +20,10 @@ owner of Benny's café to be developed in full. Too many toilets ================ -If you check the ``name`` properties of the toilet door, the toilet key +.. index:: + single: ambiguous objects + +If you check the :prop:`name` properties of the toilet door, the toilet key and the toilet room, you’ll see that the dictionary word ``'toilet'`` occurs in all of them. There won't be any problems if players mention the words DOOR or KEY, but we reach a strange impasse should they try to @@ -78,21 +81,21 @@ some routines at the heart of the standard library; these may not be identical in other Inform versions. The introduction explains what ``pname.h`` does for you; namely, it lets -you avoid using complicated ``parse_name`` routines to disambiguate the +you avoid using complicated :prop:`parse_name` routines to disambiguate the player's input when the same dictionary word refers to more than one -item. A ``parse_name`` routine would have been the solution to our +item. A :prop:`parse_name` routine would have been the solution to our problem before the existence of this file, and it qualifies as an advanced programming topic, difficult to master on a first approach. Fortunately, we don't need to worry. Neil Cerutti explains: The ``pname.h`` package defines a new object property, ``pname`` (short for phrase name), with a similar look and feel to the standard - ``name`` property: both contain a list of dictionary words. However, + :prop:`name` property: both contain a list of dictionary words. However, in a ``pname`` property the order of the words is significant, and special operators ``'.p'`` ``'.or'`` and ``'.x'`` enable you to embed some intelligence into the list. In most cases where the standard - ``name`` property isn't enough, you can now just replace it with a - ``pname`` property, rather than write a ``parse_name`` property + :prop:`name` property isn't enough, you can now just replace it with a + ``pname`` property, rather than write a :prop:`parse_name` property routine. We'll soon see how it works. Let's take a look at the installation @@ -147,7 +150,7 @@ providing replacements for some standard routines. 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 be added to some of our objects, and which works pretty much like a -``name`` property. In fact, it should be used *instead* of a ``name`` +:prop:`name` property. In fact, it should be used *instead* of a :prop:`name` property where we have a disambiguation problem. Let’s change the relevant lines for the toilet door and the toilet key: @@ -229,7 +232,7 @@ code. Remember Benny's basic definition from the previous chapter: strikes him.", has scenery animate male proper transparent; -We can now add some complexity, beginning with a ``life`` property. In +We can now add some complexity, beginning with a :prop:`life` property. In generic form: .. code-block:: inform @@ -296,9 +299,9 @@ capability), is more local property variables: live [; ... -Now we are ready to tackle the ``Give`` action of the ``life`` property, +Now we are ready to tackle the ``Give`` action of the :prop:`life` property, which deals with commands like GIVE THE KEY TO BENNY (in a moment, we'll -come to the ``Give`` action of the ``orders`` property, which deals with +come to the ``Give`` action of the :prop:`orders` property, which deals with commands like BENNY, GIVE ME THE KEY): .. code-block:: inform @@ -326,7 +329,7 @@ commands like BENNY, GIVE ME THE KEY): back anytime,~ he says."; } -The Give action in the ``life`` property holds the variable ``noun`` as +The Give action in the :prop:`life` property holds the variable :var:`noun` as the object offered to the NPC. Remember that we can use the ``switch`` statement as shorthand for: @@ -340,7 +343,7 @@ 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 successfully transferred. The property ``key_not_returned`` will be set to true when we receive the toilet key from Benny (we have not coded that bit -yet), and now, when we give it back, it's reset to ``false``. The ``move`` +yet), and now, when we give it back, it's reset to :const:`false`. The ``move`` statement is in charge of the actual transfer of the object from the player's inventory to Benny, and we finally display a confirmation message. With the coin, we find a new statement: ``remove``. This extracts @@ -350,7 +353,7 @@ object permanently -- and indeed you could return it to the object tree using the ``move`` statement); as far as the player is concerned, there isn’t a COIN to be found anywhere. The ``coffee_not_paid`` property will be set to true when Benny serves us the cup of coffee (again, we’ll see that -in a moment); now we reset it to ``false``, which liberates the player from +in a moment); now we reset it to :const:`false`, which liberates the player from debt. This culminates with the ``"..."`` print-and-return statement, telling the player that the action was successful. In passing, remember that in :ref:`homely-atmos` we defined the counter such that PUT KEY ON @@ -366,11 +369,11 @@ indulge in caffeine. Once the coin is paid, it disappears for good, supposedly into Benny's greedy pockets. No need to worry about it any more. -The benny object needs also an ``orders`` property, just to take care of +The benny object needs also an :prop:`orders` property, just to take care of the player's requests for coffee and the key, and to fend off any other -demands. The ``Give`` action in an ``orders`` property deals with inputs +demands. The ``Give`` action in an :prop:`orders` property deals with inputs like ASK BENNY FOR THE KEY or BENNY, GIVE ME THE KEY. The syntax is -similar to that of the ``life`` property: +similar to that of the :prop:`life` property: .. code-block:: inform @@ -412,7 +415,7 @@ similar to that of the ``life`` property: } ], -* We test the value of ``second`` in order to trap over-generous +* We test the value of :var:`second` in order to trap over-generous gestures such as BENNY, GIVE COFFEE TO CUSTOMERS . Then we consider potential requests. @@ -425,9 +428,9 @@ similar to that of the ``life`` property: possessions -- a perverse player could get the key, then drop it somewhere and ask for it again; if this should happen, we indicate that Benny is nobody's fool with the message ``"~Last place I saw - that key..."``. Once all these fitting conditions are ``true``, + that key..."``. Once all these fitting conditions are :const:`true`, players will get the key, which means that they have to return it -- - the ``key_not_returned`` property becomes ``true`` -- and we display + the ``key_not_returned`` property becomes :const:`true` -- and we display a suitable message. However, if the player didn't ask for a coffee, Benny refuses to oblige, mentioning for the first time the menu board where players will be able to see a picture of a cup of coffee when @@ -437,9 +440,9 @@ similar to that of the ``life`` property: * **Coffee:** we check whether players have already asked for a coffee, by testing the ``coffee_asked_for`` property, and refuse to serve - another one if ``true``. If ``false``, we place the coffee on the + another one if :const:`true`. If :const:`false`, we place the coffee on the counter, and set the properties ``coffee_asked_for`` and - ``coffee_not_paid`` to ``true``. The message bit you know about. + ``coffee_not_paid`` to :const:`true`. The message bit you know about. * **Food:** we'll provide an object to deal with all of the delicious comestibles to be found in the café, specifically those (such as @@ -520,13 +523,13 @@ description: we could have assigned a new value to the ``player.description`` variable, but opted to use the ``LibraryMessages`` object instead. This is a similar case. The code causing Benny to intercept the forgetful player could have been added, -perhaps, to a ``daemon`` property in Benny’s definition. However, since +perhaps, to a :prop:`daemon` property in Benny’s definition. However, since the action to be intercepted is always the same one and happens to be a movement action when the player tries to leave the café room, it is also possible to code it by trapping the ``Go`` action of the room object. Both would have been right, but this is somewhat simpler. -We have added a ``before`` property to the room object (albeit a longish +We have added a :prop:`before` property to the room object (albeit a longish one), just dealing with the ``Go`` action. As we mentioned in an earlier chapter, this technique lets you trap the player who is about to exit a room before the movement actually takes place, a good moment to @@ -559,9 +562,9 @@ The first three are covered by the test: if (benny.coffee_not_paid == true || benny.key_not_returned == true) ... that is, if either the coffee is not paid for *or* if the key is not -returned. When this condition is ``false``, it means that both +returned. When this condition is :const:`false`, it means that both misdemeanours have been avoided and that the player is free to go. -However, when this condition is ``true``, the hand of Benny falls on the +However, when this condition is :const:`true`, the hand of Benny falls on the player's shoulder and then the game displays a different message according to which fault or faults the player has committed. diff --git a/chapters/13.rst b/chapters/13.rst index d799630..d4c8642 100644 --- a/chapters/13.rst +++ b/chapters/13.rst @@ -77,7 +77,7 @@ And a not-so-trivial object: it's Colombian."; ]; -There's nothing really new in this object (other than that the ``name`` +There's nothing really new in this object (other than that the :prop:`name` property caters for orthographically challenged players), but notice how we don't ``remove`` it after the player drinks it. In an apparently absurd whim, the coffee returns to Benny magically (although this is not @@ -89,18 +89,18 @@ first one has been removed, Benny will complain "I don’t think that’s on the menu, sir" -- a blatant lie -- which was the default in Benny’s orders property. Since the removed coffee object does not belong to Benny, it's not a noun that the player can ASK Benny FOR. By making it a -child of the barman (who has the ``transparent`` attribute set), the +child of the barman (who has the :attr:`transparent` attribute set), the coffee is still an object that players can refer to. We ensure that they don't get more cups thanks to Benny's ``coffee_asked_for`` property, -which will remain ``true`` after the first time. +which will remain :const:`true` after the first time. We also ensure that Benny doesn't ask for money from players who have already paid, by first printing a "You pick up the cup..." message and then testing Benny's ``coffee_not_paid`` property. If its value is -``true``, we can finish the message with the "quidbuck" print-and-return -statement. If its value is ``false``, the player has previously paid, +:const:`true`, we can finish the message with the "quidbuck" print-and-return +statement. If its value is :const:`false`, the player has previously paid, and so there's nothing else to say. However, we still need to terminate -the incomplete message with a newline, and to return ``true`` from the +the incomplete message with a newline, and to return :const:`true` from the property routine; we *could* have used the statements ``{ print "^"; return true; }``, but an empty ``""`` statement does the same thing more neatly. @@ -161,7 +161,7 @@ will be some tricky side effects: We initially place the coin as a child of the lavatory (just so that we can easily make the ``if (coin in self)`` one-time test). Since the -lavatory does not have the ``transparent`` attribute set, the coin will +lavatory does not have the :attr:`transparent` attribute set, the coin will be invisible to players until they try to inspect the lavatory, an action that will move the coin into the toilet room. Once taken, the coin will remain in the inventory until the player gives it to Benny, @@ -174,11 +174,11 @@ problem: the other objects here which may have TOILET in their names -- the key and the door -- both use the ``pname`` property to turn their use of ``'toilet'`` into a lower-priority adjective. -See that here we have the only two ``scored`` attributes of the game. +See that here we have the only two :attr:`scored` attributes of the game. The player will be awarded one point for entering the toilet room, and another for finding and picking up the coin. -You might have noticed that we are forcefully clearing the ``light`` +You might have noticed that we are forcefully clearing the :attr:`light` attribute, inherited from the ``Room`` class. This will be a windowless space and, to add a touch of realism, we'll make the room a dark one, which will enable us to tell you about Inform's default behaviour when @@ -208,8 +208,8 @@ duties. ], has switchable ~on; -Please notice the appearance of new attributes ``switchable`` and -``on``. switchable enables the object to be turned on and off, and is +Please notice the appearance of new attributes :attr:`switchable` and +:attr:`on`. switchable enables the object to be turned on and off, and is typical of lanterns, computers, television sets, radios, and so on. The library automatically extends the description of these objects by indicating if they are currently on or off: @@ -230,7 +230,7 @@ display a message like: They also take care of checking if the player fumbled and tried to turn on (or off) an object which was already on (or off). How does the -library know the state of the object? This is thanks to the ``on`` +library know the state of the object? This is thanks to the :attr:`on` attribute, which is set or cleared automatically as needed. You can, of course, set or clear it manually like any other attribute, with the ``give`` statement: @@ -241,7 +241,7 @@ course, set or clear it manually like any other attribute, with the 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 @@ -249,7 +249,7 @@ and check if a ``switchable`` object is on or off with the test: 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 @@ -270,17 +270,17 @@ that at some point we'll be setting it for some purpose. Trust us: it's worthwhile taking tiny opportunities like this to help yourself. Let’s see how our light switch works. We trap the ``SwitchOn`` and -``SwitchOff`` actions in the ``after`` property (when the switching has -successfully taken place) and use them to give ``light`` to the light +``SwitchOff`` actions in the :prop:`after` property (when the switching has +successfully taken place) and use them to give :attr:`light` to the light switch. Uh, wait. To the light switch? Why not to the toilet room? Well, there's a reason and we'll see it in a minute. For now, just remember that, in order for players to see their surroundings, you need only one object in -a room with the ``light`` attribute set. It doesn't have to be the room +a room with the :attr:`light` attribute set. It doesn't have to be the room itself (though this is usually convenient). -After setting the ``light`` attribute, we display a customised message, +After setting the :attr:`light` attribute, we display a customised message, to avoid the default: .. code-block:: transcript @@ -289,9 +289,9 @@ to avoid the default: which, given the name of the object, doesn't read very elegantly. We foresee that players might try to PUSH SWITCH, so we trap this attempt -in a ``before`` property and redirect it to ``SwitchOn`` and +in a :prop:`before` property and redirect it to ``SwitchOn`` and ``SwitchOff`` actions, checking first which one is needed by testing the -``on`` attribute. Finally, we have made the switch a member of the class +:attr:`on` attribute. Finally, we have made the switch a member of the class ``Appliance``, so that the player doesn't walk away with it. .. note:: @@ -336,7 +336,7 @@ suffice: ], -And this is the reason why the light switch didn't set the ``light`` +And this is the reason why the light switch didn't set the :attr:`light` attribute of the toilet room, but did it to itself. We avoid running into trouble if we let the open/closed states of the door control the light of the room object, and the on/off states of the switch control @@ -347,7 +347,7 @@ players are never aware of this glowing artefact. Now, could they? Well, if players could TAKE the light switch (which we have forbidden) and then did INVENTORY, the trick would be given - away, because all objects with the ``light`` attribute set are listed + away, because all objects with the :attr:`light` attribute set are listed as ``(providing light)`` . So the player walks into the toilet and @@ -442,13 +442,13 @@ to remind us of what they represent), ``person`` , and then we make a complex test to see if the player is actually in the toilet and in the dark. -We have told you that the library variable ``location`` holds the +We have told you that the library variable :var:`location` holds the current room that the player is in. However, when there is no light, the variable location gets assigned to the value of the special library object thedark . It doesn't matter if we have ten dark rooms in our game; location will be equal to thedark in all of them. There is yet -another variable, called ``real_location``, which holds the room the +another variable, called :var:`real_location`, which holds the room the player is in *even when there is no light to see by*. So the test: @@ -457,7 +457,7 @@ So the test: if (person == player && location == thedark && real_location == toilet) ... -is stating: if the specified actor is the ``player`` character *and* he +is stating: if the specified actor is the :var:`player` character *and* he finds himself in the dark *and* he actually happens to be in the toilet... @@ -467,7 +467,7 @@ 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 +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: @@ -513,10 +513,10 @@ recover them (maybe going on all fours and groping a little, but it’s a possible action). We don’t want the player to have other objects in scope (like the coin, for instance), so it might be good to have a way of testing if the objects have been touched and carried by the player. -The attribute ``moved`` is perfect for this. The library sets it for +The attribute :attr:`moved` is perfect for this. The library sets it for every object that the player has picked up at one time in the game; -``scenery`` and ``static`` objects, and those we have not yet seen don't -have ``moved``. Here is the reworked ``InScope`` routine. There are a +:attr:`scenery` and :attr:`static` objects, and those we have not yet seen don't +have :attr:`moved`. Here is the reworked ``InScope`` routine. There are a couple of new concepts to look at: .. code-block:: inform @@ -564,7 +564,7 @@ What is the actual :samp:`{statement}` that we'll repeatedly execute? PlaceInScope(item); The test: ``if (item has moved)`` ensures that ``PlaceInScope(item)`` -deals only with objects with the ``moved`` attribute set. So: if the +deals only with objects with the :attr:`moved` attribute set. So: if the player is in the dark, let’s go through the objects which are in the same room, one at a time. For each of them, check if it's an item that the player has at some time carried, in which case, place it in scope. @@ -656,7 +656,7 @@ expect them to try this almost anywhere; but first of all we have to check that the ``clothes`` object is actually being worn. If not, we display a message reminding the player that this action has become irrelevant. What we do with the ``switch`` statement is to offer a -variety of responses according to the ``location`` variable. The street +variety of responses according to the :var:`location` variable. The street (in or out of the booth) and the café all display refusals of some kind, until the player character manages to enter the toilet, where we additionally require that he locks the door before taking off his @@ -664,13 +664,13 @@ clothes. If the door is closed but not locked, he is interrupted in his naked state by a nervous woman who starts shouting, and the game is lost (this is not as unfair as it seems, because the player may always revert to the previous state with UNDO). If the door is locked, he succeeds in -his transformation (we take away the ``worn`` attribute from the +his transformation (we take away the :attr:`worn` attribute from the ``clothes`` and give it to the ``costume`` instead). We add a special refusal to change in the dark, forcing players to turn on the light and then, we hope, to find the coin. And finally we code a ``default`` entry; you'll remember that, in a ``switch`` statement, this is supposed to cater for any value not explicitly listed for the expression under -control -- in this case, for the variable ``location``. Since we have +control -- in this case, for the variable :var:`location`. Since we have already gone through all the possible locations of the game, this entry appears only as a defensive measure, just in case something unexpected happens (for instance, we might extend the game with another room and @@ -781,13 +781,13 @@ two states display, respectively, *** You have won *** -These states correspond to the values of the ``deadflag`` variable: 1 +These states correspond to the values of the :var:`deadflag` variable: 1 for losing, 2 for winning. However, we have made up different messages, because our hero does not really die -- ours suffers a FATE worse than death -- and because we want to give him a more descriptive winning line. Therefore, we must define a ``DeathMessage`` routine as we did in "William Tell", to write our customised messages and assign them to -``deadflag`` values greater than 2. +:var:`deadflag` values greater than 2. .. code-block:: inform @@ -852,10 +852,10 @@ Not so. The library grammar that deals with ASK BENNY FOR... is this * creature 'about' topic -> Ask * creature 'for' noun -> AskFor -You'll see the ``noun`` token, which means that whatever the player asks +You'll see the :var:`noun` token, which means that whatever the player asks him for must be a real game object, visible at that moment. Assuming that the player mentions such an object, the interpreter finds it in the -dictionary and places its internal ID in the ``noun`` variable, where +dictionary and places its internal ID in the :var:`noun` variable, where our ``switch`` statement can handle it. So, ASK BENNY FOR KEY assigns the ``toilet_key`` object to the noun variable, and Benny responds. ASK BENNY FOR CUSTOMERS also works; the ``default`` case picks that one up. diff --git a/chapters/14.rst b/chapters/14.rst index aed53b3..9a62a74 100644 --- a/chapters/14.rst +++ b/chapters/14.rst @@ -307,7 +307,7 @@ Properties ---------- The library defines around forty-eight standard property variables (such -as ``before`` or ``name``), but you can readily create further ones just +as :prop:`before` or :prop:`name`), but you can readily create further ones just by using them within an object definition. You can create and initialise a property in an object's ``with`` segment: @@ -366,6 +366,9 @@ and are usually called automatically by the library, or manually by:: obj_id.property() ! everywhere +.. index:: + single: arguments (of a routine) + Arguments and local variables ----------------------------- @@ -405,11 +408,11 @@ or implicitly when the routine runs out of statements. If none of these [ routine_id; statement; statement; ... statement; ]; -returns ``true`` and :: +returns :const:`true` and :: property [; statement; statement; ... statement; ] -return ``false``. +return :const:`false`. This difference is *important*. Remember it by the letter pairs STEF: left to themselves, Standalone routines return True, Embedded routines @@ -608,7 +611,7 @@ you'll come across. if (MyVar) ... Note that the following statement specifically tests whether ``MyVar`` - contains ``true`` (1), *not* whether its value is anything other than + contains :const:`true` (1), *not* whether its value is anything other than zero. :: if (MyVar == true) ... @@ -660,8 +663,8 @@ you'll come across. "number" property and "general" attribute ----------------------------------------- -The library defines a standard ``number`` property and a standard -``general`` attribute, whose roles are undefined: they are +The library defines a standard :prop:`number` property and a standard +:attr:`general` attribute, whose roles are undefined: they are general-purpose variables available within every object to designers as and when they desire. @@ -707,8 +710,8 @@ within the overall object tree either by explicitly mentioning its parent's ``obj_id`` (if any) in the first line of the object definition -- what we've been calling the header information -- or, for a few 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 +:prop:`found_in` properties. For example, in "William Tell" we defined +twenty-seven objects; omitting those which used :prop:`found_in` to define their placement at the start of the game, we're left with object definitions starting like this:: diff --git a/chapters/15.rst b/chapters/15.rst index ae0eff2..491720a 100644 --- a/chapters/15.rst +++ b/chapters/15.rst @@ -124,7 +124,7 @@ punctuation is missing:: In fact, there's nothing wrong with the ordering or punctuation. The problem is actually that we've tried to define a new object with an -internal ID of ``door`` -- reasonably enough, you might think, since the +internal ID of :attr:`door` -- reasonably enough, you might think, since the object *is* a door -- but Inform already knows the word (it's the name of a library attribute). Unfortunately, the error message provides only the vaguest hint that you just need to choose another name: we used diff --git a/chapters/16.rst b/chapters/16.rst index a255484..702a594 100644 --- a/chapters/16.rst +++ b/chapters/16.rst @@ -272,7 +272,7 @@ PURLOIN *object* matter where the object is: in another room, inside a locked container, in the claws of the bloodthirsty dragon. More dangerously, it doesn't matter if the object is takeable, so you may purloin - ``static`` or ``scenery`` objects. PURLOIN is useful in a variety of + :attr:`static` or :attr:`scenery` objects. PURLOIN is useful in a variety of situations, basically when you want to test a particular feature of the game that requires the player character to have some objects handy. Instead of tediously collecting them, you may simply PURLOIN @@ -284,7 +284,7 @@ ABSTRACT *object* TO *object* This verb enables you to move the first *object* to the second *object*. As with PURLOIN , both objects can be anywhere in the game. Bear in mind that the second object should logically be a - ``container``, a ``supporter`` , or something ``animate``. + :attr:`container`, a :attr:`supporter` , or something :attr:`animate`. Infix: the harlot's prerogative @@ -317,8 +317,8 @@ inspect -- and change -- a variable: In that game you scored 0 out of a possible 2, in 2 turns. It's often quite maddening to realise that some variable is still -``false`` because the Chalk puzzle didn't work properly, and that you -can't test the Cheese puzzle until the variable becomes ``true``. Rather +:const:`false` because the Chalk puzzle didn't work properly, and that you +can't test the Cheese puzzle until the variable becomes :const:`true`. Rather than quit, fix the Chalk, recompile, play back to the current position and only *then* tackle the Cheese, how much easier to just change the variable in mid-stream, and carry right on. diff --git a/conf.py b/conf.py index a83caf6..d7cd39c 100644 --- a/conf.py +++ b/conf.py @@ -137,6 +137,9 @@ highlight_language = 'none' # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True +# Turn off default domain. +primary_domain = None + # -- Options for HTML output ---------------------------------------------- diff --git a/config/defs.rst b/config/defs.rst index f55f649..a66a585 100644 --- a/config/defs.rst +++ b/config/defs.rst @@ -43,3 +43,23 @@ .. |X| replace:: :latex:`\dropcap{x}` .. |Y| replace:: :latex:`\dropcap{y}` .. |Z| replace:: :latex:`\dropcap{z}` + +.. Inform language roles. + +.. role:: var(code) + :class: nv + +.. role:: const(code) + :class: kc + +.. role:: obj(code) + :class: vg + +.. role:: act(code) + :class: na + +.. role:: prop(code) + :class: nb + +.. role:: attr(code) + :class: na -- 2.31.1