[SOLVED] Failed actions take no time

Hello Informers,

I’m experimenting with a game idea where timing and strategic actions are critical. When in a tight spot, I want the player to be able to assess the situation without any time passing. This was easily accomplished following one of the documented recipes, but I have a more advanced problem I am unsure of how to solve.

In addition to some actions taking no time, I want failed actions to take no time, like trying to walk by a non-existent exit or taking a fixed in place thing.

Is there a place in some rulebook I can stick a rule that will prevent my advance time rule from firing in such circumstances? I’m not yet very familiar with rulebooks.

Something like this (pseudocode):

After performing any action:
    If the action failed:
        don't follow the advance time rule for this turn;

See this thread: https://intfiction.org/t/i7-can-i-understand-persuasion-as-a-mistake/5496/1

Thanks! I think I got the idea here; I can insert an early rule that sets a variable, and then have the every turn rule act depending on that variable. The question now is, how do I set this variable?

So, would something like this work? (pseudocode again)

After doing something:  [needs to run after every action, to see if it failed.]
    If the check rule of the action performed failed:
        now fail action is true;  [truth state set]

Then I’d check the “fail action” state in my advance time rule.

You could do that by modifying the code that runs the action processing rules (see chart) to set the I6 “meta” flag (which is normally set for out-of-world actions and mistakes) for any failed actions. Unfortunately, I don’t really see any way to do that without at least a bit of I6 coding.

If you want to do this all in I7, you could instead define your own flag variable to replicate the behavior of the I6 “meta” flag, which simply causes the turn sequence rules to be aborted after the action ends. Here’s a simple example of how to do that:

"White Rabbit" by Vyznev Xnebara

The story headline is "An Interactive Test".

Chapter 1 - Rules

The skip-rest-of-turn-sequence flag is a truth state that varies.

To skip this/the/a/-- turn: now the skip-rest-of-turn-sequence flag is true.
To skip this/the/a/-- turn saying (T - text): say T; skip the turn.

The modified generate action rule is listed instead of the generate action rule in the turn sequence rulebook.

This is the modified generate action rule:
	now the skip-rest-of-turn-sequence flag is false;
	abide by the generate action rule;
	if the skip-rest-of-turn-sequence flag is true, rule succeeds.

Chapter 2 - Testing

Wonderland is a room.

The player carries a pocket watch. The description of the watch is "The time is now [the time of day in words]. You're late!"

Every turn when the pocket watch is touchable: say "'Tick.'"

Instead of waiting or sleeping when the pocket watch is held, skip turn saying "You're late! There's no time to wait![paragraph break]"

Test me with "x watch / z / z / z / x watch / drop watch / z / z / x watch".

The code above defines the phrases “skip the turn” and “skip the turn saying”, which you can use in an action-processing rule to cause the rest of the turn sequence to be skipped.

Note that these phrases don’t automatically stop the action; if you use them outside “instead” rules (which stop the action by default), you’ll probably want to write “instead skip the turn” to do so. Also keep in mind that, unlike the I6 “meta” flag, this custom flag is not automatically saved and restored whenever an action calls another action using “try”. Thus, if any tried action sets the flag, the rest of the turn sequence will be skipped.

The I6 “meta” flag actually has other implications for actions. The pure I7 solution is preferable here.

Hey, that rules chart will come in handy!

Geting closer here I think! Using a flag works fine for my own actions, and if I’m redefining existing actions.

However, consider the following examples:

eat apple (when you have it)
Success. Action takes time.

eat apple (when you don’t have it)
Fail. No time taken.

eat chair
Also fail (different reason though). No time taken.

sit chair
Success. Uses time.

sit apple
Fail. No time taken.

The “turn takes no time” flag should somehow be set if the action doesn’t pass the check stage. Would it be possible to insert a rule between the check and carry out rules that sets the flag depending on the outcome of the previous (that is the check) rule?

Actually, yes, you can do it that way too:

The action-processing success flag is a truth state that varies.

The modified generate action rule is listed instead of the generate action rule in the turn sequence rulebook.

The record action success rule is listed before the carry out stage rule in the specific action-processing rulebook.

This is the modified generate action rule:
	now the action-processing success flag is false;
	abide by the generate action rule;
	if the action-processing success flag is false, rule succeeds.

This is the record action success rule: now the action-processing success flag is true.

You can replace the “Rules” section in my earlier example with this code (and change the “skip turn saying” to just “say”) and it should work.

A possibly surprising side effect of this implementation is that successful implicit actions will also allow time to pass; that is, if you enter the commands “drop watch”, “eat watch”, “eat watch” in sequence, the first eating attempt will take a turn (because the player picks up the watch before realizing that it’s inedible) but the second does not (because he already carries it). If this seems like a problem to you, consider implementing a “sanity check” rulebook like in Example 196: “Delicious, Delicious Rocks”.

Honestly, it would make a lot more sense if Inform considered the carrying requirements rule, which is where the implicit taking is handled, after the check stage rules. However, I suspect that simply moving the rule there might break some standard check rules which assume that, by the check stage, if the player doesn’t carry something it’s because he couldn’t pick it up. If you do want to try such a drastic change, though, here’s the code to do it (use at your own risk!):

The carrying requirements rule is listed before the carry out stage rule in the specific action-processing rules.
The carrying requirements rule is not listed in the action-processing rules.

NB: If you want to combine these two snippets, make sure the carrying requirements rule ends up before the record action success rule, otherwise actions that fail due to carrying requirements will still take a turn. (You can check this in the Inform IDE’s Index tab, under “rules”.) In fact, it might generally make more sense to record the success of the action before the “after” stage instead of the “carry out” stage, since at that point we can be sure that the action has been successfully completed.

I wrote an extension “After NOT doing something” which might be handy here.

inform7.com/extensions/Ron%20New … index.html

Thanks!
I was able to combine Ron’s extension with vyznev’s code, and it seems to work great!