let's play: Inform 10's Basic Inform and Standard Rules (Complete)

Not that it should, but it definitely could count as an answer. C compilers just call it “undefined behavior”. :grin:

“If you do this, well… don’t. We’re not responsible for what happens.”

That said, I’ve already done it long ago, and I seem to recall that it does, in fact, choose a different holdall if the previous one is full. Though, that said, I’m not 100% sure that I didn’t reimplement the holdall logic…

In seriousness, I think the answer is “there’s no guarantee which object will get chosen, so don’t rely on this behavior across versions”.

What really happens is that every turn, the “note object acquisitions rule” runs. This rule does four things:

  • Every object held by or worn by (note: not enclosed by) the player becomes “handled”
  • Every object enclosed by the player becomes “not undescribed”
  • For every player’s holdall that is held by or worn by the player, the SACK_OBJECT is set to that holdall
  • For every player’s holdall that is part of the player, the SACK_OBJECT is set to that holdall

Which means “part of” wins out over “held by” and “worn by”, but if multiple player’s holdalls are “part of”, or multiple player’s holdalls are “held by” and/or “worn by”, the value of SACK_OBJECT depends on the order that an objectloop iterates in. And I don’t know if Inter guarantees this order.

What I believe will happen in practice is that, for multiple “part of” holdalls, the one last defined in source code order will win (it’s an objectloop ofclass), and for multiple “held by” or “worn by” holdalls, the one that least recently moved to the player’s inventory will win (it’s an objectloop in). When an object’s parent is changed, that object becomes the first child of its new parent, so the last child will be the one that was added least recently.

But I think the better answer really is “don’t do that”. Player’s holdalls are already annoying to deal with on the player’s end: inserting things into them is automatic but taking things out of them is not, so you end up with a lot of > PUT APPLE ON TABLE “but you aren’t holding the apple!” unless you’re manually managing your inventory anyway, which is what player’s holdalls were meant to avoid. Having the behavior depend on which one least recently entered the inventory is just asking for trouble—or rather, just asking for players to get frustrated and say “your game is broken”.

Standard Rules: Variables and Rulebooks 5

We are still in this! I keep planning to make shorter posts, and then I do the opposite. But perhaps today I’ll stick to it. There is a natural stopping point coming up soon. Additionally, some rules run activities that we will be looking at later, which will also serve to keep things brief.


§29. Shutdown. Goodbye is not the hardest word to say, but it does involve a little bit of work. It might not actually be goodbye, for one thing: if this rulebook ends in success, then we go back to repeating the turn sequence rulebook just as if nothing had happened.

A bit of verbal playfulness to get us started!

  • (a) The “when play ends stage rule” follows the rulebook of the same name.

when play ends rules don’t see a lot of action in the documentation. In fact, it only appears in concert with resume the story.

Marbles, D, and the Sinister Spotlight took this opportunity to rewrite the contents of the status window, customizing its appearance during the ask the final question display.

 Objectives:                 Marbles, D          Important Landmarks:    
  - Snack                                          - Fish                
  - Chat                        & the              - Loretta             
  - Have Fun                                       - D                   
                         Sinister Spotlight        - Fweep
  • (b) The “resurrect player if asked rule” does nothing unless one of the “when play ends” rules ran the “resume the game” phrase, in which case it stops the rulebook with success (see above).

Repeat the Ending can end an astounding 38 ways, and 34 those endings resume immediately following. Would I do it the same way today? From a coding efficiency perspective, I probably could have handled things differently. But reading over the source code, it feels truer to say that the story ended and resumed. That must mean something!

In any case, I doubt this rule is frequently invoked.

  • (c) The “print player’s obituary rule” carries out the activity of nearly the same name (see below).

The activity in question will be discussed in the later Activities chapter.

  • (d) The “ask the final question rule” asks the celebrated “Would you like to RESTART, RESTORE a saved game or QUIT?” question, and acts on the consequences. It can also cause an UNDO, and on a victorious ending may carry out the “amusing a victorious player” activity (see below). The rule only actually ends in the event of a QUIT: an UNDO, RESTART or RESTORE is performed at the hardware level by the virtual machine and destroys the current execution context entirely.

Having written games that seldom ask the final question, I’m most aware of the challenges involved with editing the table of final question options directly. handling the final question actually carries out the will of the ask the final question rule, so we’ll revisit this one later as well.

The when play ends stage rule is listed first in the shutdown rulebook.
The resurrect player if asked rule is listed last in the shutdown rulebook.
The print player's obituary rule is listed last in the shutdown rulebook.
The ask the final question rule is listed last in the shutdown rulebook.

This is the when play ends stage rule: follow the when play ends rulebook.
This is the print player's obituary rule:
    carry out the printing the player's obituary activity.

The resurrect player if asked rule translates into Inter as "RESURRECT_PLAYER_IF_ASKED_R".
The ask the final question rule translates into Inter as "ASK_FINAL_QUESTION_R".

§30. Scene changing. Scene changing is handled by a routine called DetectSceneChange which is compiled directly by Inform: this is so primitive that it can’t even be handled at the template layer. The rulebook is all a little elaborate given that it contains only one rule, but it’s possible to imagine extensions which need to do book-keeping similar to scene changing and which want to make use of this opportunity.

I don’t fully understand the complexities here, since at the natural language level we are instructing Inform to start and stop scenes based on values. Under the hood, though, it seems that the reality is more complex. So far as inserting other rules into the rulebook goes, I cannot find an example either here or at the Friends of Inform repository.

Judging from a forum search, the most common use of scene changing rules is to force a scene change in the middle of action processing. I take no position on starting and stopping scenes during action processing! But… at that point using global variables would likely be a better fit for me, as I use a lot of after and every turn rules for daemon-like functions. I wouldn’t want to worry about skipping past all of that.

The scene change machinery rule is listed last in the scene changing rulebook.

The scene change machinery rule translates into Inter as "SCENE_CHANGE_MACHINERY_R".

§31. We couldn’t do this earlier (because creating a scene automatically generates two rulebooks, and that would have thrown the rulebook numbering), so let’s take this opportunity to define the “Entire Game” scene:

An observation: if an author ends the entire game, it will resume at the next execution of the scene change machinery rule.

Section 3 - The Entire Game scene

The Entire Game is a scene.
The Entire Game begins when the story has not ended.
The Entire Game ends when the story has ended.

I’ve promised a short post and, for once, I’ve delivered! Action processing comes next, and it only makes sense to discuss those rules within a single post.

It’s interesting to note that scene rules can either go in the generic “when scene begins/ends” rulebook or in a special “when scene X begins/ends” rulebook. The former is used for rules that match multiple scenes. Both are shown on the same page of the index, but in different sections.

The complexity is basically that none of the scene-changing machinery can feasibly be supplied in the I6 kits—it all needs to be built from scratch by the compiler, since the whole machinery is just a long series of “if X condition holds, then start this scene; if Y condition holds, then stop that scene; if Z condition holds…” None of that can really be provided without knowing which conditions and scenes are involved.

So the compiler builds the whole thing for us automatically rather than any of it being in the kits.

All you need is some sort of reflection system though? Then the entire scene changing machinery boils down to a simple loop:

repeat with s running through scenes:
    if starting condition of s applied is true:
        start scene s;
    repeat with end running through endings of s:
        if condition of end applied is true:
            end scene s with ending end;

The above is theoretically valid Inform7 code, but it assumes scenes have a few properties:

A scene has a phrase nothing -> boolean called starting condition.
A scene ending is a kind of value. game-end is a scene ending.
A scene ending has a phrase nothing -> boolean called condition.
A scene has a list of scene endings called endings.
To start scene (s - a scene):
    do nothing.
To end scene (s - a scene) with ending (e - a scene ending):
    do nothing.

And there are a few difficulties with actually making it work that way (using phrases as the conditions is probably suboptimal, for example), but the main point here is that it’s theoretically possible for the code to be identical for all games, rather than generated based on the list of scenes that exist.

I do understand why it’s done the way it’s done – it may even be simpler to do it that way. But it’s not an absolute necessity.

Standard Rules: Variables and Rulebooks 6

We’ve reached action processing!

§32. Action-processing. Action-processing happens on two levels: an upper level, handled by the main “action-processing” rulebook, and a lower level, “specific action-processing”. This division clearly complicates matters, so why do we do it? It turns out be convenient for several reasons:

Lots to look at here. I’ll break it up.

  • (a) Out-of-world actions like “saving the game” need to run through the lower level, or they won’t do anything at all, but must not run through the upper level, or in-world rules (before or instead rules, for instance) might prevent them from happening.

The documentation does not refer to actions operating at lower or higher levels, but we can infer that this refers to the rulebooks permitted by out of world actions: check, carry out, report. How could a higher level action have unexpected consequences for, say, restoring a saved game? We’d never get there if we prevented it with a

before doing something rule.

  • (b) Requested actions such as generated by a command like “CLARK, BLOW WHISTLE” have the reverse behaviour, being handled at the upper level but not the lower. (If Clark should agree, a definite non-request action “Clark blowing the whistle” is generated afresh: that one does indeed get to the lower level, but the original request action doesn’t.)

I haven’t done anything with persuasion rules, so I’m just feeling my way through this. It does seem true that action processing rules for asking [someone] to try [action] operate differently. For instance, this does what we expect it to do:

before asking bob to try jumping:
	say "Guncho!";

…as does an instead rule, but carry out and report rules have no apparent effect. Neither does upper level after. Having a look at the RULES output (abridged), it’s easy to see why:

>bob, jump
[Rule "declare everything initially unmentioned rule" applies.]
[Rule "generate action rule" applies.]
[Rule "announce items from multiple object lists rule" applies.]
[Rule "set pronouns from items from multiple object lists rule" applies.]
[Rule "before stage rule" applies.]
[Rule "basic visibility rule" applies.]
[Rule "basic accessibility rule" applies.]
[Rule "carrying requirements rule" applies.]
[Rule "instead stage rule" applies.]
[Rule "requested actions require persuasion rule" applies.]
Bob has better things to do.

Reading ahead, this is verified by the code below.

  • (c) Specific action-processing has a rather complicated range of outcomes: it must succeed or fail, according to whether the action either reaches the carry out rules or is converted into another action which does, but also ensure that in the event of failure, the exact rule causing the failure is recorded in the “reason the action failed” variable.

The documentation discusses the reason the action failed exclusively in terms of asking [someone] to try [action] scenarios. This makes sense. Failed player actions are halted. We can’t, for instance, say report taking the plover's egg when the action failed or some such thing. Isn’t that right? So far as the documentation goes, a primary use is customizing output for requested action failures.

In any case, for the purposes of phrases like if we have [verb], they only apply if an action has succeeded, i.e., reached the carry out phase.

  • (d) The specific action-processing stage is where we have to split consideration into action-specific rulebooks (like “check taking”) rather than general ones (like “instead”). To get this right, we want to use some rulebook variables, and these need to be set at exactly the correct moment. It’s tricky to arrange for that in the middle of a big rulebook, but easy to do so at the beginning, so we want the start of the SA-P stage to happen at the start of a rulebook.

Is there a distinction between action-specific and lower level? They seem to indicate the same things, though action-specific is more mechanical and less abstract. The action machinery will be looked at in greater detail later. Clarification: the action-specific rules pertain to lower-level rules, so mean more or less the same thing (see below).

This does mean that an attempt by the user to move the before stage to just after the check stage (say) will fail — the before and check stages happen in different rulebooks, so no amount of rearranging will do this.


§33. The upper level of action-processing consists of seeing whether the actor’s current situation forbids the action from being tried: does anybody or anything intervene to stop it? Are there are any basic reasons of physical realism why nobody could possibly try it? Does it require somebody else to cooperate who in fact chooses not to?

Doctrinally, the before stage must see actions before anything else can happen. (It needs the absolute freedom to start fresh actions and dispose of the one originally intended, sure in the knowledge that no other rules have been there first.) So before-ish material is anchored at the “first” end of the rulebook.

The other book-end on the shelf is provided by the instead stage, which doctrinally happens only when the action is now thought to be physically reasonable. So this is anchored at the “last” end. (In fact it is followed by several more rules also anchored there, but this is essentially just the clockwork machinery showing through: they aren’t realism checks.)

Miscellaneous general rules to do with physical realism are placed between the two book-ends, then, and this is where any newly created action-processing rules created by the user or by extensions will go.

Ok, here we see a distinction between action-specific rulebooks and lower level action processing in terms of intent. While after rules are non-specific, they arrive too late for interventions. And thus possible controversies regarding usages of instead versus before are born. So much has been said about the use of instead rules. The conventional wisdom advises against it. Repeat the Ending, my first game, certainly has its share of bad habits. What was its rule distribution like?

before: 95
instead: 337
check: 391
carry out: 482
after: 48
report: 12

Not bad! Things would be different today. Id use more before and check rules, certainly, though I’m still not a big report person.

Forgive this digression! For more thoughts on instead, see here.

Regarding “miscellaneous general rules,” I have in mind preambles like before doing something with the frob or even, more boldly, before doing something.

Section 4 - Action processing

The before stage rule is listed first in the action-processing rules.
The set pronouns from items from multiple object lists rule is listed first in the
    action-processing rules.
The announce items from multiple object lists rule is listed first in the
    action-processing rules.
The basic visibility rule is listed in the action-processing rules.
The basic accessibility rule is listed in the action-processing rules.
The carrying requirements rule is listed in the action-processing rules.
The instead stage rule is listed last in the action-processing rules. th from last.
The requested actions require persuasion rule is listed last in the action-processing rules.
The carry out requested actions rule is listed last in the action-processing rules.
The descend to specific action-processing rule is listed last in the action-processing rules.
The end action-processing in success rule is listed last in the action-processing rules.

§34. As we shall see, most of these rules are primitives implemented by the template I6 layer, but five are very straightforward.

I assume—none of my released games use the multiple object list in meaningful ways—that this setup sets pronouns from the last applicable item in the list. Is that right? Clarification: this pertains to the last relevant pronoun, so if there is both a “he” and an “it” in the list, the last relevant he and it are set as pronouns (see below).

Again, feeling my way through this, the announce items from the multiple object list prints the name of a noun before printing its corresponding action feedback. For instance, from a take all command, we get this debug feedback for each item constituting all:

>take all
[Rule “exclude people from take all rule” applies.]
[Rule “exclude people from take all rule” applies.]
[Rule “declare everything initially unmentioned rule” applies.]
[Rule “generate action rule” applies.]
[Rule “announce items from multiple object lists rule” applies.]

hat: [Rule “set pronouns from items from multiple object lists rule” applies.]

[Rule “before stage rule” applies.]
[Rule “basic visibility rule” applies.]
[Rule “basic accessibility rule” applies.]
[Rule “access through barriers rule” applies.]
[Rule “carrying requirements rule” applies.]
[Rule “instead stage rule” applies.]
[Rule “requested actions require persuasion rule” applies.]
[Rule “carry out requested actions rule” applies.]
[Rule “descend to specific action-processing rule” applies.]
[Rule “work out details of specific action rule” applies.]
[Rule “investigate player’s awareness before action rule” applies.]
[Rule “player aware of his own actions rule” applies.]
[Rule “check stage rule” applies.]
[Rule “can’t take yourself rule” applies.]
[Rule “can’t take other people rule” applies.]
[Rule “can’t take component parts rule” applies.]
[Rule “can’t take people’s possessions rule” applies.]
[Rule “can’t take items out of play rule” applies.]
[Rule “can’t take what you’re inside rule” applies.]
[Rule “can’t take what’s already taken rule” applies.]
[Rule “can’t take scenery rule” applies.]
[Rule “can only take things rule” applies.]
[Rule “can’t take what’s fixed in place rule” applies.]
[Rule “use player’s holdall to avoid exceeding carrying capacity rule” applies.]
[Rule “can’t exceed carrying capacity rule” applies.]
[Rule “carry out stage rule” applies.]
[Rule “standard taking rule” applies.]
[Rule “after stage rule” applies.]
[Rule “investigate player’s awareness after action rule” applies.]
[Rule “report stage rule” applies.]
[Rule “standard report taking rule” applies.]

Taken.

[Rule “last specific action-processing rule” applies.]

The item from the list gets this rule response "[current item from the multiple object list]: [run paragraph on]" (A). Much later, the report outcome from the taken action prints inline.

So far as abiding goes: these stage rules call the corresponding rulebooks and the results of those rulebooks apply to their parent rules. Our rules run in those rulebooks, and if we throw an instead in there, that will be that.

This is the set pronouns from items from multiple object lists rule:
    if the current item from the multiple object list is not nothing,
        set pronouns from the current item from the multiple object list.

This is the announce items from multiple object lists rule:
    if the current item from the multiple object list is not nothing,
        say "[current item from the multiple object list]: [run paragraph on]" (A).

This is the before stage rule: abide by the before rules.
This is the instead stage rule: abide by the instead rules.

§35. The final rule in the rulebook always succeeds: this ensures that action-processing always makes a decision. (I7’s doctrine is that an action “succeeds” if and only if its carry-out stage is reached, so any action getting right to the end of this rulebook must have succeeded.)

This is a way to guarantee that things get tied off. We aren’t obliged to manually end the report stage ourselves. Thank goodness! I would never remember to do that.


§36. The action-processing rulebook contains six primitives:

Another long section to work through in chunks.

  • (1) The “basic visibility rule” checks the action to see if it requires light, and if so, and if the actor is the player and in darkness, asks the visibility rules (see below) whether the lack of light should stop the action. (It would be cleaner to apply this rule to all actors, but we would need much more extensive light calculations to do this.)

As I’ve already conceded, I’m not familiar with Inform’s darkness machinery. This rule calls the visibility rules, so we’ll get to that in a bit.

  • (2) The “basic accessibility rule” checks the action to see if it requires the noun to be touchable, and if so, asks the accessibility rulebook to adjudicate (see the following post); then repeats the process for the second noun.

Thanks to some reckless experiments with scope, I have run against the basic accessibility rules many times! This rule also calls a rulebook, so I’ll defer discussion for now.

(3) The “carrying requirements rule” checks the action to see if it requires the noun to be carried. If so, but the noun is not carried, it generates an implicit taking action (in effect, "try silently taking "); and if that fails, then the rulebook is halted in failure. The process is then repeated for the second noun.

This rule executes an implicit taking action for something preferably held that is not carried. It’s almost always a kindness, though we don’t always have insight into its operation at the natural language level. Note that preferably held is not necessarily the same as held or carried.

See also Difference between holding and carrying relations

  • (4) If the action is one where the player requests somebody else to do something, the “requested actions require persuasion rule” asks the persuasion rulebook for permission.

Another rule calling a rulebook. Unlike the others above, though, this rulebook is one we fill with our own custom rules.

  • (5) If the action is one where the player requests somebody else to do something, the “carry out requested actions rule” starts a new action by the person asked, and looks at the result: if it failed, the “unsuccessful attempt by” rulebook is run to tell the player what has (not) happened. (If that does nothing, a bland message is printed.) In all cases, the original action of requesting is ended in success: a success because, whatever happened, the request succeeded in making the actor try to do something.

This rule spawns a new action attempt by an NPC (provided persuasion succeeds). That is, Bob, jump or the like. Failed requests are requests all the same, so we’ll wind up running through the turn sequence either way.


  • (6) The “descend to specific action-processing rule” really only runs the specific action-processing rulebook, but it’s implemented as a primitive in the template I6 layer because it must also find out which are the specific check, carry out and report rulebooks for the current action (for instance, “check taking” is the specific check rulebook for the “taking” action — which seems obvious from the names: but at run-time, the names aren’t so visible).

This is a slippery idea that I didn’t get for a long time, but the non-specific rulebooks like before contain every matching rule within them. In other words, before jumping and before waiting would all reside in the before rulebook.

In the case of specific actions, carry out for instance, carry out taking the carrot and carry out waiting would occupy separate rulebooks carry out taking and carry out waiting. This is only one reason why we can’t have a carry out doing something with the carrot rule: there is no carry out doing something rulebook.

So far as the descend to specific-action processing rule goes, we can’t (or shouldn’t) intervene, but we can know while debugging what out to precede and follow it. It additionally decides which rulebooks fire for which rules, but this is at a low level (meaning in the code, not the “lower level” discussed here), so hopefully that never comes up!

The basic accessibility rule translates into Inter as "BASIC_ACCESSIBILITY_R" with
    "You must name something more substantial." (A).
The basic visibility rule translates into Inter as "BASIC_VISIBILITY_R" with
    "[It] [are] pitch dark, and [we] [can't see] a thing." (A).
The carrying requirements rule translates into Inter as "CARRYING_REQUIREMENTS_R".
The requested actions require persuasion rule translates into Inter as
    "REQUESTED_ACTIONS_REQUIRE_R" with
     "[The noun] [have] better things to do." (A).
The carry out requested actions rule translates into Inter as
    "CARRY_OUT_REQUESTED_ACTIONS_R" with
    "[The noun] [are] unable to do that." (A).
The descend to specific action-processing rule translates into Inter as
"DESCEND_TO_SPECIFIC_ACTION_R".

§37. Specific action-processing. And now we descend to the lower level, which is much easier to understand.

It’s true. This is all straightforward, natural language stuff. I’ll be obliged to discuss the player's action awareness rules below. Hopefully I get it right! Otherwise, we’re seeing action-specific rulebooks kick off (except for oddball after, which manages to escape specific rulebooks despite it’s placement in specific action processing.

The work out details of specific action rule is listed first in the specific
action-processing rules.

A specific action-processing rule
    (this is the investigate player's awareness before action rule):
    follow the player's action awareness rules;
    if rule succeeded, now within the player's sight is true;
    otherwise now within the player's sight is false.

A specific action-processing rule (this is the check stage rule):
    anonymously abide by the specific check rulebook.

A specific action-processing rule (this is the carry out stage rule):
    follow the specific carry out rulebook.

A specific action-processing rule (this is the after stage rule):
    if action in world is true, abide by the after rules.

A specific action-processing rule
    (this is the investigate player's awareness after action rule):
    if within the player's sight is false:
        follow the player's action awareness rules;
        if rule succeeded, now within the player's sight is true;

A specific action-processing rule (this is the report stage rule):
    if within the player's sight is true and action keeping silent is false,
        follow the specific report rulebook;

The last specific action-processing rule: rule succeeds.

§38. The unusual use of “anonymously abide by” above is a form of “abide by” which may be worth explaining. Suppose rule
X consists of an instruction to abide by rulebook Y, and suppose that Y in fact fails when it reaches Yk. If the ordinary “abide by” is used then the action will be deemed to have failed at rule X, but if “anonymously abide by” is used then it will be deemed to have failed at Yk. (Thus X remains anonymous: it can never be the culprit.) We only use this at the check stage, because the carry out, report and after stages are not allowed to fail the action. (The after stage is allowed to end it, but not in failure.)

Whew! I had to think this one through. In cases of anonymity, the rule containing the abide by phrase is not credited with a rulebook’s failure. Instead, the specific failed rule receives the “blame.”

§39. The specific action-processing rulebook is probably more fruitful than the main one if we want to modify what happens. For instance:

This is the sixth sense rule: if the player is not the actor, say “You sense that [the actor] is up to something.”

The sixth sense rule is listed before the carry out stage rule in the specific action-processing rules.

…produces the message at a time when the action is definitely possible and will succeed, but before anything has been done.

This is an interesting construction! I had never considered “squeezing in” like this, but it’s a useful example.


§40. The only rule not spelled out was the primitive “work out details of specific action rule”, which initialises the rulebook variables so that they record the action’s specific check, carry out and report rulebooks, and whether or not it is in world.

This is presumably the rule that adjudicates which action-specific rulebooks are followed, ie, setting the specific carry out rulebook and the like. Or is it? The descend to specific action-processing rule gives a similar impression. Perhaps it’s just doing something with variables. Please feel free to chime in with corrections or advice! This rule takes the global variables set by the descend to specific action-processing rule and puts them in the relevant rulebook variables, the rulebooks have to be running before this can be done (see below).

The work out details of specific action rule translates into Inter as
"WORK_OUT_DETAILS_OF_SPECIFIC_R".

Goodness! We’ve made it through action processing, though there remain some rulebooks called by action processing to discuss. Let’s get to those next time, as this is a long post already. Once that’s done, I’ll update sample RULES debug output with more information.

Doing all of this has taught me a lot. Hopefully some readers are benefiting as well.

Basically the same thing. “Specific action-processing” is the name of the rulebook for the lower level.

This is the stage that I think deserves its own rulebook name. Dialog uses “refuse”. But given all the controversy over “instead” rules, maybe adding another name would just make things worse.

Strictly speaking it sets pronouns from each item in turn, so it’s possible for HIM, HER, IT, and THEM to each get set to a different item from the list. But the last one wins out.

The “descend to specific action-processing rule” is basically a jump table created by the compiler to find the appropriate rulebooks and store them in global variables, and then the “work out details of specific action rule” takes the rulebooks from those global variables and puts them in the rulebook variables. The split is necessary because the rulebook variables don’t exist until the rulebook is already running.

This is interesting to think about! I recall avoiding instead early on because experts were critical of it, though I didn’t really understand the distinction for quite a while. I think controversy can drive discussion, which can be helpful for people to read. But in this case, a new rulebook would be entering an already-fraught space!

Yeah, I’ve always felt the current system works pretty well (except for After trying to be two things at once):

  • Before: redirect one action to another, or special-case behavior that need to circumvent “refuse”
  • Action processing (“refuse”): check general plausibility in the world model
  • Instead: most special-case behavior goes here
  • Check: check plausibility for this specific action
  • Carry out: normal non-special-case behavior
  • After: ??? (see my previous posts)
  • Report: describe the results

Which means that a lot of things should, in my view, be Instead rules! (Though some of them should be Carry out rules that succeed.)

There isn’t much left in this chapter, and the majority of that remainder consists of parser errors. We’ll be through it in no time.

Standard Rules: Variables and Rulebooks 7

§41. Player’s action awareness. This rulebook decides whether or not an action by somebody should be routinely reported to the player: is he aware of it having taken place? If the rulebook positively succeeds then he is, and otherwise not.

It may or not be clear, but this seems to apply exclusively to the actions of other characters, unless we intervene. By default, the player is always aware of the player’s actions. This check is performed before the check phase, and again before report.

refresher: ``specific action-processing ``rules from the previous post
The work out details of specific action rule is listed first in the specific
action-processing rules.

A specific action-processing rule
    (this is the investigate player's awareness before action rule):
    follow the player's action awareness rules;
    if rule succeeded, now within the player's sight is true;
    otherwise now within the player's sight is false.

A specific action-processing rule (this is the check stage rule):
    anonymously abide by the specific check rulebook.

A specific action-processing rule (this is the carry out stage rule):
    follow the specific carry out rulebook.

A specific action-processing rule (this is the after stage rule):
    if action in world is true, abide by the after rules.

A specific action-processing rule
    (this is the investigate player's awareness after action rule):
    if within the player's sight is false:
        follow the player's action awareness rules;
        if rule succeeded, now within the player's sight is true;

A specific action-processing rule (this is the report stage rule):
    if within the player's sight is true and action keeping silent is false,
        follow the specific report rulebook;

The last specific action-processing rule: rule succeeds.

We can make eccentric interventions, of course, and blow the whole thing up for the player and everyone else.

lab is a room.

hat is in lab.

before taking the hat:
	say line break;
	say "oh, no.";
	say line break;

a first player's action awareness rule (this is the stupid rule):
	rule fails;

yields

>get hat
[Rule "declare everything initially unmentioned rule" applies.]
[Rule "generate action rule" applies.]
[Rule "announce items from multiple object lists rule" applies.]
[Rule "set pronouns from items from multiple object lists rule" applies.]
[Rule "before stage rule" applies.]
[Rule "before taking the hat" applies.]

oh, no.


[Rule "basic visibility rule" applies.]
[Rule "basic accessibility rule" applies.]
[Rule "access through barriers rule" applies.]
[Rule "carrying requirements rule" applies.]
[Rule "instead stage rule" applies.]
[Rule "requested actions require persuasion rule" applies.]
[Rule "carry out requested actions rule" applies.]
[Rule "descend to specific action-processing rule" applies.]
[Rule "work out details of specific action rule" applies.]
[Rule "investigate player's awareness before action rule" applies.]
[Rule "stupid rule" applies.]
[Rule "check stage rule" applies.]
[Rule "can't take yourself rule" applies.]
[Rule "can't take other people rule" applies.]
[Rule "can't take component parts rule" applies.]
[Rule "can't take people's possessions rule" applies.]
[Rule "can't take items out of play rule" applies.]
[Rule "can't take what you're inside rule" applies.]
[Rule "can't take what's already taken rule" applies.]
[Rule "can't take scenery rule" applies.]
[Rule "can only take things rule" applies.]
[Rule "can't take what's fixed in place rule" applies.]
[Rule "use player's holdall to avoid exceeding carrying capacity rule" applies.]
[Rule "can't exceed carrying capacity rule" applies.]
[Rule "carry out stage rule" applies.]
[Rule "standard taking rule" applies.]
[Rule "after stage rule" applies.]
[Rule "investigate player's awareness after action rule" applies.]
[Rule "stupid rule" applies.]
[Rule "report stage rule" applies.]
[Rule "last specific action-processing rule" applies.]
[Rule "A first turn sequence rule" applies.]
[Rule "scene change machinery rule" applies.]
[Rule "every turn stage rule" applies.]
[Rule "timed events rule" applies.]
[Rule "advance time rule" applies.]
[Rule "update chronological records rule" applies.]
[Rule "A last turn sequence rule" applies.]
[Rule "scene change machinery rule" applies.]
[Rule "adjust light rule" applies.]
[Rule "note object acquisitions rule" applies.]
[Rule "notify score changes rule" applies.]
[Rule "parse command rule" applies.]

Before and instead Rule before this check, so we still see output from our before rule.

A player's action awareness rule
    (this is the player aware of his own actions rule):
    if the player is the actor, rule succeeds.
A player's action awareness rule
    (this is the player aware of actions by visible actors rule):
    if the player is not the actor and the player can see the actor, rule succeeds.
A player's action awareness rule
    (this is the player aware of actions on visible nouns rule):
    if the noun is a thing and the player can see the noun, rule succeeds.
A player's action awareness rule
    (this is the player aware of actions on visible second nouns rule):
    if the second noun is a thing and the player can see the second noun, rule succeeds.

§42. Accessibility. The “accessibility” rulebook is not very visible to users: it’s another behind-the-scenes rulebook for managing the decision as to whether the actor can touch any items which the intended action requires him to be able to reach.

In its default configuration, it contains only the “access through barriers” rule. This in all circumstances either succeeds or fails: in other words, it makes a definite decision, and this is why it is anchored as “last” in the rulebook. If users or extensions want to tweak accessibility at this general level, any new rules they add will get the chance to decide before the “access through barriers” rule settles the matter. But in practice we expect most users to work with one of the two reaching rulebooks instead.

While this rule isn’t exposed to us, I believe this rule generally prohibits actions on items that were initially deemed to be in-scope but have more recently become inaccessible. Alternately, the rule also prohibit try phrases on out of scope things, since it can’t be clear what is or is not possible for a try during scope check (things move around, etc)

For instance:

lab is a room.

hat is in lab.
shoe is nowhere.

before taking the hat:
	now the hat is nowhere;
	
after jumping:
	try touching the shoe;

yields

>jump
That isn’t available.

>take hat
That isn’t available.

Section 5 - Accessibility

The access through barriers rule is listed last in the accessibility rules.

The access through barriers rule translates into Inter as
    "ACCESS_THROUGH_BARRIERS_R" with
    "[regarding the noun][Those] [aren't] available." (A).

§43. Reaching inside. What the access through barriers rule does is to try to construct a path through the object containment tree from the actor to the item needed, and to apply the reaching inside or reaching outside rulebooks each time this path passes inside or outside of a container (or room). (Supporters never form barriers.)

In Marbles, D, and the Sinister Spotlight, the player can go to rooms and things. Poor Marbles was always trying to reach into rooms! Everything worked out in the end, fortunately.

This restriction applies to actions that require a touchable noun.

The contents of closed opaque containers are not in scope, so one scenario applies to closed transparent containers. In the second case a check can fail if, for some reason, the chest closes after the scope check but before the relevant action.

We can fail reaching inside check in scenarios like this:

the glass box is a closed container in lab.
the glass box is transparent.
the frob is in the glass box.

the chest is a open container in lab.
the goody is in the chest.

before taking the goody:
	now the chest is closed.

Similarly, can't reach into rooms applies when a noun or second noun is in an out-of-scope room, even though the noun or second noun was in scope during the deciding the scope of activity.

before taking the hat:
	move the hat to closet.

Less frequently, this problem might arose if we manually add a room to the scope of the player, since that makes the contents visible, but not touchable.

In either case, we can make a reachability rule of our own if we want to head this sort of thing off.

The can't reach inside rooms rule is listed last in the reaching inside rules.
The can't reach inside closed containers rule is listed last in the reaching
inside rules. ast.

The can't reach inside closed containers rule translates into Inter as
    "CANT_REACH_INSIDE_CLOSED_R" with
    "[The noun] [aren't] open." (A).
The can't reach inside rooms rule translates into Inter as
    "CANT_REACH_INSIDE_ROOMS_R" with
    "[We] [can't] reach into [the noun]." (A)

§44. Reaching outside. And, not quite symmetrically since we don’t need to block room-to-room reaching on both the inbound and outbound directions,

While the documentation does not mention this possiblity, we can write our own reaching outside rules.

The can't reach outside closed containers rule is listed last in the reaching outside rules.

The can't reach outside closed containers rule translates into Inter as
    "CANT_REACH_OUTSIDE_CLOSED_R" with
    "[The noun] [aren't] open." (A).

§45. Visibility. The visibility rulebook actually has the opposite sense to the one the name might suggest. It is applied only when the player (not any other actor) tries to perform an action which requires light to see by; the action is blocked if the rulebook succeeds. (Well, but we could hardly call it the invisibility rulebook. The name is supposed to suggest that the consideration of visibility is being applied: rather the way cricket matches end with a declaration that “light stopped play”, meaning of course that darkness did.)

As the code below indicates, this is a straightforward check (perhaps evaluating something less straightforward). As the documentation indicates, we can write our own rules if we wish to head off the default result.

The can't act in the dark rule is listed last in the visibility rules.

The last visibility rule (this is the can't act in the dark rule): if in darkness, rule succeeds.

§46. Does the player mean. This rulebook is akin to a set of preferences about how to interpret the player’s commands in cases of ambiguity. No two Inform users are likely to agree about the best way to decide these, so we are fairly hands-off, and make only one rule as standard:

This has proven a very popular (!) subject over the years, and it does seem to be true that different authors have different preferences. Since I tend to have few objects in my games, I am usually successful in specifying nouns of choice (and discouraging them when that is better). But this gets hard to manage after a certain point. Actions involving two nouns tend to ignore our requests, so that is another topic of interest.

We begin with only one rule, as the code indicates. Authors can add more, and I always do.

Does the player mean taking something which is carried by the player
    (this is the very unlikely to mean taking what's already carried rule):
    it is very unlikely.

§47. And that completes the creation and stocking of the 25 rulebooks. More than half of them are initially empty, including before, instead and after — at the end of the day, these rulebooks are hooks allowing the user to change the ordinary behaviour of things, but ordinariness is exactly what the Standard Rules is all about.

I appreciate this statement of purpose, here. Making a game in large part does consist of interventions into the ordinary.

§48. Adjectives applied to values. There is a small stock of built-in adjectives for values.

cf WI 10. Scenes

Section 6 - Adjectival definitions

A scene can be recurring or non-recurring. A scene is usually non-recurring.
The Entire Game is recurring.

§49. Scene descriptions. And there is one build-in value property for values.

I’ve always printed my own text with a when [scene] begins rule, but an alternative is to declare a scene’s description. That prints at the beginning of a scene automatically.

Section 7 - Scene descriptions

A scene has a text called description.
When a scene (called the event) begins (this is the scene description text rule):
    if the description of the event is not "",
        say "[description of the event][paragraph break]".

§50. Command parser errors. This abstracts a set of return codes from the I6 parser, which are written there as constants with the notation *_ETYPE.

The documentation specifies a means for intervening during the printing a parser error activity. While these constants are listed in the documentation, there is no reference for identifying what prints when.

Section 8 - Command parser errors

A command parser error is a kind of value. The command parser errors are
    didn't understand error,
    only understood as far as error,
    didn't understand that number error,
    can only do that to something animate error,
    can't see any such thing error,
    said too little error,
    aren't holding that error,
    can't use multiple objects error,
    can only use multiple objects error,
    not sure what it refers to error,
    excepted something not included error,
    not a verb I recognise error,
    not something you need to refer to error,
    can't see it at the moment error,
    didn't understand the way that finished error,
    not enough of those available error,
    nothing to do error,
    referred to a determination of scope error,
    noun did not make sense in that context error,
    I beg your pardon error,
    can't again the addressee error,
    comma can't begin error,
    can't see whom to talk to error,
    can't talk to inanimate things error, and
    didn't understand addressee's last name error.

The latest parser error is a command parser error that varies.
The latest parser error variable translates into Inter as "etype".

§51. Internal rules. These rules do nothing in themselves, and are really just hooks on which some response texts can be hung.

Rather than writing printing a parser error rules, I prefer writing custom rule responses. In every game that I’ve released, I’ve written my own parser error responses. It’s extra work, but I spend a lot of time on narrative voice. Some of these parser error messages seem to be apocryphal. I’ll include my own template for editing default messages (parser, action, and everything else) at the bottom of the post..

Section 9 - Responses for internal rules

The list writer internal rule translates into Inter as
    "LIST_WRITER_INTERNAL_R" with
    " (" (A),
    ")" (B),
    " and " (C),
    "providing light" (D),
    "closed" (E),
    "empty" (F),
    "closed and empty" (G),
    "closed and providing light" (H),
    "empty and providing light" (I),
    "closed, empty[if serial comma option is active],[end if] and providing light" (J),
    "providing light and being worn" (K),
    "being worn" (L),
    "open" (M),
    "open but empty" (N),
    "closed" (O),
    "closed and locked" (P),
    "containing" (Q),
    "on [if the noun is a person]whom[otherwise]which[end if] " (R),
    ", on top of [if the noun is a person]whom[otherwise]which[end if] " (S),
    "in [if the noun is a person]whom[otherwise]which[end if] " (T),
    ", inside [if the noun is a person]whom[otherwise]which[end if] " (U),
    "[regarding list writer internals][are]" (V),
    "[regarding list writer internals][are] nothing" (W),
    "Nothing" (X),
    "nothing" (Y).

The action processing internal rule translates into Inter as
    "ACTION_PROCESSING_INTERNAL_R" with
    "[bracket]That command asks to do something outside of play, so it can
    only make sense from you to me. [The noun] cannot be asked to do this.lose
    bracket]" (A),
    "You must name an object." (B),
    "You may not name an object." (C),
    "You must supply a noun." (D),
    "You may not supply a noun." (E),
    "You must name a second object." (F),
    "You may not name a second object." (G),
    "You must supply a second noun." (H),
    "You may not supply a second noun." (I),
    "(Since something dramatic has happened, your list of commands has been
    cut short.)" (J),
    "I didn't understand that instruction." (K).

The parser error internal rule translates into Inter as
    "PARSER_ERROR_INTERNAL_R" with
    "I didn't understand that sentence." (A),
    "I only understood you as far as wanting to " (B),
    "I only understood you as far as wanting to (go) " (C),
    "I didn't understand that number." (D),
    "[We] [can't] see any such thing." (E),
    "You seem to have said too little!" (F),
    "[We] [aren't] holding that!" (G),
    "You can't use multiple objects with that verb." (H),
    "You can only use multiple objects once on a line." (I),
    "I'm not sure what ['][pronoun i6 dictionary word]['] refers to." (J),
    "[We] [can't] see ['][pronoun i6 dictionary word]['] ([the noun]) at the moment." (K),
    "You excepted something not included anyway!" (L),
    "You can only do that to something animate." (M),
    "That's not a verb I f American dialect option is
        active]recognize[otherwise]recognise[end if]." (N),
    "That's not something you need to refer to in the course of this game." (O),
    "I didn't understand the way that finished." (P),
    "[if number understood is 0]None[otherwise]Only [number understood in words]nd if
        of those [regarding the number understood][are] available." (Q),
    "That noun did not make sense in this context." (R),
    "To repeat a command like 'frog, jump', just say 'again', not 'frog, again'." (S),
    "You can't begin with a comma." (T),
    "You seem to want to talk to someone, but I can't see whom." (U),
    "You can't talk to [the noun]." (V),
    "To talk to someone, try 'someone, hello' or some such." (W),
    "I beg your pardon?" (X).

The parser nothing error internal rule translates into Inter as
    "PARSER_N_ERROR_INTERNAL_R" with
    "Nothing to do!" (A),
    "[There] [adapt the verb are from the third person plural] none at all available!" (B),
    "[regarding the noun][Those] [seem] to belong to [the noun]." (C),
    "[regarding the noun][Those] [can't] contain things." (D),
    "[The noun] [aren't] open." (E),
    "[The noun] [are] empty." (F).

The darkness name internal rule translates into Inter as "DARKNESS_NAME_INTERNAL_R" with
    "Darkness" (A).

The parser command internal rule translates into Inter as
    "PARSER_COMMAND_INTERNAL_R" with
    "Sorry, that can't be corrected." (A),
    "Think nothing of it." (B),
    "'Oops' can only correct a single word." (C),
    "You can hardly repeat that." (D).

The parser clarification internal rule translates into Inter as
    "PARSER_CLARIF_INTERNAL_R" with
    "Who do you mean, " (A),
    "Which do you mean, " (B),
    "Sorry, you can only have one item here. Which exactly?" (C),
    "Whom do you want [if the noun is not the player][the noun] [end if]to
        [parser command so far]?" (D),
    "What do you want [if the noun is not the player][the noun] [end if]to
        [parser command so far]?" (E),
    "those things" (F),
    "that" (G),
    " or " (H).

The yes or no question internal rule translates into Inter as
    "YES_OR_NO_QUESTION_INTERNAL_R" with
    "Please answer yes or no." (A).

The print protagonist internal rule translates into Inter as
    "PRINT_PROTAGONIST_INTERNAL_R" with
    "[We]" (A),
    "[ourselves]" (B),
    "[our] former self" (C).

addendum: my template for Inform’s default responses.
Default Responses Template.i7x (53.6 KB)


That was our longest section yet, but we have reached the end of Variables and Rulebooks at last.

  • Basic Inform: Preamble
  • Standard Rules: Preamble
  • Basic Inform: Miscellaneous Definitions
  • Standard Rules: Physical World Model
  • Standard Rules: Variables and Rulebooks
  • Standard Rules: Activities
  • Standard Rules: Actions
  • Standard Rules: Command Grammar
  • Basic Inform: Phrase Definitions
  • Basic Inform: Adjectival Definitions
  • Standard Rules: Phrase Definitions

Next up: Activities. I’ve been dreading the printing the locale description activity all along, but we can’t put it off any longer!

It’s performed twice specifically for actions like “going” that move the actor from one place to another. That’s also why it gets its own rulebook: to make it convenient to call the whole thing twice.

This means if you add an action for (say) throwing a thing in a direction, which moves it to the next room in that direction, the player will witness the action if they see the start or the end of the throw.

If an action applies to a “thing” instead of a “visible thing”—that is, if an action requires touchability—then this rulebook determines whether that thing can be touched or not. It’s also run every time you explicitly ask if something is touchable. If you try to take something that’s inside a glass case, for example, this rulebook is the one that shuts down the action. (The thing is in scope, since it’s visible through the glass.)

I think trying to act on an off-stage thing is the only way to trigger the fallback “that isn’t available” message, though, because normally reaching inside and reaching outside give more informative messages.

Indeed, calculating “in darkness” is a whole ordeal, but one that’s almost entirely at the I6 level. So generally no need to worry about it.

Sadly, the answer is to read the I6 documentation, since that’s where all these different errors are inherited from. To make matters worse, some of them (as far as I can tell) are completely impossible in I7!

Of course, going! I’ve never worked with other actors, so it’s a bit of a mind shift for me.

It’s going to take longer to cover this ground than the actual code would suggest, because it is relying heavily on the documentation for explanations. That’s fine! We’ll get there. I stopped just before the parsing activities. Next time!

Standard Rules: Activities

§1. These must not be created until the basic rulebooks are in place, because creating any activity automatically creates three rulebooks as well.

The srules template expects the following activities to be created and in this order. (That is, the order here must exactly match that of the *_ACT constant definitions made in Definitions.i6t.) The activities are fairly completely described in the Inform documentation, so the only notes here concern implementation.

suggest that built-in activities may or may not be thoroughly defined in Writing with Inform. It likely depends on what one is trying to do. Things come into better focus when paired with the information in this chapter, so it is helpful (it helps me, at least) to consider what is here both with and beyond the contents of the documentation.

Part Four - Activities

§2. Issuing responses. Responses are textual replies made by rules, and while one could imagine uses for them outside of an IF-like dialogue, they belong better in the Standard Rules (i.e., as an aspect of IF) than in the general-purpose language. So STANDARD_RESPONSE_ISSUING_R is in srules, not basicinform, and we define:

A bit of an esoteric beginning! Here’s what the documentation has to say about the issuing the response text of something activity. A useful observation for us, having learned a bit of Basic Inform, is that the documentation distinguishes between defined rule responses and what we might just call texts that are said. Basic Inform, if I understand the matter, does the former but not the latter.

The default rule is listed last in the for rules (we discover that here), so we can work around that or otherwise intervene. In practice, though we have several ways of customizing responses without engaging with response text at the activity level. The documentation says as much: “This activity should be used only if it’s important to amend blocks of responses in some systematic way.”

Nevertheless, this part of the documentation is where we learn about rule responses generally, so we need some level of understanding before we can leverage those other, simpler methods!

The activity contains only one rule by default, and it is in Inter.

Section 1 - Responses

Issuing the response text of something -- documented at act_resp -- is an
activity on responses.

The standard issuing the response text rule is listed last in for issuing the
response text.

The standard issuing the response text rule translates into Inter as
"STANDARD_RESPONSE_ISSUING_R".

§3. Naming and listing. We start with a piece of unfinished business. The “printing the name” activity was created by Basic Inform, but we need to add a rule to its before rule which marks any item whose name is being printed with the “mentioned” property, for reasons to be found below.

This would make less sense if we had not found our way here through Basic Inform! The Basic Inform printing the name of something activity contains only one Inter rule. As promised, the difference is the addition of the mentioned property, which is used with the printing the locale description activity. Basic Inform has neither rooms nor locales, and its objects do not provide the mentioned property.

The reasoning may not be immediately clear, but the printing a number of something activity is declared in this same section of the rules. The activity doesn’t just print numbers. It prints listing group size (number of items grouped together in a list) then calls the printing the plural name of something activity.

I note that printing the plural name of something does not declare things mentioned. That must be handled elsewhere, unless I’ve missed something.

Section 2 - Naming and Listing

Before printing the name of a thing (called the item being printed)
    (this is the make named things mentioned rule):
    if expanding text for comparison purposes, continue the activity;
    now the item being printed is mentioned.

Printing a number of something (documented at act_pan) is an activity.

Rule for printing a number of something (called the item) (this is the standard
    printing a number of something rule):
    say "[listing group size in words] ";
    carry out the printing the plural name activity with the item.
The standard printing a number of something rule is listed last in the for printing
a number rulebook.

§4. When they occur in room descriptions, names of things are sometimes supplemented by details:

printing room description details and printing inventory description details produce similar outcomes. The primary distinction is suggested by the activity names themselves.

I do not see the default rules for these activities listed here, but if convention is adhered to they are probably last for rules in their respective rulebooks.

Printing room description details of something (documented at act_details) is an activity.
Printing inventory details of something (documented at act_idetails) is an activity.

§5. Names of things are often formed up into lists, in which they are sometimes grouped together:

listing contents of something receives more treatment in the documentation than does the typical activity. However, that’s largely because of its potential involvement with other activities. For instance, it’s possible to have a rule like

rule for printing the name of the frob while listing contents

The rulebook can invoke different group phrases that in turn run the grouping together something activity (the actual to group definitions are all in I6).

group phrases are used in before listing contents rules. Grouping must occur before the actual list output is generated!

Listing contents of something (documented at act_lc) is an activity.
The standard contents listing rule is listed last in the for listing contents rulebook.
The standard contents listing rule translates into Inter as "STANDARD_CONTENTS_LISTING_R".
Grouping together something (documented at act_gt) is an activity

§6. And such lists of names are formed up in turn into room descriptions. Something which is visible in a room can either have a paragraph of its own or can be relegated to the list of “nondescript” items at the end.

This activity is significant within the wider scope of the printing the locale description activity, but an author need not understand that apparatus to use writing a paragraph about something. Thinking back to Repeat the Ending, I am embarrassed to admit that I only understood the activity near the end of development, so I awkwardly set the locale priority of relevent things to 0 instead.

Both are ways to prevent items from being accounted for while listing contents of rooms while at the same time displaying custom texts. New and intermediate authors, please don’t do what I have done. Use writing a paragraph about something instead.

Writing a paragraph about something (documented at act_wpa) is an activity.

§7. When these paragraphs have all gone by, the nondescript items left over are more briefly listed: the following activity gets the chance to change how this is done.

Like the activity before, listing nondescript items of something is a foretaste of the printing the locale description yet to come. Similarly, it affords a way to intervene in part of that activity without tackling the whole thing.

It can be used to customize the “you can also see” sentence listing, well, nondescript items that succeeds a room’s description, either entirely or at the item level. The activity by default contains one I6 rule that we can either work around or contravene.

Listing nondescript items of something (documented at act_lni) is an activity.

§8. Darkness behaves, for room description purposes, a little as if it were a room in its own right. Until the 1990s that was almost always how darkness was implemented in IF programs: this persists in I6, but not I7, where the existence of a room-which-is-not-a-room would break type safety.

I’ve already confessed that I have no experience with darkness of the Inform variety. However, this suite of activities does what the names promise: print various texts related to dark locations and actions in dark locations.

There are rule responses related to darkness. It might be better to customize the player’s encounter with darkness via text rather than through rules, but that’s likely down to authorial preference. I’ll list the relevant parts of the documentation for reference’s sake:

printing a refusal to act in the dark
printing the announcement of darkness
printing the announcement of light
printing the name of a dark room
printing the description of a dark room

Printing the name of a dark room (documented at act_darkname) is an activity.
Printing the description of a dark room (documented at act_darkdesc) is an activity.
Printing the announcement of darkness (documented at act_nowdark) is an activity.
Printing the announcement of light (documented at act_nowlight) is an activity.
Printing a refusal to act in the dark (documented at act_toodark) is an activity.

The look around once light available rule is listed last in for printing the
announcement of light.

This is the look around once light available rule:
    try looking.

§9. Two special forms of printing: the status line at the top of the screen, refreshed every turn during play, and the banner which appears at or close to the start of play:

constructing the status line won’t, by itself, offer many opportunities to the natural language author. In fact, the documentation example treats it more as referent than thing in itself, for instance

The Temple Of A Thousand Mightily Peeved Deities is a room. Rule for printing the name of the Temple while constructing the status line: say "Temple".

The constructing the status line activity does not so much construct as it does populate it. This small program, for instance, invites us to contemplate the difference between nothingness and absence:

lab is a room.
		
rule for constructing the status line:
	do nothing;

Some additional customization is available via Basic Screen Effects by Emily Short, which is installed with the Inform 10 IDE.

I have manually handled printing the banner text in every game that I’ve released. Repeat the Ending has a long (relatively speaking, it isn’t so long in the abstract) prologue after which the banner text prints.

Lab is a room.
the description of lab is "Wow, this is some lab!"
		
the display banner rule is not listed in any rulebook;
	
after looking for the first time:
	follow the display banner rule;

yields

lab
Wow, this is some lab!

Welcome
An Interactive Fiction
Release 1 / Serial number 260722 / Inform 7 v10.1.2 / D

Constructing the status line (documented at act_csl) is an activity.
Printing the banner text (documented at act_banner) is an activity.

I think that’s a good place to stop. It’s taking a fair bit of time to get through the code here because It’s necessary to jump back and forth between the Standard Rules and the docs, but we’re making progress. Next up: parsing activities.

I’m very fond of that technique too. I think putting a bit of establishing action before the banner text makes it land more effectively, like when TV shows have the title sequence after the first scene of the episode.

If nothing else, I like to move the banner after the intro text.

:100: Definitely nice to set the mood a little before the credits.

This may or may not be coincidence, but all of the top five or six Inform games at IFDB do something before the printing the banner text activity runs. In most cases, this is likely accomplished with a when play begins: say... rule, but many of them (Counterfeit Monkey, Hadean Lands, Eat Me) additionally ask questions of the player, or offer up tutorial information. Anchorhead boasts a Trinity-style “boxed quotation” screen.

Many include `wait for any key`` prompts for dramatic effect.

I think there are both utilitarian and narrative cases for printing text before the banner. My favorite usage is for dramatic effect, as we’ve been discussing, Portrait with Wolf is the only game of mine (released or in progress) that prints the banner before introductory text, because I thought the player should know for certain what the real bibliographic information is.

My favorite kind of opening text has a narrative stinger. Perhaps something unexpected or emotionally charged thing happens all at once, and then the camera “cuts to title” suddenly. I enjoy this technique in film as well.

oops, published too soon. stand by

Progress remains slow. There’s just a lot to work through here.

Standard Rules: Activities 2

§10. Parsing activites. Now a brace of activities to intervene in how the command parser does its parsing, arranged roughly in chronological order of their typical use during a single turn of a typed command, its parsing, and final conversion into an action.

The unusual notation “(future action)” here allows Inform to parse rule preambles for these activities in a way which would refer to the action which might, at some point in the future, be generated — during parsing we don’t of course yet know what that action is, but there is always a current guess at what it might be.

Some authors—perhaps even I—will be disappointed to learn that they cannot spackle “future action” all over the after reading a command rulebook, but it’s probably for the best.

There are a lot of activities listed, so let’s break them up a bit.

Section 3 - Command parsing

Reading a command (documented at act_reading) is an activity.

Speaking of which, there it is! The reading a command activity is mostly used to manipulate the player’s input before it is parsed. It’s also a way to “drop out” of command parsing to solicit specific inputs. As anyone who’s messed around with that sort of thing knows that it can be a lot of trouble. Consider the effort involved in solicititing the answer to one question at the beginning of Counterfeit Monkey :slight_smile:

After reading a command during identification (this is the parse identification rule):
	unless the player's command matches "restore":
		if stored first name is "nothing":
			now stored first name is the player's command;
			now stored first name is stored first name in sentence case;
			replace the regular expression "\p" in stored first name with "";
			if stored first name is "Alexandra":
				say "That's our joint name now, yes. I was Alex before the synthesis. You were...";
			otherwise if stored first name is "Alex":
				say "No, I'm Alex. Together we're Alexandra; before our synthesis, you were...";
			otherwise if stored first name is "Andra":
				say "Exactly right. And I'm Alex, making us jointly Alexandra. As far as I can tell, the operation was a success. We're meant to be one person now, unrecognizable to anyone who knew us before.[paragraph break]";
				custom-wait for any key;
				say "[banner text]";
				say "[paragraph break]Let's try to get a look around. I haven't been able to run our body without your help, but maybe now you're awake, it'll work better.";
			otherwise if stored first name is "No" or stored first name is "N":
				say "To review, we're Alexandra now. I was Alex, before the synthesis. You were...";
			otherwise if stored first name is "Yes" or stored first name is "Y":
				say "Right, we're Alexandra now. Before the synthesis, I was Alex. You were...";
			otherwise:
				say "...er, no. We're Alexandra now. Before the synthesis, I was Alex. You were...";
		otherwise:
			now new first name is the player's command;
			replace the regular expression "\p" in new first name with "";
			now new first name is new first name in sentence case;
			if new first name is "Andra":
				say "...yes! Okay. We're both here, neither of us lost our minds in the synthesis process. ";
			otherwise:
				say "...oh boy. Okay. Okay. I need you on form here. This is going to be hard if you don't remember being Andra. Not panicking. ";
			say "As far as I can tell, the operation was a success. We're meant to be one person now, unrecognizable to anyone who knew us before.[paragraph break]";
			now stored first name is "Andra";
			custom-wait for any key;
			say "[banner text]";
			say "[paragraph break]Let's try to get a look around. I haven't been able to run our body without your help, but maybe now you're awake, it'll work better.";
		follow the scene changing rules;
		reject the player's command;

Deciding the scope of something (future action) (documented at act_ds) is an activity.

The player’s scope has come up before, since it is entangled with visibility and acessibility. Authors don’t—or probably shouldn’t get involved with the default scoping rules. The documentation provides examples for extending, or adding items to, the player’s scope with after rules.


Deciding the concealed possessions of something (documented at act_con) is an activity.

We’ve discussed concealment a great deal already, so I’ll just provide a link to the relevant documentation.


Deciding whether all includes something (future action) (documented at act_all) is an activity.
The for deciding whether all includes rules have outcomes it does not (failure) and it does (success).

The built-in rules for the activity are listed below, so let’s defer for now.


Clarifying the parser's choice of something (future action) (documented at act_clarify) is an activity.

This activity produces the say [noun]" output below:

>take
(hat)
Taken.

Anecdotally, I haven’t seen a great deal of customization for this activity. Writing with Inform helpfully reminds authors that the player’s action is not entirely fixed at many points in the parsing process. It’s useful to bear this in mind with regard to most parsing activities.

4. A note about actions. This activity takes place during the process of understanding the player’s command, when the action that will take place is not fully known. So if the player types “TAKE SHOEBOX”, this activity would happen when SHOEBOX is being examined for meaning. Inform knows that the action will be taking, but nothing else. That means attaching a proviso like “… while taking a container” to a rule for this activity will cause the rule to have no effect - whereas “… while taking” would be fine.


Asking which do you mean (future action) (documented at act_which) is an activity.

Documented customizations of asking which do you mean behavior include prefacing that familiar question as well as customizing the printed names of things while the activity is running. It has no advice for brazenly writing one’s own for rule. Elsewhere, the “Walls and Noses” example does just that, though its use of I6 might be a bit spicy for natural language authors.


Printing a parser error (documented at act_parsererror) is an activity.

Most of Writing with Inform’s treatment of the printing a parser error activity is a list of the error themselves. These are mostly in natural language, though it may not always be clear what is triggering what! We’ve discussed this quite recently, so there’s no need to pursue that further.

We can write our own parser error messages—rather awkwardly— with constructions like rule for printing a parser error when the most recent parser error is can only do that to something animate error, but most authors will likely write their own rule responses.

There are some interesting possibilities for after rules that I’ve never really thought about, like tracking errors for some curious use or for debugging information. I’ve never heard of such usages, though.


Supplying a missing noun (documented at act_smn) is an activity.
Supplying a missing second noun (documented at act_smn) is an activity.

Writing with Inform documents both of these activities at once, so we may as well follow its lead. I imagine that this activity confuses new authors. It confused me, at least. These activities are triggered when the author has provided incomplete command grammar for an action. For instance:

frobbing is an action applying to one visible thing.
understand "frob" as frobbing.

This absence provides authors with a higher degree of customization opportunities than might a does the player mean, for instance, though that isn’t the only possible use.


Implicitly taking something (documented at act_implicitly) is an activity.

This one gets a fair bit of discussion on the forum. The documentation’s examples of intervention into the implicitly taking something activity, as it should, since this is automated behavior that can, as-is, produce undesirable effects.


§11. Here are the default rules for the behaviour of ALL:

This is a helpful bit of reference. The default inclusions and exclusions are not listed in the documentation, but we can find them here:

Rule for deciding whether all includes scenery while taking or taking off or removing (this is the exclude scenery from take all rule): it does not.
Rule for deciding whether all includes people while taking or taking off or removing (this is the exclude people from take all rule): it does not.
Rule for deciding whether all includes fixed in place things while taking or taking off or removing (this is the exclude fixed in place things from take all rule): it does not.
Rule for deciding whether all includes things enclosed by the person reaching while taking or taking off (this is the exclude indirect possessions from take all rule): it does not.
Rule for deciding whether all includes a person while dropping or throwing or inserting or putting (this is the exclude people from drop all rule): it does not.

We can make our own rules here, of course, and a lot of authors will.


§12. The supplying activities are linguistically interesting, for reasons gone into in the paper “Interactive Fiction, Natural Language and Semantic Analysis”: English verbs do not naturally seem to feature optional nouns. Indeed, we say “it rained on Tuesday” where “it” refers to nothing at all, merely because we can’t bring ourselves to leave a gap and say just “rained on Tuesday”. A better example here would be “it sounded like rain”, because we do the same to convey the idea of listening ambiently rather than to any single thing: listening appears to be rare among actions in that it can equally well take a noun as not. Just as English handles this problem by supplying a spurious “it” which appears to mean “the world at large”, so Inform handles it by supplying the current location, with the same idea in mind. And the same applies to the sense of smell, which can be similarly defocused.

I hope someone does a let’s play of the paper one day! I might have a nearly good background for it, but who knows when I’ll finish this? I think listening ambiently does mean listening to the environment around the listener, so the rules for ambient listening reflect our shared reality rather than a linguistic eccentricity. I could be wrong! I parse “it sounded like rain” as a more comprehensible and apt way to phrase “the place where I was sounded like rain,” since we never mean “it sounded like rain two counties over.”

I suppose I should be careful around linguists; we have at least one here! Nevertheless, this passage may or may not contradict my earlier assertion that choosing a first or second noun is an opportunity for customizing noun selection, as it here seems meant to address something more ethereal. In any case, here are the default rules for smelling and listening. touchability ceiling is not mentioned in the documentation at all, though presumably this is a way to handle enterable containers and such.

Rule for supplying a missing noun while an actor smelling (this is the ambient odour rule): now the noun is the touchability ceiling of the player.

Rule for supplying a missing noun while an actor listening (this is the ambient sound rule): now the noun is the touchability ceiling of the player.

§13. The following rule is something of a dodge to provide a better parser response to commands like GO or BRETT, GO. (Putting the rule here, and giving it a name, allows the user to override it and thus accept the idea of vague going after all.)

This usage is better aligned with the cases I outlined above.

Rule for supplying a missing noun while an actor going (this is the block vaguely going rule): say "You'll have to say which compass direction to go in." (A).

§14. Implicit taking is delegated to the I6 template:

We can write our own responses here, if we wish, but that’s likely it.

The standard implicit taking rule is listed last in for implicitly taking.

The standard implicit taking rule translates into Inter as "STANDARD_IMPLICIT_TAKING_R" with
    "(first taking [the noun])[command clarification break]" (A),
    "([the second noun] first taking [the noun])[command clarification break]" (B).

I think that’s a good stopping point for today. I had hoped to make it through the printing the final question, but this is a lot to digest already.