Inform7/10 Reference Manual

It has been low-key bugging me for awhile that Inform7 doesn’t have anything that could be called a “reference manual” – something where you can easily look up how to do a specific thing, ideal for someone who already mostly knows the language but can’t quite remember that one phrasing.

There’s no lack of manuals for Inform, mind you. The core “Writing with Inform” manual distributed with the IDE is not terrible, particularly given how easily searchable it is and the fact that it has an index. I haven’t read much of Jim Aikin’s “The Inform Handbook”, but it seems decent enough from what I did read. Ron Newcomb’s “The Inform 7 Programmer’s Manual” is probably the closest to what I’d want, but it falls a bit short. It nicely covers a number of topics[1] that aren’t well decribed by “Writing with Inform”, and its approach is close to what I want; but it doesn’t cover everything in the language, and it’s perhaps a little too prose-heavy to qualify as a reference manual.

There’s also the Index, which provides a ton of useful information, such as an easily-searchable almost-complete[2] list of phrases, a complete list of supported actions, a (sadly-incomplete[3]) list of understandable commands, a complete list of kinds, a list of adjectives, a list of relations, a list of verbs, a list of every rule in every rulebook (divided into three sections, but at least they’re all there), a list of scenes, a list of timed events… it’s good enough for certain things that I’ve seen people be directed to it in lieu of proper reference documentation, but it doesn’t help in the least when it comes to more basic syntax elements.

So, if it doesn’t exist, why not create it? I’ve started out by scouring the first 7 chapters of “Writing with Inform”, looking for ways of doing things that are either undocumented or just barely mentioned in passing, filing them all away into appropriate categories.

The reason I’m creating this topic is to glean opinions on how such a manual should be structured (though I do have a partial outline in my head) and how sections should be worded and formatted, as well as whether I’ve missed anything of note. So, to start off with, I’ll outline the current categories that I’m filing things into. I’m sure this omits a bunch of things introduced in chapter 8 and later of “Writing with Inform”, though I’ve pencilled in some of those things as well.

My current outline
  • Syntax Reference The intent here is to cover every kind of written construct (sentence or otherwise) that Inform can understand.
    • Headers Pretty straightforward; this section is dedicated not just to headers but to all the special things you can do with them, like "not for release", "in place of", etc. I also include the other special one-time syntaxes here – the story title, extension preamble and closing line, and extension documentation syntax.
    • Literals This is section is about specifying literal values in your code, so it would be mostly about text (with brief coverage of integers, real numbers, and time) but should probably also have a section on arithmetic values and maybe a section on topics. Oh, and also a section on lists.
    • Assertions I'm not sure if it's commonly-used, but this is the term I'm using for the static sentences that build up the model world. Generally speaking, anything that's not a header, rule, or phrase counts as an assertion for this definition.
      • Structural Assertions – I’m not sure if this is the best term for it, but this section is intended to cover assertions that work with values, not kinds. Right now it covers ways of declaring that something exists, ways of setting properties on something, and ways of declaring a relationship between things. (In this context, “thing” refers to any object or enumerable value, including scenes.)
      • Defining Kinds – This section is intended to cover assertioms that work with kinds (some of these can also be used on values, but are primarily intended for kinds). Defining kinds and their properties all go here (including the definition of arithmetic values using “specifies”). At the moment I also slipped in variables and constance, not sure if that fits here. It also covers assemblies. Implications also belong here (not sure if I’ve added them yet).
      • Defining Other Things – Highly tentative, as I’ve barely started to fill it in yet. Would likely be split into a section per key thing. Things to cover include actions, relations, rulebooks, and activities. Tables and equations probably each need a section of their own too. There’s also figures, sounds, and files, and maybe the syntax for specifying the start and end of a scene. (Declaring scenes and their properties doesn’t go here – that’s covered by “Structural Assertions”.)
      • Understand Assertions – A whole section dedicated to the “Understand” keyword, which has a whole bunch of different forms. I haven’t started filling this section in yet.
      • Other Imperative Assertions – A section for any assertions made in the imperative, other than “Understand”. So far I only have “Test”, “Use”, and “Include” (for extensions) here; I’ll eventually add “Index map” and probably more as well.
    • Phrasebooks Here again, I'm not sure if this is a term that other people have ever used in this context. I'm using it to refer to anything that contains "phrases", so the term seems vaguely appropriate to me, but I'm not sure if others might find it misleading. In fact, this section just documents the _headers_ and overall format of what I'm calling phrasebooks – there'd probably be a separate section on the phrases themselves.
      • Phrases – Covering the syntax to define phrases.
      • Rules – Covering the syntax to define rules.
      • Events – Covering the syntax to define timed events. (A very short section, to be sure, but it doesn’t really fit anywhere else.)
      • Definitions – Covering the syntax to define adjectives. (Also fairly short, but again, doesn’t really fit anywhere else.)
    • Descriptions Syntax for describing things goes here.
      • Descriptions of Values – The syntax for descriptions (or as Ron Newcomb calls them, “set-descriptions”). As far as I know, there’s no difference between a “description of objects” and a “description of values” in terms of the basic syntax, so both can be covered by a single section. (For example, a description of numbers still has the basic form consisting of some adjectives and a relative clause.)
      • Descriptions of Actions – The syntax for describing actions, which I’ve also seen referred to as “action patterns”.
      • Descriptions of Kinds – Not started, but I was thinking syntax such as “K valued table column” could be listed here. It’s already listed in the Kinds index, mind you, but it’s undeniably a syntax thing so I think having everything in one place is a good idea… especially since the index oversimplifies this.
  • Debugging Commands – I’m not sure if this section is worth including, but the debug commands are documented pretty briefly, so maybe?

  • Phrases – This section might be a bit redundant since the Index Phrasebook is a pretty good reference, but I want to list at least the most common, basic phrases such as flow control phrases (if, repeat, etc). I could include a complete list of phrases, but I’m not sure to what extent this is worthwhile when the index already lists every defined phrase (well, other than unindexed ones…).

  • I’ve considered including overviews of built-in definitions, for example the standard set of object kinds and their properties and relations, or the standard set of actions, or the standard set of rulebooks. I’m not sure whether I will.


  1. It helps a lot in understanding the concepts of repeated and consecutive events, as well as the past tense tests. ↩︎

  2. I know for certain that there are phrases not listed in the Index. Most likely they’re just phrases declared in “unindexed” sections, but I’m not 100% sure about this. ↩︎

  3. It doesn’t contain any of the low-level commands implemented in Inform6, such as “oops” or “again”, or debug commands like “showme” or “purloin”. ↩︎

6 Likes

Many people have started this project.

I think the underlying reason why it’s hard is that when you dig into some hard-to-remember Inform phrasing, it turns out to be either (a) in the Phrasebook, or (b) some form of “X is Y”.

Organizing a complete catalog of the latter is not an obvious problem.

3 Likes

it’s a so excellent idea, one whose will put the IDE into “Ideal” category. let’s work on it, then coax Lord Inform into adding a “green book” (or whatever light-hued background colour…) to the already good WI/RB !!

Best regards from Italy,
dott. Piergiorgio.

It’s not going to be hard to write a better book than “Creating Interactive Fiction with Inform 7” by Aaron Reed. It doesn’t even have anything with tables in it! Of all of the resources available, I find that it’s the least used and what I go to only as a last rest.

I think it’s a great idea. If I can help, let me know. It would be good to have a manual like the one you are describing.

It’s true that it’s not completely obvious, but it’s certainly possible.


I heard about this one but haven’t seen it, so I have no idea how good it is.

If nothing else, you can help by reading my drafts here and noting if a) something is confusing or b) something is missing. :slight_smile:


I’m going to start by posting my summary of the syntax of what I’m calling “phrasebooks”, which is divided into 4 sections.

I’m going to use a vaguely regular expression language to define the form of valid statements, and since Inform mostly treats articles as insignificant, I’m going to omit them entirely from the specification. The following is a summary of the syntax I’m using to define the syntax:

  • «this» is a placeholder that will be substituted with something else
  • enclosed symbols or bolded words are completely literal values that must be written as-is (other than being case-insensitive)
  • Forward slash separates alternative words, eg otherwise/else
  • Parentheses are used for grouping
  • Square brackets enclose optional passages
  • The characters + ? * | have the usual regular expression meanings (the pipe separates alternatives that aren’t a single word)
  • I’ll include all syntax within block quotes. Usually each line of the block quote is an alternative; but in some cases a single block quote specifies the full pattern, split into multiple lines for readability. I’ll note it whenever the second case happens.
Phrasebooks In contrast to an assertion, which is resolved statically at compile time, a phrasebook contains imperative code to be executed at runtime.

With one exception, all phrasebooks have one of the following general forms:

«preamble» : «phrase» ( ; «phrase» )* .
«preamble» : (- «inform 6 code» -) .

That’s not quite accurate, as the final period can be omitted or (for inform 7 phrasebooks at least) replaced by a semicolon as long as the phrasebook is followed by a blank line. Though the preamble depends on the type of phrasebook, the contents of all phrasebooks is the same – a sequence of phrases that are run one after another.

The type of phrasebook you’re looking at can always be determined by the first word. – “To” for a phrase, “At” for an event, “Definition” for a definition. Anything else is a rule.

The remainder of this section focuses only on the preamble of each type of phrasebook.

Phrases I believe the following list covers every possible way of defining a phrase:

To say «phrase pattern» [( this is «phrase name» )] :
To decide what/which «kind or kind variable» is «phrase pattern» [«phrase option list»] [( this is «phrase name» )] :
To decide if/whether «phrase pattern» [«phrase option list»] [( this is «phrase name» )] :
To «phrase pattern» [«phrase option list»] [( this is «phrase name» )] :

The following form is not allowed, except for phrases defined in I6 – you need to use the if/whether form instead:

To decide what/which truth state is

Phrase patterns are a sequence of one or more of the following:

«any literal word» [ / «any literal word» ] [ / -- ]
( name of kind of «generic value kind» «kind variable» )
( «name» - «generic value kind» of kind «kind variable» )
( «name» - «description of values» )
( «name» - «special non-kind» )

That first one is slightly inaccurate – -- is not required to come at the end. The second and third ones define a kind variable which can then be referenced from other parameters or in the phrase body. There is also a restriction that a close parenthesis cannot be followed by an open parenthesis – at least one literal word must be interposed.

This is a list of the special non-kinds (these are only allowed on I6 phrases; scraped from the syntax document, not sure if this is missing some detail or other):

storage
[ existing/nonexisting/global ] [ «kind» ] variable
property-value
table-reference
list-entry
condition
now-condition
phrase
action

Phrase options are defined with the following syntax (these are the full specification, not alternatives):

, «phrase option»
[ [ , «phrase option» ] [ , ] ( or | and/or ) «phrase option» ]
[ «special phrase option» ]

Special phrase options always contain -- and are only recognized as such if they are an exact known option that applies to that phrase type. Otherwise, they (along with the double hyphen introducing them) are treated as part of the preceding pattern or phrase option. The only special phrase option that I know of that’s useful for phrases not written in I6 is “running on”, which is valid for say phrases.

This is a list of all special phrase options used in Basic Inform:

  • -- running on – for say phrases
  • -- beginning «name» – for say phrases
  • -- continuing «name» – for say phrases
  • -- ending «name» [ with marker «name» ] – for say phrases
  • begin -- end conditional/loop – this seems to be the way to define block phrases
  • -- in loop – a phrase that can only be used in a loop; works on imperative phrases, haven’t tested on other types
Rules

There are three ways of declaring rules. The first is a named rule with no circumstances and not placed in a rulebook:

This is the «rule name» :

The second way is a rule with circumstances, placed in a rulebook, with an optional name:

[ First/Last ] «rulebook name» [ for | of | rule about/for/on ]
[ «description of target» ]
[ when/while «condition» ]
[ during «description of scenes» ]
[ ( this is the «rule name» ) ] :

The form of «description of target» depends on the basis of the rulebook. For a nothing based rulebook, it’s not allowed at all. For an action based rulebook, it will be a description of an action. For an object based rulebook, it will be a description of an object.

There is a bit of ambiguity here for action based rulebooks, as a description of an action also supports a when/while clause. However, it’s not valid to have two when/while clauses on a rule, so if there’s an action description in the preamble, the when/while clause belongs to that description and the second one noted above may not be included.

The third way of declaring rules is the special exception noted earlier, where a phrasebook definition does not include a colon:

(Before/After/When | Instead of | Every turn) «rest of preamble» , «phrase» .

Note that there can only be a single phrase in this form. Furthermore, the initial word or words don’t need to be the full name of the rulebook – this form can be used for any rulebook whose name happens to begin with one of those words. Though it’s rarely done, this form can be given a name.

Events

Events are very simple. There are two ways to define them:

At «time» :
At the time when «rule name» :

The second case will be an error if there is no code that schedules it.

Definitions

A definition phrasebook is defined with the following preamble:

Definition : «kind or value» [ ( called «name» ) ] is/are «adjective» [ rather than «opposite adjective» ] :

There are also two forms of definition that are not technically phrasebooks, but are included here because they have the same initial word:

Definition : «kind or value» [ ( called «name» ) ] is/are «adjective» if «condition» .
Definition : «kind or value» is/are «adjective» if its/his/her/their «property name» is/are «value» [ or more/less ] .


Some other miscellaneous trivial things I noticed I'm noticing a few things that could be described as "syntax holes". For example, rulebooks producing a value can have named outcomes, but this doesn't really work – a named outcome can't produce a value. It also looks like there's no way to create a literal snippet – maybe this is intended, but I just thought that the syntax listed as the default value of a snippet in the Kinds index might actually be valid in code (it's not).

I also noticed that the “when scene begins” and “when scene ends” rulebooks are special-cased. I’d actually thought that each scene has its own rulebook, but judging from the rules listing in the scenes index, that doesn’t appear to be the case. Instead, there’s only two rulebooks, “when scene begins” and “when scene ends”, which are scene-based rulebooks. You can write rules as “when scene begins for «a description of scenes»” just like you’d expect, but you can also write rules like “when «a description of scenes» ends «scene ending name»”, which is a special case but still goes in the same rulebook. (I’m not sure if there exists a way to specify a scene ending name in the former format, though it doesn’t matter all that much.)

After seeing that I thought there might be a general rule in the language allowing for such things:

When scene purifies is a scene based rulebook.
When person sleeps is a person based rulebook.

When entire game purifies: say "Oh my!".
When kitten sleeps: say "Meow!".

But that doesn’t work. Another thing I noticed about scene is that the recurring property is just a normal property that can be toggled at runtime. (I didn’t test whether this actually functions or if it makes the system break down somehow.)

And then there’s the “apply/applied” phrases that apply a phrase to a set of values. They only work for up to three inputs… but as it turns out, every one of them has the same Inform6 body, so it seems to be trivial to define similar phrases for more than 3 outputs if you really need them.

Welcome to my world.

Not sure what you’re saying here. Could you give an example, please?

when <specific-scene> begins and when <specific-scene> ends are conventional rulebooks, but they’re created by the compiler. And, counter-intuitively, they’re not scene-based: they’re the default, action-based. Their associated scene is baked into the rulebook’s identity itself so it doesn’t need it as a parameter.

A bit of syntactic sugare I like for scenes:

During is a scene based rulebook.

This is the during stage rule:
  repeat with sc running through scenes begin;
    if sc is not happening, next;
    follow the during rules for sc;
  end repeat.

The during stage rule is listed before the every turn stage rule in the turn sequence rules.

During entire game: say "this rule is going to get annoying fast."

Here’s my organizing scheme for talking about these things:

An inform program is a series of assertions, optionally organized by sections (i.e., one of volume, book, part, chapter, section); these section headers aren’t assertions, per se.

Assertions are terminated by a . or by whitespace that includes two newlines (and, optionally, any number of .s or ;s so long as you don’t have both a . and ; on the same line, because that would be silly).

Specifying the title and/or author in the first line is syntactic sugar for one or both of these assertions:

The story title is "Work of Genius".
The story author is "Brilliant Writer".

There are three kinds of things that can take imperative code blocks: to-phrases, rules, definitions. The specification of each of these things is, itself, an assertion, but the code blocks themselves cannot include assertions. Code blocks are made of phrases, cannot have blank lines, and each phrase other than the last must end ;. The last phrase ends both itself and the assertion that is the definition of the imperative code block itself, thus may end ..

To-phrases, here, includes to say phrases, to decide if phrases, to decide what/which <kind> phrases.

at <time> or at the time when ... specify rules; they’re just a special-case of rules that don’t exist within a rulebook.

actions are a kind of value, the same kind of value named by stored action.

You can, though, say

The X rule does nothing when Y.

which is logically equivalent to adding when Y is not true preamble on the rule. (Yes, I know you’re concerned with syntax here.)

1 Like

The Standard Rules have the following definitions:

When scene begins is a scene based rulebook.
When scene ends is a scene based rulebook.

So that made me wonder what’s the difference between that and the “when «scene» begins” syntax. Thus, I tried doing both:

When entire game begins: do nothing.
When a recurring scene begins: do nothing.
When scene begins for entire game: do nothing.
When scene begins for a recurring scene: do nothing.

The first two use the special syntax. The second two are normal syntax for a scene based rulebook. After compiling, the Scenes Index shows four rules in the “when scene begins” rulebook.

The When entire game begins rule is missing however… that’s weird. I didn’t notice that last time. (One of the four “when scene begins” rules listed in the Scenes Index is defined in the Standard Rules, so only three of my four rules are there.)

Ah, looking closer, I found it listed further up under the description of the “Entire Game” scene. So maybe “When «scene name» begins” is somehow special, but “When «description of scenes» begins” seems to be the same as “When scene begins for «description of scenes»”. I don’t think scene ending options can be specified in the latter format though.

Yeah, I too was thinking along these lines. I don’t know of any assertions that can contain semicolons though? (I’m not counting what I call “phrasebooks” here.) But I’m thinking of pretty much everything else as an assertion, which means that everything in the source text is either an assertion, a phrasebook, or a section header. (Plus comments.)

Hmm, maybe that’s a good point, I could move those two into the rules section… it does feel a little silly having a separate section just for them.

I practically copy-pasted that list from the syntax document, but you have a good point. I’m not sure why that would be included under the non-kind parameter types.

1 Like

They (other than the assertions creating a definition, rule, or to-phrase) can’t contain them, but if an assertion is being terminated by whitespace-that-includes-two-newlines… well, this compiles.

The story author is "aoeuaoeu";;;;
;
;;;;

lab is a room.

Hunh, and this is a better way to have vertical whitespace within a code block than []:

This is the during stage rule:
  repeat with sc running through scenes begin;
;
    if sc is not happening, next;
;
    follow the during rules for sc;
  end repeat.

Can’t immediately follow the colon, though.

This isn’t true… it’s something closer to: anywhere you can have one semi-colon, you can have any number of them, and any place where you can have one period, you can have any number of them.

1 Like

one must be careful that [] being i7/10’s comment delimiter, one can surmise wrongly that ; is the comment-to-EOL… but OTOH, inform 7/10 is designed as NL for people with little or no programming experience, so the risk of confusing ; with the comment-to-EOL, typical of assembly coding, should be near-nil.

Best regards from Italy,
dott. Piergiorgio.

Hmmm… here’s another weird discovery. The compiler accepts “action”, “description of actions”, and “described action” as parameter types, but it’s not clear what it thinks a “description of actions” actually is. Meanwhile, “described action” doesn’t work, with an error message that seems to imply it fully understood it yet gave up anyway.

To attempt (A - action): try A.
To randomly attempt (A - description of actions): try a random A. [This compiles, but I don't know a way to actually call this phrase.]
To contemplate (A - described action): do nothing. [Not sure what can even be done with A here]

The kitten is an animal. The courtyard is a room. The kitten is in the courtyard.

When play begins:
	attempt taking the kitten;
	[both these lines give an error]
	randomly attempt doing something to the kitten;
	contemplate doing something to the kitten;
The full error messages:

Problem. You wrote ‘randomly attempt doing something to the kitten’, but ‘doing something to the kitten’ seems to be a described action, whereas I was expecting to find a description of actions there.

I was trying to match this phrase:

randomly attempt (doing something to the kitten - description of actions) :x:

I recognised:

doing something to the kitten = a described action


Problem. You wrote ‘contemplate doing something to the kitten’, but ‘doing something to the kitten’ seems to be a described action, whereas I was expecting to find a described action there.

I was trying to match this phrase:

contemplate (doing something to the kitten - described action) :x:

I recognised:

doing something to the kitten = a described action


Okay. I think I’ll post a few more snippets now.

Descriptions are used throughout the source text (in rule preambles and phrases) to refer to things based on their properties and relations. Ron Newcomb compares them to regular expressions, and indeed they are a form of pattern matching.

Descriptions of Values

A description of values takes on one of the following two general forms:

«indefinite pronoun» [«adjectives»] [( called «name» )] [that/which/who «verb» «description»]
[«determiner»] [«adjectives»] [«noun»] [( called «name» )] [that/which/who «verb» «description»]

The noun can be the name of a kind, or the name of a specific object. It’s more commonly the name of a kind. The verb for relative clauses can be any verb that means a relation or property, and is of course followed by a description of values pertaining to the type of the property or the other side of the relation. Since many relations relate objects to objects, this recursive definition allows the creation of very complex patterns.

The indefinite pronouns are as follows:

something/someone/somebody/somewhere
anything/anyone/anybody/anywhere
everything/everyone/everybody/everywhere
nothing/no-one/no one/nobody/nowhere

In rule preambles, only the first two rows are allowed, with any- forms being equivalent to the corresponding some- form. Each of the indefinite pronouns is equivalent to a determiner plus a noun. However, “any” as a determiner (eg “any container”) is not allowed in rule preambles, even though “any” as a determiner seems to essentially be a noise word that does nothing.

Indefinite pronoun meanings
Pronoun Meaning
something a thing
someone/somebody a person
somewhere a room
anything any thing
anyone/anybody any person
anywhere any room
everything every thing
everyone/everybody every person
everywhere every room
nothing no thing
no-one/no one/nobody no person
nowhere no room

Determiners are only allowed in a conditional context, not in rule preambles. The determiners are as follows:

any
each/every/all of
some of
most of
almost all of
no/none of
exactly «number»
[at least] «number»
at most «number»
fewer/less than «number»
more than «number»
all but/except «number»

Most of these have obvious meanings, but “some of”, “most of”, and “almost all of” aren’t so clear. They mean “at least one”, “more than half”, and “at least 80%”, respectively.

Although descriptions of values are most commonly seen with subkinds of objects, with descriptions of enumerated values being the next most common, they can be used on other kinds as well. For example, “an even number” is a description of numbers, and “a one-to-one relation” is a description of relations.

Unlike in assertions, a string of adjectives in a description may not be separated by commas. You can write “a fixed in place open container” but not “a fixed in place, open container”.

Descriptions of Actions

Action descriptions (or “described actions” as the compiler calls them) can get quite complex. The general form is as follows – since it’s quite long, it has been split across several lines:

[«actor»] «action list» [«description of objects»]
[«action preposition» «description of objects»]
[«action variable preposition» «description of values»]+
[in «description of rooms»]
[in the presence of «description of objects»]
[when/while «condition»]
[«recurrence condition» | «duration condition»]

The optional initial «actor» specifies who is doing the action (the actor) and whether it is requested. If omitted entirely, it means the player is doing the action. It can take one of the following possible forms:

«description of objects» [trying]
asking «description of objects» to try
an actor [trying]

The first form matches if the actor fits the description, but never matches when the actor is the player. The optional word “trying” is used for disambiguation, in case the last word of the description looks like an action participle. The second form matches if the player is requesting the action and the person asked fits the description. The third form matches any actor at all, but I believe it does not match requested actions. It must be the exact words “an actor” – if you write “actor” or “the actor” it will not work. I’m pretty sure there’s no reason to ever use “an actor trying”, but it does compile.

The «action list» can take the following possible forms, where «action» is either an action name preamble (the part before “it”, if the name contains “it”; otherwise the full name) or a named behaviour (also called a kind of action).

«action» [ (, | or | , or) «action»]+
doing something/anything [to/with]
doing it
doing something/anything (except | other than) «action» [, «action»]+ [ [,] or «action»] [to/with]

The special form “doing it” would more naturally be written as “doing so”, but unfortunately the compiler doesn’t understand the latter. In a rule preamble, it means the action described in the previously-declared rule, including its noun specifications (so adding noun specifications is not allowed in this form). I haven’t tested if this works similarly within a phrasebook.

The second form is a wildcard, matching anything at all. The last form is also essentially a wildcard, but a restricted one.

Specifying the noun and the second noun is done with a normal description of values. The “action preposition” used to introduce the second noun is part of the action name, the part that comes after “it”. When there are multiple actions, it must be the action preposition of the final action in the list. For example, “putting or inserting something into something” is correct, and “inserting or putting something on something” is correct, but “putting or inserting something on something” and “inserting or putting something into something” won’t work.

In both of the “doing something” forms, you can only specify the first noun as part of the description (the only way to constrain the second noun is with a when/while condition). Use of the preposition “to” or “with” when “doing something except” has a different effect than using no preposition. (This is mentioned in the documentation… I need to come up with a good example to illustrate it, because it’s a bit hard to describe.)

When using behaviours (kinds of action), you can’t specify the noun or second noun, because the behaviour could potentially contain various actions applying to various different nouns. You can mix behaviours and regular actions in a single description; I haven’t tested whether there’s any way to specify a noun or second noun just on the actions that aren’t behaviours.

Action variable clauses are introduced by the preposition defined for the specific action variable. Action variables without a “matched as” clause in their definition cannot be matched in action descriptions. After the preposition is a description of values matching the kind of the action variable, so it can be almost anything.

The location and presence clauses are pretty straightforward. The one thing you need to be careful about is that “in the presence of a person” will always match, because the player is a person and you are always in the presence of yourself. Thus you instead need “in the presence of a person who is not the player” or similar.

The conditional clause is just a regular condition. The one downside is that there’s no way to negate the entire condition, like “unless”.

The “recurrence clause” at the end is things like “for the first time”. The same clause can be used on a relation condition, so see the description of conditions for details of its format.

A description of actions is usually written in the present tense, but it can also be used in the past tense. In this case, just substitute the present participle with the corresponding past participle. Past tense descriptions are also more restricted – there can only be one action (“done something” is not supported), actions taking a second noun are not allowed, the first noun must be a specific object, and none of the optional clauses are permitted.

Composite Kinds

Kinds defined directly in the source text are simple kinds – they have a name, and that’s it. But Inform also understands a small number of composite kinds that can be built out of simple kinds.

Composite kinds have a concept of covariance and contravariance. Put simply, suppose you have a variable of a composite kind built out of a simple kind K. If the composite is covariant, that means that a composite built from a more specific type can be assigned to the variable. If the composite is contravariant, that means a composite built from a less specific type can be assigned to the variable.

For example, lists are covariant, which means you can assign a list of doors to a list of things variable, but you can’t assign a list of objects. On the other hand, activities are contravariant, so if you have an activity on things variable, you can’t assign it an activity on doors… but you can assign it an activity on objects, because an object is less specific than a thing.

The following is a full list of composite kinds that can be created:

list of «kind»
activity on «kind»
description of «kind»
«kind» valued property
«kind» valued table column
relation of «kind»
relation of «kind» to kind
nothing based rule/rulebook
nothing based rule/rulebook producing «kind»
«kind» based rule/rulebook
«kind» based rule/rulebook producing «kind»
phrase nothing -> nothing
phrase «kind» -> nothing
phrase nothing -> «kind»
phrase «kind» -> «kind»
phrase ( «kind» (, «kind»)+ ) -> nothing
phrase ( «kind» (, «kind»)+ ) -> «kind»

Lists, descriptions, properties, table columns, and relations are covariant, while activities are contravariant. Rules and phrases are a bit more complicated. A rule or rulebook is contravariant in its basis, but covariant in its production. Similarly, a phrase is contravariant in its parameters, but covariant in its return value.

I have not yet investigated how “nothing” fits into the co(ntra)variance system. As far as I’m aware, phrases need to at least have the same number of parameters, but I have not investigated that in detail, either.

Conditions

A condition (the text you write after “if”, “unless”, “when”, or “while”) can come in several different forms:

«conditional phrase»
[we are] [not] «description of action»
we have [not] «description of action in past tense»
«description of value» «relation verb» «description of values» [ «recurrence condition» | «duration condition» ]
«condition» and «condition»
«condition» or «condition»
( «condition» )

A conditional phrase refers to any phrase defined by “To decide if/whether”. There is no general way to negate a condition. Conditional phrases often (but not always) define a negated form of the phrase, however; and action and relation conditions have a built-in way to negate them.

Action conditions in the present can optionally take a “we are” prefix only when the action description doesn’t specify the actor. It is allowed for “asking to try” however. Action conditions that do specify the actor will usually need to add “trying” to disambiguate.

The most common relation verb used is “to be”, but any relation verb works in a condition as far as I know. The verb can be conjugated into simple/perfect, present/past, and positive/negative. The possible forms are as follows (using “to unlock” as an example):

Form Normal verb to be to be able to
Positive simple present unlock/unlocks is/are can
Negative simple present do/does not unlock is/are not cannot
Positive simple past unlocked was could
Negative simple past did not unlock was not could not
Positive perfect present has unlocked has been has been able to
Negative perfect present has not unlocked has not been has not been able to
Positive perfect past had unlocked had been had been able to
Negative perfect past had not unlocked had not been had not been able to

A recurrence condition can take the following forms:

once/twice/thrice
[for] «number» time/times
for at least/most «number» time/times
for «number» to «number» time/times

Keep in mind that «number» can be either a cardinal or ordinal number, so for example line 2 above covers both “for five times” and “for the fifth time”, which are equivalent.

These all match non-consecutive actions, simply counting how many times the action has been attempted . It counts unsuccessful attempts as well, so it’s best to use such clauses only in Before rules or occasionally in Persuasion or Instead rules. Every turn rules should also be safe.

A duration condition can take the following forms:

for «number» turn/turns
for at least/most «number» turn/turns
for «number» to «number» turn/turns

These all match consecutive actions, as if an implicit “in a row” were appended. (However, it’s not valid to explicitly add “in a row” on the end.) Though ordinals are technically supported here, I think it makes it sound misleading and would recommend cardinals only. (Would you guess without being told that “Before jumping for the fourth turn” triggers when you jump four times in a row?)

1 Like

You have passed through the third gate, and there is nothing left but for you to read the literate source: Action Patterns.

And may Knuth have mercy on your soul.

No, wait, there’s one thing left… be sure to read this reply regarding Action Patterns too.

2 Likes

To be perfectly honest, I don’t find that to be very useful. It’s good to see it, and it’s not like it’s too technical for me or anything, but it’s mostly just showing code with some brief, terse comments, and the code itself is fairly cryptic.

I actually saw that post already. It was pretty helpful and probably influenced my explanation of action patterns.


I’m planning to post an attempt at “every possible assertion that can be made” next, though I still haven’t finished compiling the list so I’m not sure when that’ll be. I might post something else in the meantime if it takes awhile.

I also just discovered (maybe rediscovered?) the haphazard attempt at a “sentence grammar” in example 223 (§13.9). I’m not sure to what extent that’ll influence my overview of assertions though; it’s perhaps a little too general to be broadly useful (as it rolls assertions, conditions, and now-conditions into a single category). It also seems like it might be incomplete – I’m not sure how “west of X is south of Y” would fit into that grammar, assuming that “west of” and “south of” count as prepositions. Plus it only covers simple sentences, and most assertions outside of basic structural sentences have special syntaxes that don’t fit well into that grammar.

It is a little frustrating how many cases there are that seem like they should work but don’t. Things like “when we have taken or dropped X” and “if we have taken the noun” seem like they should be relatively simple to resolve, but the compiler just gives up. In the former case, it seems obvious to me that it should expand to “when we have taken X or we have dropped X”, and in the latter case, well… why on earth would you want to ask “if we have taken the global variable called noun”? That’s how the compiler interprets it, yet it has a much more sensible and logical interpretation of “if we have taken whatever object is currently stored in the noun” that seems like it should be easy to check.

Graham needs a lesson on responsive web design.

1 Like

It is sensible to consider sentences in assertions, conditions, and imperatives as a single category. These are excerpts from the rules:

To if (c - condition) begin -- end conditional
        (documented at ph_if):
        (- {c}  -).
[...]
To now (cn - condition)
        (documented at ph_now):
        (- {cn} -).

Now there are verbs that mean different things in different contexts (to be, to have, to hold) and there are things that are semantically valid as one but not another (one of the most obvious being that only conditionals can have tenses other than present).

And it wouldn’t be Inform if there weren’t special cases. West of X is south of Y is an assertion but it isn’t really a sentence in the Example 223 sense because west of X and south of Y aren’t really description phrases.

To the extent there’s any documentation on this, it’s Mapping Hint Requests.

2 Likes

Hmm. Or it might be more accurate to say that they are sentences but that Example 223’s explanation of Description Phrases is lacking. I’m not sure.

1 Like

Okay, so now let’s talk about the syntax of assertions. First, before we get started, assertions and conditions both have something in common in their structure.

Generic Sentence Grammar As noted in §13.2, 90% of assertions can be boiled down to the following syntax:

«noun phrase» «verb» [«adverb»] «noun phrase»

Where the noun phrase looks something like this:

«adjective»* «noun»? «relative phrase»?

And the relative phrase looks something like this:

(«preposition» | «participle» | which/that «verb») «noun phrase»

Conditions also follow the same basic syntax. Note that all the components of the noun phrase are marked as optional, but that’s not quite accurate – you must have at least one component. Furthermore, some constructs are allowed only in certain contexts (only in assertions, or only in conditions). For example, “«relative phrase» «verb» «noun»” is not allowed as a condition, but is allowed as an assertion.

The verb is perhaps the most interesting part of this, because it can be put into several forms:

  • active or passive voice
  • positive or negative
  • past or present tense
  • simple or perfect
  • simple or progressive

Assertions however only allow the first two. They also allow simple or progressive tenses. Also, progressive seems to be unsupported in the passive voice and for the verbs to be and to be able to. Those two verbs also don’t support the passive voice. This kind of makes sense though, since most people wouldn’t use those forms anyway even if they are technically valid grammar.

I already posted a table of verb forms in the Conditions section, but that omitted progressive and passive forms, so here’s a more complete table. Or rather, three tables. I’m using the verb to carry as an example of a standard verb here.

Voice Tense Aspect Positive Form Negative Form
active present simple carries/carry do/does not carry
active present progressive is/are carrying is/are not carrying
active present perfect has/have carried has/have not carried
active present progressive perfect has/have been carrying has/have not been carrying
active past simple carried did not carry
active past progressive was carrying was not carrying
active past perfect had carried had not carried
active past progressive perfect had been carrying had not been carrying
passive present simple is/are carried by is/are not carried by
passive present perfect has/have been carried by has/have not been carried by
passive past simple was carried by was not carried by
passive past perfect had been carried by had not been carried by

Here’s the same table for to be, simplified to omit the unsupported forms:

Tense Aspect Positive Form Negative Form
present simple is/are is/are not
present perfect has/have been has/have not been
past simple was was not
past perfect had been had not been

And for to be able:

Tense Aspect Positive Form Negative Form
present simple can cannot
present perfect has been able to has not been able to
past simple could could not
past perfect had been able to had not been able to

Anyway, knowing the grammar at this generic level isn’t the most useful, so let’s go ahead and make a list of everything that you can assert. This means specifying which verb to use in most cases.

Structural Assertions

I’m defining “structural assertions” as ones that directly make a statement about the model world. They define the things that exist, and how they relate to each other.

Assertion sentences support the use of pronouns. They don’t have any concept of gender however – you can use him, her, or them if you want, but it’s no different from using it. All of these refer to the subject of the most recent sentence that had one. The pronoun here is also supported, and refers to the most recently defined room. That means you can write something like “the size of it is 21”. In fact, this is so common that you can omit “of it” entirely and just write “the size is 21”.

Anyway, let’s start with basic declarative assertions – those that explicitly define something in the world. These usually take forms like the following:

«name» is/are [«adjectives»] «kind».
There is/are [«number»] «kind» [called «name»].

Note: You can also write something like “The puddle is scenery” even though scenery is defined as an adjective and not a kind. I think this might be a special exception for scenery, but I haven’t investigated.

Those assertions aren’t particularly interesting. Most assertions specify a relation. Such assertions can take on a form like the following:

[«preposition»] «name» «verb» [«preposition»] «name» [called «name»]

That definition is perhaps a bit too abstract to be useful, so here are a bunch of examples:

Examples

The Harbour is south of the Shopping Mall.
The wood-slatted crate is in the Gazebo.
Mr Jones wears a top hat.
The crate contains a croquet mallet.
West of the Hadean Pits is the Elysian Fields.
On the table is a scrumptious meal.
Miss Felix is interested in Mr Jones.
Interested in videogames is Felix.
On the table is a thing.
Three things are in the box.
Miss Trombone hides the pencil.
On the table is a box called a bowl.
A supporter called a comfy armchair is in the lounge.
East of the Debris Room is nowhere.
West of Thames Street End is north of Fisher’s Row.
The attic is a dark room above the Parlour.
The sky is everywhere.

So the abstract definition could be broken down into the following (possibly incomplete) list of possibilities, most of them using the verb to be:

«room or door» is/are «direction» of «room or door».
«direction» of «room or door» is/are «room or door».
«direction» of «room or door» is/are «direction» of «room or door».
«direction» of «room or door» is/are nowhere.
Nowhere is «direction» of «room or door».
«noun» is/are «kind» «preposition» «noun».
«noun» «verb» «noun».
«noun» is/are «preposition» «noun».
«preposition» «noun» is/are «noun».
«preposition» «noun» is/are «kind» called «name».
«kind» called «name» «verb» «noun».
«backdrop» is/are everywhere.

That’s still pretty abstract, but in my opinion it does give a better idea of the kinds of things that are possible. Note in particular the case where it’s safe to put more than just a name after “called” – this will only work if there’s no other verb before “called” in the sentence. Also, consider a “preposition” here to be any sequence of words that could be placed after to be, so in particular, it could be a participle rather than an actual preposition, or it could be the passive voice.

For some further explanation, suppose you define the following verbs:

The verb to quark means the X relation.
The verb to be in front of means the Y relation.
The verb to be able to carp means the Z relation.

Now all the following sentence forms become viable as assertions:

thing A quarks thing B.
thing C is quarking thing D.
thing E is quarked by thing F.
quarked by thing G is thing H.
thing I is in front of thing J.
in front of thing K is thing L.
thing M can carp thing N.

Notice the apparent inconsistency that the passive voice is invertible but the progressive tense is not. Notice also that progressive is not supported for the verb to be, and to be able doesn’t appear to support even the passive.

The result of those statements, as shown by the relations command, is:

X relates various things to various things:
  Thing A  >=>  thing B
  Thing C  >=>  thing D
  Thing F  >=>  thing E
  Thing G  >=>  thing H
Y relates various things to various things:
  Thing I  >=>  thing J
  Thing L  >=>  thing K
Z relates various things to various things:
  Thing M  >=>  thing 

Relation assertions don’t just define a relation between two things. They can also implicitly define the things involved in the relation. For example, suppose “hides” is defined as meaning a relation applying to one person and one trinket. Then the statement “Miss Trombone hides the pencil” will also implicitly define Miss Trombone as a person and the pencil as a trinket. This also works for enumerated values instead of things; and if you use the name of a kind of object, it ends up creating an object that doesn’t have a name.

Note that a statement like “Three apples are in the box” won’t necessarily create three apples. If “apple” isn’t already defined as a kind, it will instead create a single thing called “Three apples”.

Next is property assertions – specifying that something has a particular property. These can take the following forms:

«noun» is/are «adjective».
«property» of «noun» is/are «value».
«noun» has/have «property» «value».

As a special case, you can write a quoted string as a sentence of its own, without any preamble. Usually, this is equivalent to setting the description property of the value or object currently referred to by the pronoun it. However, if the object in question is a non-scenery thing, it sets the initial appearance property instead. Note that this functionality is not limited to built-in objects (rooms, things, and scenes) – any value or object that can have a description will support this.

You can link multiple sentences together with and, as long as they have the same verb and either the same subject or the same object. That is, if you have sentences “X is Y” and “X is Z”, you can write them as one sentence, “X is Y and Z”. Similarly, if you have sentences “X is Z” and “Y is Z”, you can write them as one sentence, “X and Y are Z”. This may not work in every conceivable case though, and in particular should be avoided on sentences using called, as the compiler may interpret the and as part of the first object’s name instead.

Finally, it’s possible to mass-define things using a table. The syntax for that looks like this:

«kind» [«preposition» «noun»] is/are defined by «table name».

The optional preposition can specify a relation applied to every defined thing. It must be a various-to-one or various-to-various relation. This syntax works for kinds of objects and also for enumerated values.

I think there’s maybe something lacking in the above explanation. It really isn’t easy to just give a list of every possible format that an assertion can be expressed in, after all. The fact that you can invent arbitrary verbs to be used in sentences complicates things too.

Defining Kinds

Assertions can be used to define new kinds. The basic format for this is:

«name» is a kind of («base kind» | value).

The base kind can be either a previously-known kind of object (including object itself), or the special word value. You must define the base kind before you can define any subkinds. Note that kinds of value don’t have a tree, so this isn’t a consideration.

Usually Inform automatically guesses the correct plural form of a kind. However, you can override its guess as follows, or even define multiple plurals:

plural of «kind» is «plural kind».

By default, a custom kind of value is neither an enumerable nor an arithmetic value. However, such a kind cannot be used for anything, so to finish defining it you need to actually give it some values. There are two ways to do this. The first makes it a kind of enumerated value.

«name of kind of value» is/are «values».
«values» is/are «name of kind of value».

In fact, notice that declaring the values for an enumerated value is exactly identical to declaring the existence of an object. This means that any enumerated kind of value can be extended with additional values at the author’s convenience – there doesn’t appear to be any way to prevent this. (It is however disallowed for some built-in enumerated types, such as truth states.)

The second way is to make it an arithmetic kind. You can declare any number of formats for an arithmetic kind, but the first such declaration for any arithmetic kind cannot use the scaled up/down or equivalent to clauses (but scaled at is allowed, though mutually exclusive with with parts). This syntax is quite long, so I’ve split it across multiple lines.

«format specification»
[( [singular/plural] , [in «name»] )]
specify/specifies «kind of value»
[with parts «part specification» (, «part specification»)* |
scaled (at | up/down by) «number» | equivalent to «value of same kind»].

Format specifications are kind of really complicated, in that they can be almost anything imaginable – other than double quotes, there doesn’t seem to be any kind of restriction on the characters you can use in a format specification. Generally speaking, the specification will be broken down into sequences of digits and non-digits. Even a decimal point is treated as a non-digit, unless it’s followed by a zero, in which case it declares the type to be real-valued rather than integer-valued. (I_think_ that’s the rule, at least.) Similarly, if the first run of digits is preceded by a minus sign, it means you’re allowed to write negative values of the kind, but otherwise a minus sign is just treated as another character. The format specification can contain spaces but does not have to, so you can declare kinds with a compact specification like $99.99, or kinds that are written out in words like 99 feet 11 inches.

When breaking down the format specification, each run of non-digits is associated with the following run of digits as its preamble. Runs of digits after the first are also treated as limits on that component, so in the feet and inches example above it won’t let you set the inches to 12 or higher.

A format specification can be given a name with in (which enables you to convert values of this kind into this format for output) and can be declared to be either plural or singular. The plurality affects which form is chosen for saying values of this kind – it’ll choose a singular form if the value is 1 and a plural form otherwise (in English at least, I don’t know how that carries over to other languages).

The part specification can give a name to each of the components, and also set options for them. It’s a comma-separated list, each element of which looks like this:

«name» [( [[preamble] optional] , [without leading zeros] )]

If the segment is optional, it can be omitted entirely when writing values of that type. If the preamble is optional, both the segment and its preamble may be omitted. Without leading zeroes controls how the value is printed when the segment has fewer digits than the specification.

Lastly, by default it’s an error to multiply an arithmetic kind by anything other than a plain number, but you can specify how arithmetic kinds are multiplied together. At least one format specification must be defined before you can do this.

«kind» times «kind» specify/specifies «kind».

Note also that you can’t write “X divided by Y specifies Z”. Instead you have to rearrange it to write “Y times Z specifies X”.

You can define new properties for specific objects, kinds of object, or kinds of enumerated values. (Arithmetic values are not allowed to have properties.) This can be done using statements like the following:

«kind or value» can be [either] «adjective» [or «adjective»].
«kind or value» can be [either] «adjective» (([,] or | ,) «adjective»)+ [( this is its/her/his/their «name» property )].
«kind or value» has/have «kind» [called «name»].

The first form creates an either/or property. If the opposite is not specified, it defaults to prefixing not to the adjective. This form doesn’t necessarily need to define a new adjective – it can also be used to specify that an existing either/or adjective can be applied to the new kind. If the property already exists, you can use either the adjective or its opposite here, or you can use both; but specifying a different opposite from the already-existing one is not allowed.

The second form creates a new enumerated kind of value with the specified name (defaulting to suffixing condition to the name of the object or kind) and adds a property with the same name as the new kind. Though the syntax definition above doesn’t make this clear, it must have at least three alternatives. Also, the new kind can still be extended with additional possible values using separate assertions later on.

The third form creates a property of the specified kind with the specified name (defaulting to the same name as the property). Note that when a property has the same name as its kind, and the kind is an enumerated value, you can use the values of that kind as adjectives describing the object or value that has the property. However, if the property has a different name, you can’t use the values as adjectives.

You can control default values for properties or specify implications between either/or adjectives using statements like the following:

«kind or value» is/are «adverb» «adjective».
(«adjective» «kind» | «correlative pronoun» «adjective») is/are «adverb» «adjective».
«property name» of «kind or value» is/are «adverb» «value».
«kind or value» «adverb» «verb meaning a property» «value».

Correlative pronoun here refers to any of the pronouns beginning with “some” or “any”. The possible adverbs are:

usually/normally
seldom/rarely
always
never

But not all these adverbs are supported in every type of sentence, and in fact, only the first form (X is «adv» Y) supports all four. The second form (something X is «adv» Y) doesn’t support always or never, and the last two that work with arbitrary-valued properties only support usually/normally.

It’s possible to define a kind and give it properties in a single statement like this:

«name» is/are a kind of («base kind» | value) that/which is «adjective» (and «adjective»)*.
«name» is/are a kind of («base kind» | value) with «property name» «value» (and «property name» «value»)*.

Each of these rolls up three statements into a single sentence. If you write “X is a kind of Y that is Z”, it’s equivalent to the following three statements:

X is a kind of Y.
X can be Z.
X is usually Z.

Similarly, if you write “X is a kind of Y with Z W”, it’s equivalent to the following three statements, automatically inferring the kind of W:

X is a kind of Y.
X has a (kind of W) called Z.
The Z of X is usually W.

Defining a global variable looks a lot like a declaring an object, but with a few extra words:

«name» is/are «kind» (that varies | variable).
«name» is/are initially «value».

A variable previously defined using the first form can also be given an initial value without using the word initially.

You can also declare constants with a similar assertion:

«name» is always «value».

The word every can be added to a normal relation assertion (merging with correlative pronouns, if present, to become everything etc) to make a broad assertion about kinds. If both sides of the relation are a kind, this even implicitly defines instances of the kind on the opposite side as every so as to make the statement true – this is called “assembly”. The general form is like this:

(every «kind» | «universal pronoun») «verb» [«number»] «kind» [( called «name» )].
[«number»] «kind» [( called «name» )] «verb» (every «kind» | «universal pronoun»).
(every «kind» | «universal pronoun») «verb» «value».
«value» «verb» (every «kind» | «universal pronoun»).

The called clause, if present, generates names for the implicitly-defined objects, substituting any pronouns or possessive pronouns in the specified name with the name of the owning object, in the possessive if applicable. The supported pronouns are it, he, she, and they, together with their possessive forms. The called statement doesn’t work if you specify a number.

If you want, you can give names to Unicode characters. Usually this would be done by an extension though.

«name» translates into Unicode as «number».

This is pretty similar to the syntax to specify the I6 name of something.

«name» translates into I6 as «quoted I6 identifier».

I’m starting to wonder if this gets too wordy, but… I do think a lot of these quirks are better documented in-place rather than linking to the official documentation or something. Anyway, there’s still one more bundle of assertions to cover…

Defining Other Things

You can define new actions with the following syntax:

«name» is an action «action specification»

The action specification is a sequence of one or more of the following:

applying to nothing
applying to one [visible/touchable/carried] thing.
applying to two [visible/touchable/carried] things.
applying to one ([visible/touchable/carried] thing | «kind») and one ([visible/touchable/carried] thing | «kind»).
out of world
requiring light
with past participle «participle»

For obvious reasons, you can’t have more than one applying clause. Also, actions applying to two things must include the pronoun it somewhere in the middle of their name, which divides the name into two parts – the part after it is considered the preposition of the new action. Be careful – the compiler will accept a name ending in it, but it won’t be able to recognize the action in action descriptions, so this should be avoided.

Defining action variables looks almost exactly the same as defining properties:

«action name» action has «kind» called «name» [( matched as «quoted word» )].

The main differences are the matched as clause (which defines a preposition for matching this variable in action descriptions) and the fact that called is required.

You can group actions together as “behaviours” or “kinds of action”. The general pattern for this is as follows:

«description of action» is «behaviour name».

Such assertions for the same name are cumulative. The descriptions permitted for behaviours are a little limited – requested actions and actions with a specified actor (including an actor) can’t be added to behaviours.

A scene is just a regular enumerated value, so new scenes can be declared in the same way as other things. Specifying when they begin and end however use some special statements:

«scene» begins when «condition».
«scene» begins when play begins.
«scene begins when «scene» begins/ends.
«scene» ends [«ending name»] when «condition».
«scene» ends [«ending name»] when «scene» begins/ends.

A scene can have multiple begin conditions, but each ending can only be given a single condition. Fortunately, the when «condition» form is a full-fledged condition, so it can use and. It is possible to define a general (nameless) ending in addition to named endings; I’m not sure if this is useful however.

Relations can be defined as follows:

«name» relates various «kind» to various «kind» [with fast route-finding].
«name» relates one «kind» [( called «name» )] to various «kind» [with fast route-finding].
«name» relates various «kind» to one «kind» [( called «name» )] [with fast route-finding].
«name» relates one «kind» [( called «name» )] to one «kind».
«name» relates various «kind» to each other [with fast route-finding].
«name» relates one «kind» [( called «name» )] to another.
«name» relates one «kind» to another [( called «name» )].
«name» relates «kind» [( called «name» )] to kind.
«name» relates «kind» [( called «name» )] to «kind» [( called «name» )] when «condition».

The second-to-last form is particularly interesting in terms of whether Inform defaults to various or one. In fact, that relation will be one-to-various if a called clause is used and various-to-one otherwise. So it’s probably better to always specify whether each side is various or one. (I assume it’s also possible to omit one/various on one side but specify it on the other, but again, I wouldn’t recommend it.)

The form creating an equivalence relation (in groups) also accepts the with fast route-finding clause, but I think this is a mistake, as it doesn’t make sense to route-find through an equivalence relation (for any two things, there’s either no route at all, or a single-step route). Relations that don’t have various on at least one side will raise an error if you try to specify it.

It’s worth noting that a called clause in the definition of a non-calculated relation actually defines properties on the related kinds, which are automatically kept in sync with the relation. So, changing the relation updates the property and vice versa.

Verbs can be defined as follows:

To «verb» is a verb [( «conjugation» )].
The verb to «verb» [( «conjugation» )] means/implies ([reversed] «relation» | «property»).

Note that the name of a relation always ends in relation and the name of a property always ends in property. So, the second form will always end in one of those words. The first form defines a verb that is sayable but has no other meaning.

It’s also worth noting that defining a verb to mean a property also defines an implicit, nameless relation that automatically relates the holder of the property to its value, as if you had written something like the following:

My-property-relation relates a thing (called A) to a value (called B) when the «property-name» of A is B.

Despite not automatically defining them as verbs, Inform7 knows the conjugations of most English irregular verbs, so you usually don’t need to specify the conjugation manually. However, if you want to do so, it’s a comma-separated list of one or more of the following (I think they must also be in the specified order):

he/she/it «present singular»
they «present plural»
he/she/it «past»
he/she/it is «past participle»

I don’t think there’s any way to specify the present participle, probably because it’s always regular in English.

There are two special cases of verbs: to be, and to be able to. Inform7 has special handling for defining a verb that begins with either of those. It’s not permitted to specify the conjugation in this case.

If you define a verb beginning with to be (but not beginning with to be able to), then the sentence defines a preposition rather than a verb. Everything after to be in the definition becomes the preposition.

Similarly, if you define a verb beginning with to be able to, it’s defined not as a regular verb but as something that can follow can or could in a sentence.

You can create new rulebooks or activities with an assertion:

«name» rules/rulebook is/are «kind of rulebook».
«name» is/are «kind of activity».

This is pretty much a normal declaration, the only quirk being that the word something is treated specially in the name of an activity. Here a «kind of rulebook» or «kind of activity» uses the syntax explained in the Composite Kinds section.

Activities and rulebooks can both have semi-local variables. This looks exactly like adding a property to an object, except that the called part is required rather than optional:

«rulebook or activity» has/have «kind» called «name».

For rulebooks, you can specify the default outcome, or define a set of named outcomes. Both of these only work for rulebooks that don’t produce a value, with one exception – you can specify that a rulebook producing a value has default failure (or no outcome, which is the default anyway and thus redundant). (Though I say it’s not allowed, there’s a bug that the compiler allows you to do it anyway and then just does weird stuff at runtime, potentially even crashing.)

«rulebook» has/have default failure/success.
«rulebook» has/have default no outcome.
«rulebook» has/have outcomes «list of outcomes».

The list of outcomes is one or more of the following, joined by commas and/or and:

«name»
«name» ( success [- the default] )
«name» ( failure [- the default] )
«name» ( no outcome [- the default] )

Note that a named outcome corresponding to no outcome will never be treated as the outcome of a rulebook. Thus, it only serves to give a nicer name to the make no decision phrase when used in the rulebook in question.

I haven’t tested whether it works correctly to have multiple outcomes defined as failure.

Lastly, you can adjust the contents of an existing rulebook or conditionally control when rules trigger with statements like the following:

«rule» is listed [before/after «rule» | instead of «rule» | first/last] in «rulebook».
«rule» is not listed in («rulebook» | any rulebook).
«rule» (does nothing | substitutes for «rule») [when «condition»].

I think that pretty much covers every possible form of non-imperative assertion, and it really is a lot… but please let me know if you can think of something that I’ve forgotten. I’ll add imperative assertions (including Understand) in a later post.

1 Like

This looks good so far.

The general caveats, as I’m sure you’ve noticed, are:

  • Exactly what syntax are allowed and disallowed is pretty tightly tied to the underlying implementation. E.g. “Arithmetic values are not allowed to have properties” – because the implementation would require an extensible hash table or something like that, and Inform isn’t set up to do that. But it could. Similarly, the question of what kinds of relations are allowed grows directly from what mechanisms Inform has to store the data.

  • Because of that, any detailed syntax list is likely to change quite a bit from Inform version to version. This may not be obvious because we’re in an unusually extended period of stability. The transition from 9.3 to 10.1 was a low-level rewrite, so the user-facing syntax didn’t change much. (Aside from I6 inclusions.) But I would expect a fair number of changes when 10.2 hits.

  • (That’s a gut feeling. I haven’t gone over the Jira repository looking for what’s changed.)

Small comments:

You can also write something like “The puddle is scenery” even though scenery is defined as an adjective and not a kind. I think this might be a special exception for scenery, but I haven’t investigated.

Parallel to “The chest is open,” “The brass lamp is lit,” etc.

If you write “X is a kind of Y that is Z”, it’s equivalent to the following three statements:

I suspect there are lots of ways to combine assertions into a single sentence. But I prefer my Inform code to use the simplest sentences possible, so I haven’t explored this.

1 Like

Maybe I wasn’t quite clear. There is in fact a difference between “The puddle is scenery” and “The chest is open” – the latter will only work if Inform already knows what the chest is, while the former can be the line that defines the puddle – Inform infers it to be a thing.

You’re correct that they’re syntactically identical, though.

I find it a bit hard to imagine what the use-case would be for giving properties to an arithmetic value…

Hmm? Was there some kind of relation that’s not allowed? The options there seemed pretty comprehensive to me. Other than not being able to define new spatial relations, I guess.

Oh, whoops! I see what you mean.

The difference is that scenery is defined on things, and Inform is willing to assume that an unmentioned object is a thing. open is only defined on containers and supporters.

So you can say “The puddle is lit” or “The puddle is handled”, but not “The puddle is male” or “The puddle is openable.”

1 Like

Same as the use-case for defining relations on an arithmetic value. (Which you can do.) A property more or less is a various-to-one relation, although Inform doesn’t treat it that way.

Was there some kind of relation that’s not allowed?

Gah, I don’t know, I have never exhaustively dug unto relations. I may have been thinking of properties there.