1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-04-29 23:59:35 +03:00

Tidied documentation ahead of release

This commit is contained in:
Graham Nelson 2022-08-18 21:52:01 +01:00
parent a483ffee60
commit 7c54b99361
14 changed files with 95 additions and 209 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
[Version](notes/versioning.md): 10.1.0-beta+6V42 'Krypton' (17 August 2022)
[Version](notes/versioning.md): 10.1.0-beta+6V43 'Krypton' (18 August 2022)
## About Inform

View file

@ -1,3 +1,3 @@
Prerelease: beta
Build Date: 17 August 2022
Build Number: 6V42
Build Date: 18 August 2022
Build Number: 6V43

View file

@ -366,7 +366,8 @@ have occurred, but if it does then the creation has worked.
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dbtr.html#SP4_1_3_2" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for trying to create an existing kind as a new instance</span><span class="named-paragraph-number">4.1.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">evaluation</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">evaluation</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dbtr.html#SP4_1_3_3" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for trying to create any existing meaning as a new instance</span><span class="named-paragraph-number">4.1.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K_direction</span><span class="plain-syntax">) &amp;&amp; (</span><span class="function-syntax">&lt;notable-map-noun-phrases&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">NW</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dbtr.html#SP4_1_3_4" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for trying to create above or below as a new instance</span><span class="named-paragraph-number">4.1.3.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-tc.html#SP4" class="function-link"><span class="function-syntax">Assertions::Creator::tabular_definitions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NounPhrases::annotate_by_articles</span><span class="plain-syntax">(</span><span class="identifier-syntax">name_entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ProblemBuffer::redirect_problem_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">, </span><span class="identifier-syntax">name_entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">);</span>
@ -383,7 +384,7 @@ have occurred, but if it does then the creation has worked.
<span class="plain-syntax"> </span><a href="4-tc.html#SP4" class="function-link"><span class="function-syntax">Assertions::Creator::tabular_definitions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">name_entry</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dbtr.html#SP4_1_3_4" class="named-paragraph-link"><span class="named-paragraph">Issue a problem to say that the creation failed</span><span class="named-paragraph-number">4.1.3.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dbtr.html#SP4_1_3_5" class="named-paragraph-link"><span class="named-paragraph">Issue a problem to say that the creation failed</span><span class="named-paragraph-number">4.1.3.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">objections</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
@ -444,7 +445,25 @@ of the contents.)
<span class="plain-syntax"> </span><span class="identifier-syntax">objections</span><span class="plain-syntax">++; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dbtr.html#SP4_1_3">&#167;4.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1_3_4" class="paragraph-anchor"></a><b>&#167;4.1.3.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem to say that the creation failed</span><span class="named-paragraph-number">4.1.3.4</span></span><span class="comment-syntax"> =</span>
<p class="commentary firstcommentary"><a id="SP4_1_3_4" class="paragraph-anchor"></a><b>&#167;4.1.3.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem for trying to create above or below as a new instance</span><span class="named-paragraph-number">4.1.3.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">name_entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind_of</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">evaluation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_number</span><span class="plain-syntax">(5, &amp;</span><span class="identifier-syntax">row_count</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TableCreatedMapClash</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, and row %5 of the first column of that table is %2, which "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"I ought to create as a new value of %4. But I can't do that: it already "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"has a meaning (it refers to a map direction)."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">objections</span><span class="plain-syntax">++; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dbtr.html#SP4_1_3">&#167;4.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4_1_3_5" class="paragraph-anchor"></a><b>&#167;4.1.3.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem to say that the creation failed</span><span class="named-paragraph-number">4.1.3.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">

View file

@ -517,7 +517,10 @@ from the tree.
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"CREATED node without name"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> to recover from PM_TableDefiningNothing</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"CREATED node without name"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;grammatical-gender-marker&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;grammatical-gender-marker&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">explicit_gender_marker_ANNOT</span><span class="plain-syntax">, </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>

View file

@ -399,7 +399,7 @@ fractions: so for instance,
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> picture "backdrop/png" scale min 1/10 max 8/1</span>
</pre>
<p class="commentary">means"you can display this anywhere between one tenth normal size and
<p class="commentary">means "you can display this anywhere between one tenth normal size and
eight times normal size, but if possible it ought to be just its normal
size".
</p>

View file

@ -127,7 +127,7 @@ otherwise.
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>There is an expression grammar here, which we apply correctly if the
condition is well-formed; if it"s a mess, we try to return 0, but don"t go
condition is well-formed; if it's a mess, we try to return 0, but don't go
to any trouble to report errors.
</p>

View file

@ -102,7 +102,7 @@ we produce. It will be called <span class="extract"><span class="extract-syntax"
would then be <span class="extract"><span class="extract-syntax">images/orange.png</span></span>.
</p>
<p class="commentary">However, it"s also possible that the book"s instructions tell us to use
<p class="commentary">However, it's also possible that the book's instructions tell us to use
images from an already-existing location instead.
</p>

View file

@ -593,7 +593,7 @@ see below.
<span class="plain-syntax"> {*}A ball is in the bag.</span>
<span class="plain-syntax"> The bag is on the kitchen table.</span>
<span class="plain-syntax"> This single sentence doesn"t make much of a simulation. Let"s add:</span>
<span class="plain-syntax"> This single sentence doesn't make much of a simulation. Let's add:</span>
<span class="plain-syntax"> {**}The stitched seam is part of the ball.</span>
</pre>

View file

@ -305,7 +305,7 @@ property <span class="extract"><span class="extract-syntax">prn</span></span>:
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>And this is a variant which does not inherit: e.g. if the kind "bird" has
the property "flightless" but Orville, an individual instance of"bird" has no
the property "flightless" but Orville, an individual instance of "bird" has no
inference about this property, then we would return <span class="extract"><span class="extract-syntax">LIKELY_CE</span></span> if asked about
"bird", but <span class="extract"><span class="extract-syntax">UNKNOWN_CE</span></span> if asked Orville. The previous function would return
<span class="extract"><span class="extract-syntax">LIKELY_CE</span></span> to both because Orville ordinarily inherits from his kind.

View file

@ -1,34 +1,34 @@
Total memory consumption was 123356K = 120 MB
Total memory consumption was 121176K = 118 MB
---- was used for 2049632 objects, in 364585 frames in 0 x 800K = 0K = 0 MB:
33.1% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes
20.6% text_stream_array 4632 x 100 = 463200 objects, 26087424 bytes
19.4% linked_list 43887 objects, 24576720 bytes
11.1% inter_symbol_array 132 x 1024 = 135168 objects, 14061696 bytes
10.4% inter_error_stash_array 101 x 1024 = 103424 objects, 13241504 bytes
8.2% parse_node 129712 objects, 10376960 bytes
5.8% verb_conjugation 160 objects, 7425280 bytes
4.3% parse_node_annotation_array 346 x 500 = 173000 objects, 5547072 bytes
2.6% pcalc_prop_array 25 x 1000 = 25000 objects, 3400800 bytes
33.6% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes
21.0% text_stream_array 4632 x 100 = 463200 objects, 26087424 bytes
19.8% linked_list 43887 objects, 24576720 bytes
11.3% inter_symbol_array 132 x 1024 = 135168 objects, 14061696 bytes
10.6% inter_error_stash_array 101 x 1024 = 103424 objects, 13241504 bytes
8.3% parse_node 129712 objects, 10376960 bytes
5.9% verb_conjugation 160 objects, 7425280 bytes
4.4% parse_node_annotation_array 346 x 500 = 173000 objects, 5547072 bytes
2.7% pcalc_prop_array 25 x 1000 = 25000 objects, 3400800 bytes
2.5% inter_name_array 67 x 1000 = 67000 objects, 3218144 bytes
2.0% kind_array 66 x 1000 = 66000 objects, 2642112 bytes
2.1% kind_array 66 x 1000 = 66000 objects, 2642112 bytes
1.7% scan_directory 521 objects, 2150688 bytes
1.6% inter_name_generator_array 51 x 1000 = 51000 objects, 2041632 bytes
1.5% inter_schema_token 13964 objects, 2010816 bytes
1.4% package_request 21153 objects, 1861464 bytes
1.6% inter_schema_token 13964 objects, 2010816 bytes
1.5% package_request 21153 objects, 1861464 bytes
1.4% vocabulary_entry_array 161 x 100 = 16100 objects, 1808352 bytes
1.2% dict_entry_array 473 x 100 = 47300 objects, 1528736 bytes
1.1% match_trie_array 11 x 1000 = 11000 objects, 1496352 bytes
1.1% inter_symbols_table 26592 objects, 1489152 bytes
1.0% i6_schema_array 23 x 100 = 2300 objects, 1380736 bytes
1.2% match_trie_array 11 x 1000 = 11000 objects, 1496352 bytes
1.2% inter_symbols_table 26592 objects, 1489152 bytes
1.1% i6_schema_array 23 x 100 = 2300 objects, 1380736 bytes
1.0% inter_package 26592 objects, 1276416 bytes
0.8% map_data 671 objects, 1127280 bytes
0.9% map_data 671 objects, 1127280 bytes
0.8% id_body 942 objects, 1077648 bytes
0.7% adjective_meaning 202 objects, 1000304 bytes
0.8% adjective_meaning 202 objects, 1000304 bytes
0.7% excerpt_meaning 3109 objects, 970008 bytes
0.7% production 3878 objects, 899696 bytes
0.6% ptoken 8408 objects, 874432 bytes
0.7% ptoken 8408 objects, 874432 bytes
0.6% grammatical_usage 3613 objects, 867120 bytes
0.6% individual_form 2563 objects, 861168 bytes
0.6% inter_schema_node 8917 objects, 856032 bytes
@ -247,17 +247,17 @@ Total memory consumption was 123356K = 120 MB
100.0% was used for memory not allocated for objects:
57.6% text stream storage 72814012 bytes in 480631 claims
4.1% dictionary storage 5297152 bytes in 7590 claims
56.8% text stream storage 70581884 bytes in 480303 claims
4.2% dictionary storage 5297152 bytes in 7590 claims
---- sorting 1520 bytes in 159 claims
5.6% source text 7200000 bytes in 3 claims
8.5% source text details 10800000 bytes in 2 claims
5.8% source text 7200000 bytes in 3 claims
8.7% source text details 10800000 bytes in 2 claims
0.2% documentation fragments 262144 bytes in 1 claim
---- linguistic stock array 81920 bytes in 2 claims
---- small word set array 105600 bytes in 22 claims
3.6% inter symbols storage 4553008 bytes in 27952 claims
13.2% inter bytecode storage 16767568 bytes in 14 claims
4.9% inter links storage 6222976 bytes in 11 claims
13.5% inter bytecode storage 16767568 bytes in 14 claims
5.0% inter links storage 6222976 bytes in 11 claims
0.1% inter tree location list storage 191232 bytes in 32 claims
1.3% instance-of-kind counting 1700416 bytes in 1 claim
---- compilation workspace for objects 21896 bytes in 25 claims
@ -265,5 +265,5 @@ Total memory consumption was 123356K = 120 MB
---- code generation workspace for objects 1336 bytes in 4 claims
0.2% emitter array storage 280288 bytes in 1999 claims
-147.-2% was overhead - -185990064 bytes = -181630K = -177 MB
-149.-8% was overhead - -185990064 bytes = -181630K = -177 MB

View file

@ -1,32 +1,33 @@
100.0% in inform7 run
70.4% in compilation to Inter
49.8% in //Sequence::undertake_queued_tasks//
4.5% in //MajorNodes::pre_pass//
3.3% in //MajorNodes::pass_1//
2.0% in //RTPhrasebook::compile_entries//
1.8% in //ImperativeDefinitions::assess_all//
1.4% in //RTKindConstructors::compile//
71.4% in compilation to Inter
50.1% in //Sequence::undertake_queued_tasks//
4.8% in //MajorNodes::pre_pass//
3.8% in //MajorNodes::pass_1//
2.0% in //ImperativeDefinitions::assess_all//
1.6% in //RTKindConstructors::compile//
1.4% in //RTPhrasebook::compile_entries//
1.0% in //Sequence::lint_inter//
0.6% in //MajorNodes::pass_2//
0.6% in //World::stage_V//
0.4% in //ImperativeDefinitions::compile_first_block//
0.4% in //MajorNodes::pass_2//
0.4% in //Sequence::undertake_queued_tasks//
0.4% in //Sequence::undertake_queued_tasks//
0.4% in //World::stage_V//
0.2% in //CompletionModule::compile//
0.2% in //InferenceSubjects::emit_all//
0.2% in //RTKindConstructors::compile_permissions//
0.2% in //Task::make_built_in_kind_constructors//
3.3% not specifically accounted for
26.4% in running Inter pipeline
10.1% in step 14/15: generate inform6 -> auto.inf
5.8% in step 5/15: load-binary-kits
5.8% in step 6/15: make-synoptic-module
0.2% in //World::stages_II_and_III//
3.0% not specifically accounted for
25.4% in running Inter pipeline
9.9% in step 14/15: generate inform6 -> auto.inf
5.7% in step 5/15: load-binary-kits
5.2% in step 6/15: make-synoptic-module
1.4% in step 9/15: make-identifiers-unique
0.4% in step 12/15: eliminate-redundant-operations
0.4% in step 4/15: compile-splats
0.4% in step 7/15: shorten-wiring
0.4% in step 8/15: detect-indirect-calls
0.2% in step 11/15: eliminate-redundant-labels
1.3% not specifically accounted for
2.7% in supervisor
0.2% in step 8/15: detect-indirect-calls
1.4% not specifically accounted for
2.6% in supervisor
0.5% not specifically accounted for

View file

@ -1,16 +0,0 @@
Inform build 6M62 (14 December 2015)
Command line: -log=X is now -log X
Limit on quoted text length raised to 8K
Limit on object name length removed
Options.txt now encoded as UTF-8, not ISO Latin-1
Adjective grading improved:
big -> bigger, biggest
And "long" to "length"
In text substitutions, a local variable name is preferred over an adaptive
verb; e.g. if "index" is both.

View file

@ -1,5 +1,7 @@
[Chapter: Introduction] Preface
Note (added in August 2022): This book describes changes to the Inform language up to the end of its period as a closed-source project. Developments after that point are logged in release notes on the Inform source code repository, and most of the content below has been migrated there, too. This ebook is therefore now only of historical use.
Inform is a project under active development, both by its original authors and by users who contribute extensions. Besides that, it belongs to an ecosystem of related tools and projects, and they develop, too.
So Inform is periodically reissued in new versions, or "builds". Builds of Inform are identified by four-character codes: number, letter, number, number. Builds are always accompanied by a detailed if sometimes technical "change log", laying out what's new. You're now reading a collection of these change logs, going backwards in time to build 4S08, which was really the first version of Inform 7 considered solid enough for regular rather than experimental use.

View file

@ -12,27 +12,25 @@ Interactive fiction is a literary form which involves programming a computer so
These notes are arranged so that the reader can, in principle, write whole works of fiction as early as the end of Chapter 3. Each subsequent chapter then extends the range of techniques available to make livelier and more intriguing situations.
This new release of Inform ("Inform 7", the seventh major version since 1993) is a radical departure from most previous approaches to interactive fiction. In particular, it is very different from Inform 6, which newcomers will not need to know anything about. Inform 6 sits inside Inform 7, and is part of the inner workings, but is not visible from the outside. For information about Inform 6, see <b>www.inform-fiction.org</b>.
Today's Inform language (sometimes called "Inform 7") is very different from its 20th-century predecessor, which was called Inform 6. A few advanced sections of this book show how unusual effects can be achieved by mixing low-level coding in Inform 6 notation with more usual Inform text. However, most users will never need this. For information about Inform 6, see <b>www.inform-fiction.org</b>.
This book is also a guide to the Inform language, rather than a manual on how to use its supporting tools. Those tools, when used at the command line rather than inside the Inform app, have numerous features not covered here. Manuals for them are all available online: see <b>github.com/ganelson/inform</b>.
Programming is best regarded as the process of creating works of literature, which are meant to be read... so we ought to address them to people, not to machines. (^{@Donald Knuth}, "Literate Programming", 1981)
(See Acknowledgements for a chance to try out the cross-referencing links in <i>Writing with Inform</i> - click on the red asterisk or the name of the destination to go there.)
[x] Acknowledgements
Inform 7 is dedicated to ^{@Emily Short} and ^{@Andrew Plotkin}, whose shrewd and sceptical suggestions made a contribution which can hardly be overstated. A long email correspondence with Andrew entirely subverted my original thoughts about natural-language IF, as he convinced me that the "new model" of rule-based IF was a truer foundation; while Emily's wry, witty analysis and how-about-this? cheered me at low moments, besides providing the impetus and often the specifics for a lot of the best ideas.
From the outset, I have thought of Inform 7 as no longer being a command-line compiler, but a compiler in combination with a humanising user interface. All credit for the reference implementation under Mac OS X belongs to ^{@Andrew Hunter}. How simple the metaphor of an interactive book with facing pages may seem, but the coding was an enormous challenge. In 2014 ^{@Toby Nelson}, my brother, put months of time into the project by rewriting and modernising the Mac OS X application: sandboxing it for the Mac App Store, giving it a more contemporary design, and much more. He continues to maintain it today.
Though ^{@David Kinder}'s Windows application does indeed visually follow the OS X original, the two programs were coded independently, and the programming task taken up by David was formidable indeed. ^{@Philip Chimento}'s Gnome-based user interface for Linux became officially part of the project in November 2007, when the first easy-to-install packages for Ubuntu and Fedora were offered. Philip's efforts were particularly generous since the early stages of Inform-for-Linux were so tentative: for many months, we weren't sure how to go about the project, and during that time Philip quietly wrote us a solution. ^{@Adam Thornton} continues to support Inform at the command line on Unix-like systems.
Though ^{@David Kinder}'s Windows application does indeed visually follow the OS X original, the two programs were coded independently, and the programming task taken up by David was formidable indeed. ^{@Philip Chimento}'s Gnome-based user interface for Linux became officially part of the project in November 2007, when the first easy-to-install packages for Ubuntu and Fedora were offered. ^{@Adam Thornton} gave invaluable assistance in the closed-source age of Inform to make generic Unix binaries available, too.
Inform in its widest sense incorporates work by so many people that it's simply impossible to thank all of them, but ^{@Erik Temple}, ^{@Dannii Willis}, ^{@Ron Newcomb}, ^{@Eric Eve} and ^{@Juhana Leinonen} all deserve special mention. Many hundreds of users have filed patient and careful bug reports, keeping us on the straight and narrow. They're contributors, too.
While Inform is not strictly speaking a project of the Interactive Fiction Technology Foundation (IFTF), it benefits enormously from the Foundation's good work. In particular, the Narrascope conferences were invaluable in the period 2017-2022, and I thank ^{@Judith Pintar} and ^{@Andrew Plotkin} for arranging speaking slots at them.
It's perhaps surprising that the Inform application gained its first online component only in 2014, but the Public Library of Extensions, and its discussion forum, make a brave step into the modern age. ^{@Mark Musante}, our Extensions librarian, Dannii Willis and ^{@Justin de Vesine} have been a great help in setting this up.
Inform in its widest sense incorporates work by so many people that it's simply impossible to thank all of them, but ^{@Zed Lopez}, ^{@Dannii Willis}, ^{@Mark Musante}, ^{@Brian Rushton}, ^{@Dan Fabulich}, ^{@Hugo Labrande}, ^{@Erik Temple}, ^{@Ron Newcomb}, ^{@Eric Eve}, ^{@Justin de Vesine} and ^{@Juhana Leinonen} all deserve special mention. Many hundreds of users have filed patient and careful bug reports, keeping us on the straight and narrow. They're contributors, too.
The Inform bug tracker, now hosted on Jira, was set up by ^{@Hugo Labrande}, who migrated a large back database of issues from its Mantis predecessor, and the curator is ^{@Brian Rushton}.
The original development of Inform 7 was a long haul, and I would particularly like to thank ^{@Sonja Kesserich}, ^{@David Cornelson} and other volunteers for their early testing of a then-fragile system. The final months before the Public Beta release of Inform 7 were made more enjoyable, as well as more productive, by fruitful discussions leading to a cross-platform standard for bibliographic data and cover art. ^{@L. Ross Raszewski}, who wrote frighteningly efficient reference software in frighteningly little time; the librarians of the IF-Archive, Andrew Plotkin, David Kinder and ^{@Paul Mazaitis}; and my fellow authors of IF design systems - ^{@Mike Roberts} (of the Text Adventure Development System); ^{@Kent Tessman} (of Hugo); and ^{@Campbell Wild} (of ADRIFT).
The original development of Inform 7 was a long haul, and I would particularly like to thank ^{@Sonja Kesserich}, ^{@David Cornelson} and other volunteers for their early testing of a then-fragile system. The final months before the Public Beta release of Inform 7 were made more enjoyable, as well as more productive, by fruitful discussions leading to a cross-platform standard for bibliographic data and cover art. Special mentions to ^{@L. Ross Raszewski}, who wrote frighteningly efficient reference software in frighteningly little time; the librarians of the IF-Archive, Andrew Plotkin, David Kinder and ^{@Paul Mazaitis}; and my fellow authors of IF design systems - ^{@Mike Roberts} (of the Text Adventure Development System); ^{@Kent Tessman} (of Hugo); and ^{@Campbell Wild} (of ADRIFT).
{EPUB:}This EPUB edition of the documentation was greatly assisted by excellent advice published by ^{@Liza Daly}, an old friend of Inform's.
@ -125,113 +123,7 @@ Inform's Skein panel is just such a table, built automatically. If we think of t
Double-clicking on a command translates the source afresh and replays the story from <b>start</b> down to that command, and then stops. We are then free to continue play by typing commands into the Story panel, of course, and these commands will automatically be recorded in the Skein as a new variation of play, diverging from the previous threads.
{Linux:}The Skein is not implemented in the Linux version.
[x] A short Skein tutorial
^^{user interface: Skein panel} ^^{Skein panel+ui+}
^^{user interface: Transcript panel} ^^{Transcript panel+ui+}
^^{transcripts: in the Skein <-- blessed transcripts}
In the following example, we will see how the Skein is woven as different commands are tried. As it happens, the story being played is the example "Witnessed", from Chapter 11, but the details do not matter. When the project has never been played at all, if we switch to the Skein panel (or open it opposite the Story panel) we will only find this:
///bordered:skt1.png///
Suppose we click Go for the first time and type two commands in: TURN ON ALARM and then LOOK. Now the Skein shows:
///bordered:skt2.png///
Only one line of play is known to Inform, and it runs downwards in a thread from the special "- start -" knot, which represents the situation before any command has been tried. The useful thing about having past histories recorded like this is that we can revisit them. Suppose we want to go back to the situation after typing only TURN ON ALARM. We could click Go again and type that first command in once more, but now we have an easier method: we simply double-click on the TURN ON ALARM knot. The story restarts by itself, and commands are automatically keyed in to regain the position of play represented by the knot we clicked on - in this example that only keys a single command in, but it might have been hundreds. The Skein now looks like this:
///bordered:skt3.png///
All knots are displayed either as yellow or green. Yellow knot are the ones in the history of the story currently playing. The LOOK knot is green because it hasn't happened in the current story yet - and in fact, it won't happen in the current story, because instead we play TURN ON METER. Now the Skein changes again:
///bordered:skt4.png///
Inform now knows about two ways to play the current project: one consisting of TURN ON ALARM and then TURN ON METER, the other of TURN ON ALARM and then LOOK. Since these only differ after the first turn, Inform displays them as a thread which divides into two after the first turn. Again, LOOK remains green because it hasn't been played in the current story.
Note also that one of the two possible threads here is drawn more thickly (here it is shown with thick dashes rather than thin). Only one thread is ever drawn thickly -- the one currently being shown in the Transcript panel, which we will come to later on. (That often corresponds to the current line of play, as now, because the Transcript follows what we do unless we choose otherwise.)
After a little more exploration, we reach the following:
///bordered:skt5.png///
{OSX:}At this point we decide that we want to preserve the thread leading to EXAMINE CHIMES - perhaps it's a sequence we are going to want to test often. The Skein can be edited very easily, in several ways (for instance clicking and holding on a command allows us to edit the text of the command): control-clicking (or right-clicking) on a knot brings up a contextual menu. On Mac OS X, some popular knot controls appear whenever the mouse hovers over the knot, like so:
{OSX:}///bordered:skt6.png///
{^OSX:}At this point we decide that we want to preserve the thread leading to EXAMINE CHIMES - perhaps it's a sequence we are going to want to test often. The Skein can be edited very easily: right-clicking on a knot brings up a contextual menu.
{OSX:}We click on the padlock button (or choose Lock This Branch from the contextual menu), and this makes the thread through to here "locked". That means the knots can't be deleted (unless we unlock them again) - either by our own mistake, or by Inform trimming back no-longer-needed threads of the Skein to keep it manageable in size.
{^OSX:}We choose Lock This Thread from the contextual menu, and this makes the thread through to here "locked". That means the knots can't be deleted (unless we unlock them again) - either by our own mistake, or by Inform trimming back no-longer-needed threads of the Skein to keep it manageable in size.
///bordered:skt7.png///
Note that this locked history is now drawn as a solid thread, whereas all the others are unlocked and drawn as dashes.
Now we have a securely remembered piece of standard play: it means we can try out the sequence TURN ON ALARM / TURN ON METER / WAIT / EXAMINE CHIMES any time we want to with a double-click on the final knot. This is convenient for testing - but so far it only runs the test: to see whether the test came out well or badly, we have to look through what happened, perhaps by scrolling back in the Story panel to look at the text. And that means that we need to remember what the text should have been like.
In fact, though, Inform can remember for us, using the Transcript panel. This is closely joined to the Skein panel, and it's often convenient to flip between the two. Turning to the Transcript now, we find a two-column view of the story currently being played. The left-hand column shows the text which has been displayed on each turn so far; the right-hand column is empty. The bottom of the Transcript looks like so:
///bordered:skt8.png///
The empty right-hand column displays the "blessed" transcript - one which the author has approved as being correct. This can be done for each individual knot, using the Bless button joining the columns, but in this case we will bless the whole transcript of this story, using the Bless All button. Now there's text in both columns, and of course the two columns match. (Note that the blessed transcript is in a brighter colour.)
///bordered:skt9.png///
Back in the Skein, we find that the knots which have transcripts have lit up, and are brighter than the others. If we Go, to start a new story, and then look at the Skein:
///bordered:skt10.png///
we see that the knots for which we have blessed a transcript are in a brighter green (or a brighter yellow, if they're in the current story being played).
Now suppose we change the source text for the project, so that we make it behave differently. The details don't matter, but suppose we do something which changes the result of the TURN ON METER command, and then run the test again. Now we find:
///bordered:skt11.png///
The red warning badge on the TURN ON METER knot alerts us that the last time this knot was tried (just now, as it happens), the resulting text didn't agree with its blessed transcript. (Red badges can only be seen on bright-coloured knots which have transcripts - for other knots, there's nothing to compare with.) On the other hand, the rest of the yellow current line of play worked out exactly the same as we expected - so no badges. Clicking on the red badge takes us into the Transcript panel at the right place, where the corresponding turn's transcript has also turned red:
///bordered:skt12.png///
{OSX:}Again, what actually happened is on the left; what should have happened is on the right. The change is shown with underlining - we added the text "quivers, then". If we approve this change, by clicking on the Bless button for the red turn, the amended text will become the correct text to compare against in future runs, and the turn will become green to show that once again all is well. (We can also edit the blessed transcript directly, by clicking in the text and typing.) Clicking on the Show knot button takes us back in the skein, at the right place: where we will see that the red warning badge has disappeared.
{^OSX:}Again, what actually happened is on the left; what should have happened is on the right. The change is shown with underlining - we added the text "quivers, then". If we approve this change, by clicking on the Bless button for the red turn, the amended text will become the correct text to compare against in future runs, and the turn will become green to show that once again all is well. (We can also edit the blessed transcript directly, by double-clicking in the text and typing.) Clicking on the Show knot button takes us back in the skein, at the right place: where we will see that the red warning badge has disappeared.
Some writers of IF like to work backwards from a transcript of the story they want to produce, and for them, the Skein and Transcript combination will be helpful as a running picture of what works so far. Other authors may not use the Skein/Transcript feature at all until right at the end of a project, in testing before publication, when it becomes very important to be able to make small changes in one area without upsetting everything else. Either way, the Skein and Transcript together make a very powerful testing aid.
{OSX:}This tutorial has shown only a short line of play, to keep the pictures small, but for a large project the Skein might run to thousands of knots. It then becomes important to be able quickly to find key knots corresponding to plot developments. To help with that, we can annotate certain knots with any label we choose (using one of the mouseover buttons, for instance):
{^OSX:}This tutorial has shown only a short line of play, to keep the pictures small, but for a large project the Skein might run to thousands of knots. It then becomes important to be able quickly to find key knots corresponding to plot developments. To help with that, we can annotate certain knots with any label we choose (by selecting Add Label from the contextual menu):
///bordered:skt13.png///
And this is where the "Labels" gadget at the top of the Skein comes into its own:
///bordered:skt14.png///
since it offers a menu of all the labels in the Skein, and if selected will jump to the one chosen.
{OSX:}The Skein has other abilities too, best explored by experimenting. For instance, we can edit the commands by clicking and holding on the command text in a knot. We can add new knots in the middle of existing lines using the "add knot" mouseover button. The Play All Blessed option (on the Build menu in OS X) is especially powerful: it tests each possible blessed history in turn, trying all of them, and can therefore test very complicated multiple endings and the like in a single click.
{^OSX:}The Skein has other abilities too, best explored by experimenting. For instance, we can edit the commands by selecting Edit Knot from the contextual menu, and we can add new knots in the middle of existing lines using the Insert Knot item on that menu. The Play All Blessed option (on the Game menu) is especially powerful: it tests each possible blessed history in turn, trying all of them, and can therefore test very complicated multiple endings and the like in a single click.
{Linux:}The Skein and Transcript are not implemented in the Linux version.
[x] Summary of the Skein and Transcript
^^{user interface: Skein panel} ^^{Skein panel+ui+}
^^{user interface: Transcript panel} ^^{Transcript panel+ui+}
^^{transcripts: in the Skein}
The Skein records the history of different plays through the current project, and the Transcript records the text of each response, comparing it with a "blessed" or correct version if one is available.
In the Skein each typed command is a "knot". The threads hanging down from the top "- start -" knot are possible histories. Double-click on a knot to play through to there.
Yellow knots are commands played so far in the current story: green knots are possible lines not taken, or not taken yet.
A solid thread is "locked" and protected from deletion (by accident or when Inform trims away loose ends): a dashed thread has no such protection.
A bright knot has a blessed transcript: a darker knot is one which has no blessed transcript. When a bright knot shows a red badge, this means that when last tested its command produced a textual reply which wasn't the same as the blessed transcript. Clicking on the badge shows exactly how.
The thicker thread in the Skein shows the history currently being displayed in the Transcript panel.
{Linux:}The Skein and Transcript are not implemented in the Linux version.
The user interface for the Skein looks slightly different on different versions of the Inform apps (that is, the MacOS version is not quite the same as the Windows version, and so on), so this manual is not the best place to describe it. In any case, the best way to find out about it is probably to experiment.
[Chapter: The Source Text] Creating the world {PM_NoSuchVerb} {PM_NoSuchVerbComma} {PM_NegatedVerb1} {PM_TwoLikelihoods} {PM_CantAssertAdjective} {PM_CantAssertNegatedEverywhere} {PM_CantAssertNegatedRelations} {PM_CantAssertNonKind} {PM_CantAssertQuantifier}
@ -719,24 +611,11 @@ Inform is a system for translating textual descriptions of interactive fiction i
- how large they are, that is, how much play they can express;
- what extra-textual effects they can bring off.
Inform can write to two different formats. Neither of these is proprietary, and neither was created by the authors of Inform: each format is a community property, defined by published standards documents. An individual Inform project can make its own choice of story file format, using that project's Settings panel.
Inform can write to two different formats. Neither of these is proprietary, and neither was created by the authors of Inform: each format is a community property, defined by published standards documents. An individual Inform project can make its own choice of story file format, using that project's Settings panel. Outside the Inform app, Inform can even be used at the command line to generate C programs rather than story files, and those can be compiled to run on almost any computer.
Newly created projects are set up with the Glulx format. This has largely taken over from an earlier format called the Z-machine, but Inform can still generate a version 8 Z-machine file (a so-called "z8") if required. The Z-machine is of historic importance, and may continue to be useful for certain tasks where Glulx support is not yet available, but most users will want to keep the Glulx format set all of the time.
Internally, the Inform application uses a tool called Inform 6 (which was once the entire Inform system) to manufacture the story file. There are therefore two ways that large projects can run out of space:
(a) By exceeding some maximum in Inform 6, or
(b) By exceeding some fundamental limitation of the current story file format.
In both cases, the Inform application will display a Problems page explaining that the Inform 6 tool has failed to work as intended, and refer us to the "console output" - the text produced by Inform 6 - which is normally ignored, but can be found on the Console tab of the Results panel.
In case (a), Inform 6 will say that a memory setting has been exceeded: it will say what this setting is called (for instance "MAX_ZCODE_SIZE") and what its current value is (for instance 50000). We can then avoid the problem by adding the following use option into the source text:
Use MAX_ZCODE_SIZE of 60000.
And similarly for every other Inform 6 memory setting. (If the source tries to specify the same setting more than once - which is quite possible if extensions are included, with rival ideas - then the highest value is used.)
Case (b) is only likely to happen with the Z-machine format, since Glulx has a huge capacity; so the cure here is to switch to Glulx in the Settings. But if that's not possible for some reason - say, if we want a story file playable on a tiny handheld computer unable to manage Glulx - we still have a few options. Unless the story is very large (in which case there is little we can do), the "z8" format is most likely to be exhausted for lack of what is called "readable memory", with a message like so:
Internally, the Inform application uses a tool called Inform 6 (which was once the entire Inform system) as the final stage in manufacturing the story file. Inevitably, though, this can go wrong if the story is so large or complex that it exceeds some fundamental limitation of the current story file format. This is only likely to happen with the Z-machine format, since Glulx has a huge capacity; so the cure here is to switch to Glulx in the Settings. But if that's not possible for some reason - say, if we want a story file playable on a tiny handheld computer unable to manage Glulx - we still have a few options. Unless the story is very large (in which case there is little we can do), the "z8" format is most likely to be exhausted for lack of what is called "readable memory", with a message like so:
This program has overflowed the maximum readable-memory size of the Z-machine format. See the memory map below: the start of the area marked "above readable memory" must be brought down to $10000 or less.
@ -762,9 +641,9 @@ It is very helpful for users to report faults, so that the program can be improv
http://inform7.com/download/
If the bug is still present in the latest version, please report the bug using Inform's bug tracking database, found at
If the bug is still present in the latest version, please report the bug using Inform's bug tracking database. Links for this can be found from the Inform source code page:
https://inform7.atlassian.net/jira/software/c/projects/I7/issues
https://github.com/ganelson/inform
It may be that someone else has already identified the bug and even that a workaround for users is suggested. If not, please make an account at the bug tracking system and submit the requested information to help Inform's maintainers track and fix the fault.
@ -15137,8 +15016,6 @@ produces:
{ 2, 4, 6, 7 }
(This may seem surprising since Inform's built-in phrases to adjust lists, like "add ... to ...", don't work this way. But those are written using Inform 6 code; see the phrase definitions in the Standard Rules for more.)
[Chapter: Advanced Phrases] A review of kinds
^^{kinds}
@ -16219,7 +16096,7 @@ If, however, we want a rapid overview of all the responses provided by a given e
^^{TRACE+testcmd+} ^^{testing commands: >TRACE}
^^{magic words}
In addition to the commands designed around Inform 7's data model, there are several debugging commands that have persisted since the days of Inform 6. These are generally less useful or necessary with Inform 7's features, but there are still times when they can come in handy for a quick and dirty resolution of a problem during gameplay. They are as follow.
There are also several debugging commands going back to the early days of interactive fiction, and relating in a simple way to objects and places. These can still come in handy for a quick and dirty resolution of a problem during gameplay, and are as follows.
PURLOIN moves an object to your possession, no matter where it is on the map, like so:
@ -16354,7 +16231,7 @@ Fortunately, Inform has a lively and helpful community of users who are often wi
https://intfiction.org/
and in particular to post Inform-related problems under the topic Inform 6 and 7 Development. Where possible, it's a good idea to post the example source that is causing trouble, and to make it as short as possible so that prospective helpers will not have to read any more than necessary in order to pinpoint the problem.
and in particular to post Inform-related problems under the topic Inform 7 Development. Where possible, it's a good idea to post the example source that is causing trouble, and to make it as short as possible so that prospective helpers will not have to read any more than necessary in order to pinpoint the problem.
The user community is also a good place to find beta-testers who can try out our work and give feedback.
@ -17363,7 +17240,7 @@ So it's wise (if difficult) not to judge a story's success entirely by its immed
The range of simulation offered by Inform's model world is intentionally limited to a core of basic essentials. We could argue at the margins, and the choice of what's in and what's out is partly traditional, but most people find the model reasonable as far as it goes.
Between 1993 and 2006, quite a range of "library extensions" for Inform 6 was written. Most of these extensions aimed to fill out the model by simulating other aspects of life, too: money, clothing, pourable liquids. None of these extensions was official and all of them were: it was a free-for-all, and in several cases different authors wrote rival extensions to model the same basic ideas. The development of Inform 7 was strongly influenced by this history and by the recognition that the base of rules and grammar inside a typical modern story are seldom written by a single author. They combine the standard Inform material with extensions by several third parties, together with anything specific to the story in question.
Between 1993 and 2006, quite a range of "library extensions" for Inform's predecessor language (Inform 6) was written. Most of these extensions aimed to fill out the model by simulating other aspects of life, too: money, clothing, pourable liquids. None of these extensions was official and all of them were: it was a free-for-all, and in several cases different authors wrote rival extensions to model the same basic ideas. The development of Inform 7 was strongly influenced by this history and by the recognition that the base of rules and grammar inside a typical modern story are seldom written by a single author. They combine the standard Inform material with extensions by several third parties, together with anything specific to the story in question.
Inform 7 has a more organised idea of extensions, as we shall see. But anyone is free to write an extension on any terms or for any reason. Writers may wish to use the techniques in this chapter to develop private extensions of their own, used in several projects, or to share them with associates but not more widely.