<ulclass="crumbs"><li><ahref="../webs.html">Source</a></li><li><ahref="../extensions.html">Kits</a></li><li><ahref="index.html">WorldModelKit</a></li><li><b>Output Template</b></li></ul><pclass="purpose">This is the superstructure of the file of I6 code output by NI: from ICL commands at the top down to the signing-off comments at the bottom.</p>
<ulclass="toc"><li><ahref="#SP1">§1. ICL Commands</a></li><li><ahref="#SP2">§2. Identification</a></li><li><ahref="#SP3">§3. Constants</a></li><li><ahref="#SP4">§4. Global Variables</a></li><li><ahref="#SP5">§5. Compass</a></li><li><ahref="#SP6">§6. Score and Rankings Table</a></li><li><ahref="#SP7">§7. The Old Library</a></li><li><ahref="#SP8">§8. Parser</a></li><li><ahref="#SP9">§9. Order of Play</a></li><li><ahref="#SP10">§10. Activities</a></li><li><ahref="#SP11">§11. Object Tree</a></li><li><ahref="#SP12">§12. Tables</a></li><li><ahref="#SP13">§13. Equations</a></li><li><ahref="#SP14">§14. Actions</a></li><li><ahref="#SP15">§15. Phrases</a></li><li><ahref="#SP16">§16. Rulebooks</a></li><li><ahref="#SP17">§17. Scenes</a></li><li><ahref="#SP18">§18. The New Library</a></li><li><ahref="#SP19">§19. Parsing Tokens</a></li><li><ahref="#SP20">§20. Text generation</a></li><li><ahref="#SP21">§21. Testing commands</a></li><li><ahref="#SP22">§22. I6 Inclusions</a></li><li><ahref="#SP23">§23. Entries in constant lists</a></li><li><ahref="#SP24">§24. To Phrases</a></li><li><ahref="#SP25">§25. Chronology</a></li><li><ahref="#SP26">§26. Grammar</a></li><li><ahref="#SP27">§27. Deferred Propositions</a></li><li><ahref="#SP28">§28. Miscellaneous Loose Ends</a></li><li><ahref="#SP29">§29. Block Values</a></li></ul><hrclass="tocbar">
<pclass="inwebparagraph"><aid="SP4"></a><b>§4. Global Variables. </b>These are not the only global variables defined in the template layer:
those needed locally only by single sections (and not used in definitions
of phrases in the Standard Rules, or referred to by NI directly) are defined
within those sections — they can be regarded as unimportant implementation
details, subject to change at whim. The variables here, on the other hand,
are more important to understand.
</p>
<pclass="inwebparagraph"></p>
<ulclass="items"><li>(1) The first three variables to be defined are special in that they are
significant to very early-style Z-machine interpreters, where they are
used to produce the status line display (hence <codeclass="display"><spanclass="extract">sline1</span></code> and <codeclass="display"><spanclass="extract">sline2</span></code>).
The first variable must always equal a valid object number, which is why
we — pretty weirdly — set it equal to the placeholder object <codeclass="display"><spanclass="extract">InformLibrary</span></code>,
which takes no part in play, and is not a valid I7 object. This is not
typesafe in I7 terms, but that doesn't matter because initialisation
will correct it to a typesafe value before any I7 source text can execute.
(<codeclass="display"><spanclass="extract">sline1</span></code> and <codeclass="display"><spanclass="extract">sline2</span></code> are entirely unused on when we target Glulx.)
Once these variables are defined, the sequence of definition of the rest
is not significant.
</li></ul>
<ulclass="items"><li>(2) The <codeclass="display"><spanclass="extract">say__*</span></code> are used for the finite state machine used in printing
text, which keeps track of automatic paragraph breaking and the like. For
details see the "Printing.i6t" section.
</li></ul>
<ulclass="items"><li>(3) <codeclass="display"><spanclass="extract">standard_interpreter</span></code> is used only for the Z-machine VM, and is always
0 for Glulx. For Z, a non-zero value here is the version number of the
Z-Machine Standards Document which the interpreter claims to support,
in the form (upper byte).(lower). <codeclass="display"><spanclass="extract">undo_flag</span></code>, similarly, behaves slightly
differently on the two platforms according to whether they support multiple
consecutive UNDOs. UNDO basically works by taking memory snapshots of the
whole VM ("saving UNDO") to revert to at a later point ("performing UNDO"),
so it is expensive on memory, and traditional VMs can only store a single
memory snapshot — making two UNDOs in a row, going back two steps,
impossible. Given this, <codeclass="display"><spanclass="extract">undo_flag</span></code> has three possible states: 0 means
UNDO is not available at all, 1 means it is not available now because
there is no further saved state to go back to from here, and 2 means it
is available.
</li></ul>
<ulclass="items"><li>(4) <codeclass="display"><spanclass="extract">deadflag</span></code> in normally 0, or false, meaning play continues; 1 means the
game ended in death; 2 for ended in victory; higher numbers represent
exotic endings. (As from May 2010, the use of 2 for victory is deprecated,
and a separate flag, <codeclass="display"><spanclass="extract">story_complete</span></code>, records whether the story is
"complete" in the sense that we don't expect the player to replay.)
<codeclass="display"><spanclass="extract">deadflag</span></code> switching state normally triggers an end to rulebook processing,
so is the single most important global variable to the running of a story
file.
</li></ul>
<ulclass="items"><li>(5) At present, <codeclass="display"><spanclass="extract">time_rate</span></code> is not made use of in I7: if positive, it is
the number of minutes which pass each turn; if negative, the number of
turns which pass each minute. This is quite a neat way to approximate a
wide range of time steps with an integer such that fractions are exact
and we can approximate any duration to a fair accuracy (the worst case
being 3/4 minute, where we have to choose between 1 minute or 1/2
minute).
</li></ul>
<ulclass="items"><li>(6) Note that <codeclass="display"><spanclass="extract">notify_mode</span></code> is irrelevant if the use option "Use no scoring"
is in force: it isn't looked at, and can't be changed, and shouldn't have
an effect anyway since <codeclass="display"><spanclass="extract">score</span></code> will never be altered.
</li></ul>
<ulclass="items"><li>(7) <codeclass="display"><spanclass="extract">player</span></code> is a variable, not a constant, since the focus of play can
change. <codeclass="display"><spanclass="extract">SACK_OBJECT</span></code> is likewise an unexpected variable: in the I6
library, there could only be one player's holdall, a single rucksack-like
possession which had to be the value of the constant <codeclass="display"><spanclass="extract">SACK_OBJECT</span></code>. Here we
define <codeclass="display"><spanclass="extract">SACK_OBJECT</span></code> as a global variable instead, the value of which is
the player's holdall currently in use. <codeclass="display"><spanclass="extract">visibility_ceiling</span></code> is the
highest object in the tree visible from the player's point of view:
usually the room, but sometimes nothing (in darkness), and sometimes a
closed non-transparent container.
</li></ul>
<ulclass="items"><li>(8) See "OrderOfPlay.i6t" for the meaning of action variables.
</li></ul>
<ulclass="items"><li>(9) This is a slate of global variables used by the parser to give some
context to the general parsing routines (GPRs) which it calls; in the I6
design, any object can provide its own GPR, in the form of a <codeclass="display"><spanclass="extract">parse_name</span></code>
property. GPRs are in effect parser plug-ins, and I7 makes extensive use
of them.
</li></ul>
<ulclass="items"><li>(10) Similarly, variables for the parser to give context to another sort
of plug-in routine: a scope filter. I7 uses these too.
</li></ul>
<ulclass="items"><li>(11) The <codeclass="display"><spanclass="extract">move_*</span></code> variables are specific to the <codeclass="display"><spanclass="extract">##Going</span></code> action.
</li></ul>
<ulclass="items"><li>(12) These variables hold current settings for listing objects and,
more elaborately, performing room descriptions.
</li></ul>
<ulclass="items"><li>(13) The current colour scheme is stored in variables in order that it can
be saved in the save game state, and changed correctly on an UNDO: if it
were a transient state inside the VM interpreter's screen model, then a
RESTORE or UNDO will upset what the original author may have intended the
appearance of text in particular scenes to be. (Cf. Adam Cadre's I6 patch
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">location</span><spanclass="plain"> = </span><spanclass="identifier">InformLibrary</span><spanclass="plain">; </span><spanclass="comment">does not = I7 "location": see below</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">not_yet_in_play</span><spanclass="plain"> = </span><spanclass="reserved">true</span><spanclass="plain">; </span><spanclass="comment">set false when first command received</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">notify_mode</span><spanclass="plain"> = </span><spanclass="constant">1</span><spanclass="plain">; </span><spanclass="comment">score notification on or off</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">left_hand_status_line</span><spanclass="plain"> = </span><spanclass="identifier">T_SL_Location</span><spanclass="plain">; </span><spanclass="comment">= I7 "left hand status line"</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">right_hand_status_line</span><spanclass="plain"> = </span><spanclass="identifier">T_SL_Score_Moves</span><spanclass="plain">; </span><spanclass="comment">= I7 "right hand status line"</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">visibility_ceiling</span><spanclass="plain">; </span><spanclass="comment">highest object in tree visible to player</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">visibility_levels</span><spanclass="plain">; </span><spanclass="comment">distance in tree to that</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">SACK_OBJECT</span><spanclass="plain">; </span><spanclass="comment">current player's holdall item in use</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">actors_location</span><spanclass="plain">; </span><spanclass="comment">like real_location, but for the actor</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">meta</span><spanclass="plain">; </span><spanclass="comment">action is out of world</span>
<spanclass="reserved">Array</span><spanclass="plain"></span><spanclass="identifier">multiple_object</span><spanclass="plain"> --></span><spanclass="identifier">MATCH_LIST_WORDS</span><spanclass="plain">; </span><spanclass="comment">multiple-object list (I6 table array)</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">toomany_flag</span><spanclass="plain">; </span><spanclass="comment">multiple-object list overflowed</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">multiflag</span><spanclass="plain">; </span><spanclass="comment">multiple-object being processed</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">multiple_object_item</span><spanclass="plain">; </span><spanclass="comment">item currently being processed in multiple-object list</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">keep_silent</span><spanclass="plain">; </span><spanclass="comment">true if current action is being tried silently</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">etype</span><spanclass="plain">; </span><spanclass="comment">parser error number if command not recognised</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">special_word</span><spanclass="plain">; </span><spanclass="comment">dictionary address of first word in "[text]" token</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">consult_from</span><spanclass="plain">; </span><spanclass="comment">word number of start of "[text]" token</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">consult_words</span><spanclass="plain">; </span><spanclass="comment">number of words in "[text]" token</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">parsed_number</span><spanclass="plain">; </span><spanclass="comment">value from any token not an object</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">special_number1</span><spanclass="plain">; </span><spanclass="comment">first value, if token not an object</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">special_number2</span><spanclass="plain">; </span><spanclass="comment">second value, if token not an object</span>
<spanclass="reserved">Array</span><spanclass="plain"></span><spanclass="identifier">parser_results</span><spanclass="plain"> --></span><spanclass="constant">16</span><spanclass="plain">; </span><spanclass="comment">for parser to write its results in</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">parser_trace</span><spanclass="plain"> = </span><spanclass="constant">0</span><spanclass="plain">; </span><spanclass="comment">normally 0, but 1 to 5 traces parser workings</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">pronoun_word</span><spanclass="plain">; </span><spanclass="comment">records which pronoun ("it", "them", ...) caused an error</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">pronoun_obj</span><spanclass="plain">; </span><spanclass="comment">and what object it was thought to refer to</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">understand_as_mistake_number</span><spanclass="plain">; </span><spanclass="comment">which form of "Understand... as a mistake"</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">parser_action</span><spanclass="plain">; </span><spanclass="comment">written by the parser for the benefit of GPRs</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">parameters</span><spanclass="plain">; </span><spanclass="comment">number of I7 tokens parsed on the current line</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">action_to_be</span><spanclass="plain">; </span><spanclass="comment">(if the current line were accepted)</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">action_reversed</span><spanclass="plain">; </span><spanclass="comment">(parameters would be reversed in order)</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">wn</span><spanclass="plain">; </span><spanclass="comment">word number within "parse" buffer (from 1)</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">num_words</span><spanclass="plain">; </span><spanclass="comment">number of words in buffer</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">verb_word</span><spanclass="plain">; </span><spanclass="comment">dictionary address of command verb</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">verb_wordnum</span><spanclass="plain">; </span><spanclass="comment">word number of command verb</span>
<spanclass="comment">[10]</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">scope_reason</span><spanclass="plain"> = </span><spanclass="identifier">PARSING_REASON</span><spanclass="plain">; </span><spanclass="comment">current reason for searching scope</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">scope_stage</span><spanclass="plain">; </span><spanclass="comment">1, 2 then 3</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">advance_warning</span><spanclass="plain">; </span><spanclass="comment">what a later-named thing will be</span>
<spanclass="plain">! </span><spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">reason_code</span><spanclass="plain"> = </span><spanclass="identifier">NULL</span><spanclass="plain">; </span><spanclass="comment">for the I6 veneer</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">lt_value</span><spanclass="plain"> = </span><spanclass="identifier">EMPTY_TEXT_VALUE</span><spanclass="plain">; </span><spanclass="comment">common value of list_together</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">listing_together</span><spanclass="plain">; </span><spanclass="comment">object number of one member of a group being listed together</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">listing_size</span><spanclass="plain">; </span><spanclass="comment">size of such a group</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">c_margin</span><spanclass="plain">; </span><spanclass="comment">current level of indentation printed by WriteListFrom()</span>
<spanclass="identifier">Global</span><spanclass="plain"></span><spanclass="identifier">inventory_stage</span><spanclass="plain"> = </span><spanclass="constant">1</span><spanclass="plain">; </span><spanclass="comment">1 or 2 according to the context in which list_together uses</span>
<pclass="inwebparagraph"><aid="SP5"></a><b>§5. Compass. </b>I6 identified compass directions as being children of the pseudo-object
<codeclass="display"><spanclass="extract">Compass</span></code>, so we define it. (Note that <codeclass="display"><spanclass="extract">Compass</span></code> is not a valid I7 object,
and is used for no other purpose.) Because of the traditional structure
of language definitions, this needs to come first.
<pclass="inwebparagraph"><aid="SP6"></a><b>§6. Score and Rankings Table. </b>The following command tells NI to compile constant definitions for <codeclass="display"><spanclass="extract">INITIAL_MAX_SCORE</span></code>
and/or <codeclass="display"><spanclass="extract">RANKING_TABLE</span></code>, in cases where there are scores and rankings. If there's
no ranking table, <codeclass="display"><spanclass="extract">RANKING_TABLE</span></code> is left undefined, so that we can <codeclass="display"><spanclass="extract">#ifdef</span></code> this
<pclass="inwebparagraph">The two pseudo-objects <codeclass="display"><spanclass="extract">InformParser</span></code> and <codeclass="display"><spanclass="extract">InformLibrary</span></code> are relics of the
object-oriented approach in I6, and are used only very slightly in the
template layer; they are not used at all in I7, and are not valid for the
"object" kind of value.
</p>
<pclass="inwebparagraph">The parser includes arrays for typed text and some parsing information
derived from it, and if these should overrun it would cause enigmatic
bugs, as the next arrays in memory would be corrupted: as a tripwire,
the <codeclass="display"><spanclass="extract">Protect_I7_Arrays</span></code> array consists of two magic values in sequence.
If it is ever discovered to contain the wrong data, the alarm sounds.
<pclass="inwebparagraph"><aid="SP9"></a><b>§9. Order of Play. </b>The <codeclass="display"><spanclass="extract">Main</span></code> routine, where execution begins, and the primitive rules in the
<pclass="inwebparagraph"><aid="SP11"></a><b>§11. Object Tree. </b>The I6 object tree contains <codeclass="display"><spanclass="extract">Class</span></code> definitions as well as objects, but
<pclass="inwebparagraph"><aid="SP18"></a><b>§18. The New Library. </b>The gleaming, aluminium and glass extension to the library: almost all of it
<pclass="inwebparagraph"><aid="SP23"></a><b>§23. Entries in constant lists. </b>Well: most of them, anyway. In particular, all of those which are lists of
<ulclass="items"><li>(1) Routines which switch between possible interpretations of phrases
by performing run-time type checking. (Note that these cannot involve
grammar, or the past tenses, or text substitutions, or deferred propositions.)
</li></ul>
<ulclass="items"><li>(2) Arrays holding constant lists, such as <codeclass="display"><spanclass="extract">{2, 3, 4}</span></code>, if any.
</li></ul>
<ulclass="items"><li>(3) The string constants, named in the pattern <codeclass="display"><spanclass="extract">SC_*</span></code>, in alphabetical order.
(This ensures that their packed addresses will have unsigned comparison
ordering equivalent to alphabetical order.)
</li></ul>
<ulclass="items"><li>(4) "Stub" I6 constants for property names where properties aren't used,
to prevent them causing errors if they are referred to in code but not
actually present in any object (as can easily happen with extensions
presenting optional features which the user chooses not to employ).
</li></ul>
<ulclass="items"><li>(5) Counters are used to allocate cells of storage to inline phrases which
need a permanent state associated with them: see the Standard Rules. Since
all I7 source text has been compiled by now, we know the final values of
the counters, and therefore the amount of storage we need to allocate.
</li></ul>
<ulclass="items"><li>(6) Similarly, each "quotation" box needs its own cell of memory.