>
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.
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)::
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.
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:
| `...`
| `];`
-`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`,
`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
<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:
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 <group-2-actions>`, 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}` -
| -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
=================
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}(); ]`
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.
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
* 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
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:
`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
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
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
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
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
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
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)
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::
* 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:
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.
(``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.
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
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
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
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:
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
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
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 [; ... ],
``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!"
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`).
...
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
...
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
-----------------
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.",
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',
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;
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::
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::
>
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
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
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
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
],
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
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
: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
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 [; ... ],
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;
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.
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
==========
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.",
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::
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:
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
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
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;
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.";
...
-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
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
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:
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"
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::
],
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:
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::
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"::
...
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
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 [;
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::
"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.
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.
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)
~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
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
: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',
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',
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::
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;
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
===============================
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
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: <Examine stall>; 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: <<Examine self>>; ],
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::
<<Look>>;
],
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::
],
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:
>
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... "):
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?
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
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
========================
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;
* - ``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
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:
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
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
],
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.
: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::
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";
...
];
-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
],
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
``<<FireAt tree bow>>`` -- 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:
* 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.
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."; ];
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;
];
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
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
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
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.
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
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
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
],
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).
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
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
#. 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"
* 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."; ];
#. 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.
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
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.
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'
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
#. 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...
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::
}
],
-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
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,
statement instead.
You'll notice that -- unusually for a room -- our ``street`` object has
-a ``name`` property:
+a :prop:`name` property:
.. code-block:: inform
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
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
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
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
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:
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:
],
has enterable proper;
+.. index:: accented characters
+
.. note::
Although the text of our guide calls Benny's establishment a "café" --
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
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
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
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.
],
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::
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
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
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:
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
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.
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é.
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
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.
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).
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
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
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
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.
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
"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
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
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.
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
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
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:
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
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
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:
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
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
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
}
],
-* 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.
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
* **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
``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
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.
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
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.
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,
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
],
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:
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:
give self ~on;
-and check if a ``switchable`` object is on or off with the test:
+and check if a :attr:`switchable` object is on or off with the test:
.. code-block:: inform
if (light_switch hasnt on) ...
-A ``switchable`` object is OFF by default. However, you’ll notice that
+A :attr:`switchable` object is OFF by default. However, you’ll notice that
the has line of the object definition includes ``~on`` :
.. code-block:: inform
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
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::
],
-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
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
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:
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...
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:
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
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.
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
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
*** 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
* 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.
----------
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:
obj_id.property() ! everywhere
+.. index::
+ single: arguments (of a routine)
+
Arguments and local variables
-----------------------------
[ 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
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) ...
"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.
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::
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
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
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
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.
# 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 ----------------------------------------------
.. |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