alan-if / alan-docs

Alan IF Documentation Project
https://git.io/alan-docs
Other
4 stars 0 forks source link

Mention Conditions that Can Abort Author Code #52

Open tajmone opened 5 years ago

tajmone commented 5 years ago

@thoni56,

I've realized that The ALan Manual doesn't clarify in the VERBs section that a failed LOCATE statement could interrupt (abort) the whole verb execution.

This is a source of confusion even among expert users, for example you'll find that the StdLib uses IF clauses after an implicit-taking to check that the implicit take succeeded. E.g. from lib_classes.i, verb give on liquid:

  VERB give -- LIQUID
    WHEN obj
    DOES ONLY
      -- >>> implicit take >>>
      IF THIS NOT IN hero
        THEN
          IF vessel OF THIS = null_vessel OR vessel OF THIS IS NOT takeable
            THEN "You can't carry" SAY THE THIS. "around in your bare hands."
            ELSE LOCATE vessel OF THIS IN hero.
              "(taking" SAY THE vessel OF THIS. "of" SAY THIS. "first)$n"
          END IF.
      END IF.
      -- <<< implicit take <<<

      IF THIS IN hero
        -- i.e. if the implicit taking was successful
        THEN
          "You give" SAY THE vessel OF THIS. "of" SAY THIS. "to" SAY THE recipient. "."
          LOCATE vessel OF THIS IN recipient.
      END IF.

The problem here is that there's no need to carry out that check, for if the LOCATE statement in the implicit-take action were to fail for any reason (e.g. the object is held by an actor) then the rest of the verb execution would be aborted, so there's no risk (nor chance) that the rest of the DOES body is executed anyhow — therefore the whole IF clause surrounding the final part of the verb is unneeded.

But besides the redundant code, the big risk is that authors might thing that they could handle failure of a LOCATE statement by carrying out alternative code via an IF clause, whereas that code is actually never executed! So, probably custom verbs that rely on a LOCATE statement should verify its failure conditions before attempting it, in case they need to carry out alternative actions if that is not viable (e.g. a specific message beyond that of the EXTRACT CHECK that would prevent dislocating the item).

Unfortunately, this aspect of Alan VERBs is not covered clearly in the Alan Manual. I think it's really important to clearly mention all the possible conditions that could interrupt the execution of a VERB body, and some tips on how to handle this in real case scenarios (especially, how to handle such code abortions in custom verbs).

For more info, see also:

This issue is also mentioned in:

tajmone commented 5 years ago

Not Only Verbs ...

Actually, this issue should deal with any sort of code execution planned by the author and which could fail due to some instructions failures. (issue renamed!)

In 5.1. A Turn of Events we find the description of all the type of executions that can take place on every turn, and their order of execution:

  1. Verbs
  2. Rules
  3. Scripts
  4. Events

Unfortunately, the Manual doesn't provide an explicit term to refer to all of them — whereas it would be useful to have one, especially when discussing this context — but we find mention of "execution of a sequence of statements" (e.g. in §3.7, spekaing of CONTAINER Limits properties).

NOTE: In §2.3. Alan Fundamentals » What’s Happening? we find a general resume of how verbs, events and scripts control dynamic aspects of an adventure.

Potential Execution Interrupting Instructions

Exits?

This needs to be tested, for I'm not sure if Exit gets executed only when traversing an Exit via a direction command or if it also applies to Locate statements within the adventure code (i.e. like Entered, which applies also to the Hero being relocated by the adventure code).

Current Manual References

Now, let's look at where we find mentions of this topic in the Manual, before deciding were we need to add more contents...

Container Limits

In 3.7. Properties » CONTAINER Properties » LIMITS we find (bold added):

If any of these limits are exceeded when trying to locate anything inside the container, the statements in the corresponding Else part will be executed and the players turn aborted. In fact, these checks are performed because of the execution of a Locate statement (usually as a result of the player issuing a command with the intent of placing something in a container). This means that the execution of a sequence of statements can actually be interrupted in the middle by these limitations.

In the above, the sentence "and the players turn aborted" seems to suggest that the whole turn ends — i.e. if failure occurs inside a Verb, no more execution context will be processed (i.e. Rules, Scripts and Events):

In 3.17. Statements » Manipulation Statements » LOCATE Statement we find (bold added):

Another special case is when locating something inside a container. The Locate statement will then cause the execution of the Limits of that container, and if any of the limits are exceeded the complete player turn is aborted immediately, resulting in no more statements being executed. So, if a player command should result in locating an object inside a container, it’s better to place the Locate statement as early as possible, as this enforces the Limits checks at the beginning of this player turn.

Containers Extract

In 3.7. Properties » CONTAINER Properties » EXTRACT we find (bold added):

The Extract clause, including optional Check and Does clauses, allows prohibiting the extraction of the item from the container depending on some condition. If the Check is present, it works the same way as for Verbs (see Sect. 3.10.3). I.e. a Check without a guard expression will unconditionally prohibit extractions; a Check with an expression will evaluate that expression and, if false, execute its Else clause, and then abort the move. The Does clause will be executed if the optional Check passes, or there was no Check.

Here "abort the move" implicitly means aborting the execution context that triggered the Extract — but it seems to imply (again) that also any other contexts will abort, which is somewhat unclear.

The sentence "abort the move" seems to indicate that the whole turn will be forfeited. (see my previous note)

Script Failure

In 3.7. Properties » SCRIPTs we find mention of Extract Checks causing abortion of SCRIPTs (bold added):

An actor continues executing its script until:

  • it reaches the end
  • another Use statement is executed for that actor
  • the actor is stopped using the Stop statement
  • something fails

NOTEThere are a few things that might fail when an actor executes. One example is an Extract, which means that something is removed from a container. As containers may define Extract Checks that action might be prevented. This means of course that that step is aborted, but also that the actor is automatically stopped, so no further steps from the script will be run. The author is responsible for handling this, e.g. by using rules to ensure that the condition is detected and handled correctly.

Here it mentions Extract as "one example" if failure causes, but doesn't provide a full list, nor a reference to where a full list can be found.