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

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.