[I7] Odd behaviour when using 'listed instead of'

At least it looks strange to me. When I use this code here

[code]Lab is a room.

Bob is a man in Lab.
The table is an enterable supporter in Lab.

Report getting off something (this is the new report player getting off rule):
say “You jump back on the floor.”;
ignore the describe room stood up into rule.

Report someone getting off something (this is the new report non-player getting off rule):
say “[actor] jumps back on the floor.”;
ignore the describe room stood up into rule.

The standard report getting off rule is not listed in the report getting off rulebook.

When play begins:
silently try entering table;
silently try Bob entering the table;
try getting off the table;
try Bob getting off the table.[/code]

I get the expected output

However, if I instead try to replace the standard report getting off rule with another one like this:

The the new report player getting off rule is listed instead of the standard report getting off rule in the report getting off rulebook

the new report player getting off rule suddenly fires for both the player and Bob and I get the following output

When I replace the two Report rules with this:

[code]Report an actor getting off something when actor is player (this is the new report player getting off rule):
say “You jump back on the floor.”;
ignore the describe room stood up into rule.

Report an actor getting off something when actor is not player (this is the new report non-player getting off rule):
say “[actor] jumps back on the floor.”;
ignore the describe room stood up into rule.[/code]

everything seems to work nice and dandy again. Is this supposed to be the standard behavior when replacing rules?

The “X rule is listed instead of Y rule” is somewhat unpredictable when the new rule has different conditions than the old rule. You will note that all of the examples never specify any conditions at all on the new rule - they are all written as “This is the new report player getting off rule:”. The replacement rule will inherit the preamble from the rule being replaced (in this case, “Report an actor getting off”).

In this case, because you don’t want “report an actor getting off” (You want a player-specific rule and an NPC-specific rule), the first approach is the correct one - add your new rules with your preferred preamble and explicitly remove the old one.

One thing, though - “ignore X rule.” is a phrase which is restricted to procedural rules (see 18.15 of the documentation). You should not be using it here (and in fact should not be using it at all, as procedural rules are deprecated). The preferred method here would be to add “instead” to the end of the previous phrase in order to terminate processing the rulebook.

Thanks a bunch for the quick reply!

But what do I do if I want to just skip a rule in between? Say if I actually want to use the describe room stood up into rule for an example. I got a special rule for getting off the table yet I don’t want to remove the standard rule for all other things while the standard rule still shouldn’t fire for the table specifically. How would I handle that? Other than removing the standard rule and replacing it with a conditioned copy (which could become a pain, once the conditions start piling up).

If you make your rule more specific it will override the general one, e.g. “Report getting off the table…”

You could also use the After rulebook, which is run before the Report rules and is generally used to print a different message in special cases like this (“After getting off the table…”).
The After rules are always followed, even if the action is performed silently, so “side effects” should usually be in After rules rather than Report rules.

Well, not exactly overriding it from my understanding but rather placing it before the more general rules in a rulebbok.

My issue is the apparent lack of possibilities to skip rules in a rulebook. Take this example:

Rule 1: A rule which should always be executed at the end of the rulebook. This could be a specific ending text or setting a truth state.

Rule 2: General rule. This one should execute whenever no further conditions are specified.

Rule 3: A conditioned rule.

Rule 2 and 3 exclude each other, meaning when Rule 2 is executed, Rule 3 should not and vice versa. Rule 1 on the other hand should get executed no matter what. I can’t see a way to make this work, except I get rid of Rule 2 and stick to conditioned rules or implement Rule 1 in Rule 2 and 3. Both options can get rather bulky, depending on the complexity of the rulebook.

On a completely unrelated note: is there any advantage to make carry out or report rules succeed other than exiting the current rulebook? ‘if rule succeeded’ for an action seems to ignore the two rulebooks completely.

This is the first rule: say “the end”.
After singing when the player is not in the Gallery (this is the second rule): say “general”.
After singing when the player is in the Gallery (this is the third rule): say “specific”.
The first rule is listed last in the after singing rules.

Unfortunately I don’t see a good way to avoid the condition in the second rule without introducing another rulebook for the second and third rules, which is called before the first rule.

You observe correctly. I7’s rule model doesn’t allow this. (I’ve tried to come up with a model that does, but I always wind up spiralling down into an algorithmic mess.)

I guess you could kludge this up a bit by setting flags for every rule you want to skip:

[code]Skipping the second rule is a truth state that varies.
First before: Now skipping the second rule is false. [this resets the flag at the beginning of the rules, before any rules get processed]

This is the first rule: say “the end”.
After singing (this is the second rule): if skipping the second rule is false, say “general”. [if you don’t want the rule to run at all, stick the condition in the preamble, though that might mess with rule priority]
After singing when the player is in the Gallery (this is the third rule): say “specific”; now skipping the second rule is true.
The first rule is listed last in the after singing rules.[/code]

Procedural rules are getting the chop because they’re very computationally expensive; the documentation explains that they have to run before every rule.

I would like it if the rulebooks came with an integrated blacklist where you can just dump rules you don’t want executed, which gets reset every time the rulebook ends. Kinda something like this:

[code]Lab is a room.
Second Lab is south of Lab.

Test Run is a rulebook. Test Run rulebook has a list of rules called blacklist.

A test run rule (this is the first rule):
say “The End!”.

The first rule is listed last in the Test Run rulebook.

A test run rule (this is the second rule):
if the second rule is listed in the blacklist, make no decision;
say “Standard”.

A test run rule when player is in Second Lab (this is the third rule):
say “Specified rule.”;
add the second rule to the blacklist.

When play begins:
follow the test run rulebook;
silently try going south;
follow the test run rulebook.[/code]

This works, although I get an unwanted line break for the skipped second rule. Don’t know how to avoid that. Plus here you still need to check within the rule itself whether it is listed or not. Ideally, the rulebook would check before even starting a listed rule but I’m not sure whether this would create the same performance issues like with procedural rules.

Another curious thing I found out though is that you can also actually write this:

[code]A test run rule when the second rule is not listed in blacklist (this is the second rule):
say “Standard”.

A test run rule (this is the third rule):
say “Specified rule.”;
add the second rule to the blacklist.

The third rule is listed first in the Test Run rulebook.[/code]

This will actually work as intended but once you try to specify rule three (like ‘when player is in Lab’) you suddenly get this error:

I guess that’s a bug?

Yes, that’s some kind of bug. You can work around it by having making blacklist a global (“The blacklist is a list of rules that varies.”) Of course if you want to do that for several rulebooks, you then need several global lists.

The whole blacklist idea seems more awkward than using explicit conditions, though.

It’s only really useful if you got an unconditioned rule that you want to get executed in an effort to avoid redundant code (in that case write ‘say “The End!”’ in the second and third rule). I’m not sure how often you got such a case to make it worthwhile though.

A global list would be preferable and I bet more space effective but I wouldn’t know how to reset it automatically at the end of a rulebook. I only know that you could write a special reset rule at the beginning of a rulebook but that’s a rather awkward approach.

I’ve never felt the need for such complex rules. I recommend more use of activities and actions.

I’m not sure how this would fix anything? :confused:

An activity’s “for” rulebook has the property that exactly one rule will run. So this is often a way to handle these situations; you define an activity with a general “rule for fooing”, and then more specific “rule for fooing when …” rules. The most specific applicable rule will run.

You can also define a rulebook and end each rule with “stop”. Again, the most specific applicable rule will run and then stop the rulebook.

Ok, thanks for clearing that up!