What Rulebook?

This is the kind of thing that drives me crazy about Inform 7.

What I’m trying to do is produce an action from the command ‘bob, give me the wrench’. First I set up a persuasion rule:

Persuasion rule for asking Bob to try giving something to the player: persuasion succeeds.

But of course that doesn’t work, because the block giving rule gets in the way before the persuasion rule has a shot at it. So then I look in the manual to try to figure out how to override the block giving rule. The manual has several examples that show how to get rid of the block giving rule entirely, but that’s not what I want to do. I couldn’t find an example that shows how to override the rule in one specific case.

So I figure I need to write a new block giving rule that will be listed instead of the block giving rule. I know how to do that – except, what rulebook is the block giving rule in?

I search for it in the Standard Rules. I have no trouble finding it. But – what rulebook is it in??? The Standard Rules don’t seem to contain this nugget of information. It isn’t in the check giving rulebook – there is no such rulebook. If the error messages the compiler is giving me are to be believed, there is in fact a check rulebook – but the block giving rule isn’t in that rulebook. Nor is it in the action-processing rulebook. Nor is it in the specific action-processing rulebook.

Really, I need to ask two separate and distinct questions here.

First, where is the block giving rule? What rulebook is it in?

Second, how on Earth would the average author ever figure that out?

–JA

2 Likes

The action’s name is “giving it to”. So the rulebook is called check giving it to.

You can find the rules in the action tab of the index. There’s even an “unlist” button that copies the correct wording to the source: if you click on it a line that says “The block giving rule is not listed in the check giving it to rulebook” appears in the source.

You say you found this in the Standard Rules:

Check an actor giving something to (this is the block giving rule): stop the action with library message giving it to action number 3 for the second noun.

So, it’s in the check giving it to rules. (The action is called “giving it to”, not “giving”.) If you’re not good at mentally stripping the actor information from rule headers to get the rulebook name, you can just use the action rulebook to find the name of the action, and the associated rulebook will always be “check + action name”, e.g. check giving it to.

At present though, you don’t really have to delist the rule. If you create a more specific check rule, you can suppress the block giving rule momentarily:

Check Bob giving the wrench to: ignore the block giving rule.

…but I’m not sure whether using “ignore” is frowned upon.

–Erik

Yeah, I figured that out after posting the message. But…

Since I was looking for the name of a rulebook, I looked in the Rules tab instead of the Actions tab. Silly me.

My more general comment, after playing around with this action for a while longer, is that the rules governing it are just too tangled up. Transactions among characters should be among the easiest things to write in modern IF, not the most difficult.

This would be a dynamite thing to put in an extension. The author ought to be able to write stuff like:

Let Bob give things (except the wrench) to the player.
Let the player give the purse to Dorothy when Dorothy is amenable.
Let Steve receive the shirt and the motorcycle from anyone except David.
Let Dorothy refuse to take things from Bob saying “Oh, but your hands are too dirty. I’m afrraid you’ve soiled [the thing being offered].”

It really shouldn’t be any more complex than that, at the author code level.

–JA

I think it is – in the (5Z) docs it says that “ignore” should only be used in procedural rules, which of course are now deprecated. I’m not sure what’s wrong with using them in non-procedural rules.

Anyway, I agree with Jim about the obscurity of the rulebook names; if you find a rule in the index page, there ought to be something telling you what rulebook it’s in (short of clicking the “unlist” button, which is a non-obvious hack if you don’t actually want to unlist the rule). When I was tinkering with this I had the devil’s own time figuring out what rulebook the “describe what’s on scenery supporters…” rule was in, before realizing that I didn’t need to know. And the rulebook often has a weird name (mine is “for printing a locale paragraph about”), so figuring out from the rule is non-trivial, at least the first time.

1 Like

I’m not either, though probably ignoring a single rule is the least problematic case. I really hope that I7 retains something like this, because there really isn’t any reason why, returning to Jim’s example, you should have to replace the block giving rule just to make a single exception to it. But because a check rule’s success causes the entire action to stop (not just the check rules), that becomes necessary–you can’t write “check Bob giving the wrench to: rule succeeds” or you skip the carry out/report rules. “Ignore the block giving it to rule” really fits the bill, and I’d like to see it stay in the language even if it’s reduced in scope to, say, working only on rules in the same rulebook.

I don’t think that’s an accurate description of the index: if you’ve found the rule in the index, you’ve found the rulebook name too. Here’s the index entry that contains the “describe what’s on scenery supporters in room descriptions rule”:

For my money, the real problem is finding the rule names in the first place. If both the Standard Rules and the index were searchable—and the manual emphasized this search as something that authors should develop a habit of using—that would go a long way toward ameliorating the perennial “how do I block/unblock the default behavior?” problem. Here are some ways I’d like to see the index improved to address the broader issues that you and Jim are raising:

  1. Make the index searchable as part of the documentation search. When I type something into the search box, the list that comes up should include hits to the index even before hits to the manual or the recipe book. Search results should be subdivided by source (Index, Writing with Inform, Recipe Book, extensions, whatever) so you can go where you want to go at a glance.
  2. Link to the Actions Index from within the Rules Index. I’ve been burned, like Jim, in hunting through the Rules Index tab for action rules. It makes sense to list actions in their own tab, but it also makes sense to cross-link them from the Rules tab.
  3. The Rules tab is a bit confused at present. I usually stare at the subheadings for a while before making a choice, and I rarely pick the right one. I’m not sure what scheme would be better, but I haven’t found the current scheme particularly helpful.

–Erik

I did find the rule, but I still wasn’t able to come up with the rulebook name – I didn’t realize that I had to add the thing just after the doohickey (“for”) to the thing before the question mark (“printing a locale paragraph about”; the doohickey and question mark are visible in the index but not in Erik’s post, for those following along at home).

Anyway, as a newish I7 programmer, I can report that the way the index gives the rulebook name isn’t explicit enough for at least one newish programmer, even once you’ve found the right entry. Needs more idiot-proofing. (I confess that I didn’t even notice the “unlist” button, though I probably wouldn’t have used it anyway, since I was trying to come up with “The rule with the even longer annoying name is listed instead of the rule with the long annoying name in the convoluted name rulebook,” and I just used “is not listed in any rulebook” to unlist.)

I agree with you about making the index easier to search, tho’ the Standard Rules are searchable using a simple “find” once you’ve brought them up (which was something else I couldn’t figure out how to do for a while). I’m not sure I’d like them to come up in the documentation search; on my computer the documentation search is slow enough as it is (and annoyingly works backward through the examples when I usually want things in the main documentation). Maybe if you could turn the various components off and on it’d be good; in fact if you could turn off searching the examples that’d make me happy.

1 Like

Yeah, I guess you have to be familiar with activities to know that what you are seeing is the rulebook name (each activity has three rulebooks: for, before, and after). Ideally, of course, you would be familiar with activities before you have to start hacking them, but clearly it doesn’t work out that way in practice!

I’m not sure there’s an easy way to idiot-proof this, though; I wouldn’t like to see the index gummed up with a full restatement of the activity name each time, for example:

That just doesn’t seem like a good tradeoff to me. But maybe the full name could be provided using DHTML? A hyperlinked ellipsis maybe, and when you click on the link, the phrase expands:

Or maybe supplement the “unlist” button with a “replace” button that would paste in something like this “The XXX rule is listed instead of the describe what’s on scenery supporters in room descriptions rule in the for printing a locale paragraph about rules”? That’s less than elegant, given that the paste function has no way of providing the name of the replacement rule, but do you think it might help?

–Erik

The “replace” button sounds nice (though that doesn’t get us “the blah rule is listed before the blah rule in the blah rulebook”); you could have the cursor hop to the place where you need to type in the new name.

I agree that restating the activity name each time is ugly and actually I’m not sure it would be that helpful, since you’d still have to know that this is the rulebook name. What I’d really like would be for the index to explicitly say “rulebook” at the top of each of those panels; but this might be a problem, because the panel can actually contain up to three rulebooks. Perhaps it could name the rulebook at the top of each segment. So instead of

you’d get

Or there could just be some better explanation in the documentation. Section 18.5 actually seems to suggest that the rulebook name comes at the top, but that’s actually the activity name. You can realize what’s going on with enough study of the documentation, I guess, but that seems less than ideal.

I like the idea of a “replace” button simply for the fact that it gives you a good hint about what you need to do.

I’ve been confused about check rules, and I think I have an idea about why. Please correct me if any of this is wrong:

Before rules will override each other, with the most specific Before rule replacing any more general ones.

But Check rules are always in effect. If any check rule stops an action from happening, then the action cannot be permitted by another check rule. So all of the “block action” rules must be replaced with new Check rule, or overridden with a Before rule in order for an action to succeed. I’m not even sure if an Instead rule can do it.

I think of it in terms of Apache permissions protocols. Check rules have a “deny, allow” precedence where all of the “deny” conditions are checked first.

Am I right that Check rules and Before rules have fundamentally different ways of interacting with each other?

Here’s a quick overview of action rules:

The action sequence, the order in which the game runs the rules, is the following:

  • Before rules
  • Instead rules *
  • Check rules
  • Carry out rules
  • After rules *
  • Report rules

Instead and after rules, marked with a star above, stop the action by default. What this means is that the first instead/after rule the action sequence encounters will block everything that would come after it, unless the rule instructs otherwise. If there is an instead rule, only before rules and the instead rule will run and all others are skipped. If there is an after rule, all report rules are skipped.

You can make any of the rules stop the action sequence with “instead” or “stop the action”. This is most commonly done in the Check rules. Almost if not all standard library block rules (“block cutting”, “block drinking” etc) are check rules that have “stop the action”.

If there are multiple applicable rules of any kind, all of them will run, unless any of them stop the action sequence. This applies to every rule in every rulebook. (Remember that instead and after rules stop the action by default, but the others continue by default, including before and report rules.) Stopping the action sequence means stopping right there, without consulting any other action rules, so in practice it looks like as if the game would only follow the most specific instead rule. The order in which the rules run is decided by the specificity, this is discussed in manual chapter 18.18. The specificity rule of course applies only within the same type of rules, so a more specific carry out rule will never run before a less specific check rule.

Now, here’s a quick and dirty overview of how the rules “should” be used. In the end they’re just a bunch of rules in a specific order, so you could work with them however you want, but there are big benefits if the rules are used as they are designed to be used in that the design becomes more robust, easier to maintain and less error prone.

Before rules: The before rules are the first in the sequence so they are the strongest of them all. For the same reason they should be used with special care because they can easily introduce hard-to-notice bugs into the game. The common way to use before rules is to create implicit actions or redirect the action to another:

[code]
Before taking off the shirt when the player is wearing the jacket:
say “(first taking off the jacket)[command clarification break]”;
try taking off the jacket.

Before pushing a person:
say “(attack [the noun])[command clarification break]”;
try attacking the noun;
stop the action.[/code]
(Note how the second rule stopped the pushing action after the action had been directed to the attacking action.)

The before rules are also handy for restricting actions en masse:

Before doing something when the player is in the elaborate death trap and the action requires a touchable noun: say "You can't do that when your hands are tied!"; stop the action.

Check/carry out/report rules: These are the core action rules: check whether the action should be blocked; if not, carry out the game mechanics, then report to the player what happened. Note that none of these rules stop the action by default, so you have to remember to have “instead” or “stop the action” in the check rules that prevent the action and if you have multiple report rules make sure they don’t show the wrong messages. The core rules should handle only the general case.

After rules: The after rules override the report rules, so they are mostly used to give custom reports if the game mechanism is the same (for example, describing the taste of an edible thing after the eating action.)

Instead rules: The instead rules skip all rules except before rules, so they are used for exceptions. Literally, instead of doing what you would normally do with this action, do this instead.

So usually the action sequence is like this for the general case:

  • (before rules)
  • Check rules <-- if they pass, continue
  • Carry out rules <-- make changes to the world model
  • Report rules (or an after rule, if applicable) <-- tell the player what happened

And when there’s something that should be handled differently:

  • (before rules)
  • Instead rule <-- choose the most specific applicable instead rule, run it, stop the action

Now when it comes to replacing rules in the action sequence rulebooks, I very rarely do that. This might be a personal preference in design but I’ve preferred to build up and on top of the standard rules instead of replacing them and starting with an empty table. The only place where I mess around with the standard rules is the looking action where there’s a bunch of rules that print the room description, but even there the rules I modify are rarely part of the actual action sequence.

I hope that clarifies it a bit rather than messing it up even more.

1 Like

Basically, no. The rulebooks are run in a specific order, as Juhana indicates. If any of them ends with a “rule succeeds” or “rule fails”, then nothing else will happen after that. Each type of rule has a default outcome, which may or may not be one of those. You pretty much have to study Chapter 12 carefully to get it all sorted out in your head.

If two rules of the same type can apply to the same action, the compiler will put them in what it thinks is the correct order, with the more specific rule first. You can override the compiler’s decisions in various ways … but since you don’t get to see what it did, you have to guess about whether it made the right decisions based on what happens when you run your game. The rulebook assembly process and results are a “black box” from the author’s vantage point.

–JA

1 Like

If it compiles, can’t you see the order by looking at the Index? Assuming you can find the rule in the Index.

Exactly. This is the main reason for the existence of the Index. It not only tells you exactly how your rulebooks were ordered, but also how rooms were placed, how object names were interpreted, etc.

–Erik

That was a great explanation. It’s been a while since I read about rules in the manual, but if something like that is not in there already, it should be.

So the reason I’m getting the behavior I saw is not because of anything intrinsically special about Check rules, it’s just that the “block action” check rules are stopping the action. If such a rule exists that stops the action in every case, then it is impossible for a carry out rule to ever run for such an action. Hence the desire for an “ignore” line.

It may be reasonable to do all overriding of “blocked” actions with a Before or Instead rule, but there’s something unsatisfying about that. The case where I found this to be a problem was when an NPC is performing the action - because stopping the action for any reason produces an “unsuccessful attempt.” But I can imagine cases where normally blocked actions might become a more important part of a particular game. In such a case, you might want to write carry out and report rules. Maybe this would be a good time to unlist those block rules, but it would be nice to have some way to fall through to the block rule if something more specific fails to produce a successful attempt. Since every rule runs until something stops the action, this is currently impossible without “ignore”.

Perhaps there is some elegant way to say “proceed directly to the Carry Out rules now…” It could be limited to Check rules if that would make things safer.

Looking at this from the other direction, perhaps “block” rules could have some sort of “if no other check rule applies, stop the action with library message X…” clause.