I have run into a bit of strangeness with the Standard Rules extension (version 3/120430) in 6M62. While using Object Response Tests by Juhana Leinonen to look for ways to improve a game, the wearing the noun test consistently results in an implicit taking of the noun. This is particularly distressing when the noun is a person and definitely not wearable.
I looked at the Standard Rules, and sure enough there is a “can’t wear what’s not clothing rule” (SR line 3289). So, a command like WEAR THE JUGGLER should give the response “You can’t wear him!” but instead I get “(first taking the Juggler)” and then “I don’t suppose the Juggler would care for that.” which is the proper response to the “can’t take other people rule” (SR line 1867).
When I use RULES or RULES ALL to see what is happening, it tells me the implicit take is happening in the “before stage rule”. This seems to indicate that the I6 “Wear” module is preempting the Standard Rules, and therefore the only way to reinstate the check rules (or add new ones) is to write before rules. That sort of defeats the purpose of having the Standard Rules, at least in this instance, doesn’t it?
The purpose of the Standard Rules is to describe the default behavior of the world so that you don’t have to. The process of writing an IF game is largely describing the exceptions to these rules: what interesting and non-default things happen in your world.
In this particular case, we have a number of constraints on what can be worn. One constraint is that the item must be held and another is that it must not be a person. I read your complaint as saying that you don’t like the order in which these constraints are being applied. But both rules are still purposeful, even though a person usually can not be held, because an author can override any one of the standard rules, while leaving the others in place.
Consider this code:
Alley Outside Comedy Club is a room.
A juggler is here. The juggler is a man.
Chuckie is here. Chuckie is a man.
Instead of taking Chuckie:
now the player carries Chuckie;
say "Chuckie scowls indignantly as you pick him up. 'I have a knife, you know,' he tells you."
Test me with "wear juggler / wear chuckie".
The juggler can’t be taken, but Chuckie can, so it’s still good to have a standard rule that disallows Chuckie from being worn unless the author also explicitly allows that.
Implicit takes are actually triggered by the “carrying requirements rule”, which happens in between the before stage and the instead stage. There’s a couple of ways that you can bypass or suppress it.
Use a before rule, but use an instead clause to make sure the action stops. This prevents the action from ever getting as far as the implicit take, so you can substitute your own explanation for why the action fails.
Before wearing a person:
instead say "What are you, a serial killer? You can't wear a person."
You can also suppress the carrying requirements rule itself for certain circumstances. This prevents the implicit take from happening and lets the action proceed, allowing the instead and/or check rules to handle things.
The carrying requirements rule does nothing when the current action is wearing.
The problem I have is that the Standard Rules extension provides rules for both attempting to wear unwearable things, and attempting to wear things you aren’t carrying, but neither of these rules are ever reached because “something” performs an implicit take on the noun long before the check stage rules. My analysis indicates that this “something” happens in the before stage rules and appears to be in the I6 code.
For example, your code results in the following:
This illustrates the issue perfectly. Attempting to wear the juggler results in an implicit take and the expected response from taking a person. Attempting to wear Chuckie triggers the check wearing rules because your instead rule changes the result of the implicit take.
Yes, I suspected as much. However, that essentially means you have to specifically write something in your code to cause the built-in standard check wearing rules to be enforced, or you have to specifically write something in your code to put the built-in standard check wearing rules before the implicit taking rule.
By way of comparison, the putting something on rules, which also has a “can’t put what’s not held rule”, doesn’t cause an implicit take in the before stage rules. The check rules for this action are actually enforced, and the implicit take only happens if the check rule fails. So, if you wanted to stop the implicit take for scenery items, it’s as easy as adding a check putting rule before the “can’t put what’s not held” rule. If you want to stop the implicit take for unwearable items, and you add a check wearing rule before the “can’t wear what’s not held” rule, it has no effect.
Ah, ok. I’ve looked at the I6 translation of my example code, and that something appears to be the grammar of the Wear verb in conjunction with the parser. The verb is defined like this:
Verb 'wear' 'don'
* held -> Wear
Notice the “held” grammar token. The parser will only accept “wear [thing]” if the thing is held. If not, the parser “helpfully” generates an implicit take in an effort not to have to reject the command. This all happens in the parsing phase before the Wear action is generated.
The solution would appear to be to change the grammar so that held token becomes a regular noun token (applying to both held and unheld things) and then let the standard rules be applied later after the parser has accepted the command. I tried adding this:
Extend 'wear' replace
* noun -> Wear;
and got an error msg saying ‘There is no previous grammar for the verb “wear”’. When I instead tried:
* noun -> Wear;
I got an error saying ‘Two different verb definitions refer to “wear”’. So it seems that Inform 7 is inserting its grammar after the body of my code. I’m not sure how to force I7 to include its grammar prior to evaluating this code. In I6, I could just put the code after the inclusion of Grammar.h. So it seems like this will need to be solved at the I7 level with understand statements. I can do something like:
Unconstrained wearing is an action applying to one visible thing.
Understand the command "wear" as something new.
Understand the command "don" as something new.
Understand "wear [something]" or "don [something]" as unconstrained wearing.
but then I’m on the hook to implement this new action. What I’d like to do is hook this new action into the existing set of rules for Wear, having redefined only its grammar. Any ideas?
I have found a couple ways to get around the problem.
The simplest solution is:
the can't wear what's not clothing rule is listed in the before rules.
the can't wear what's not held rule is listed in the before rules.
the can't wear what's already worn rule is listed in the before rules.
This puts the check rules in the before stage before the carry requirements rule, but the check rules won’t trigger an implicit take, so you’d have to write a replacement rule (see #2).
The next simplest solution is to simply write before rules that mirror the check rules, and while you’re at it add a call to the implicit taking activity. This is essentially the same as Mike’s first solution.
Finally, Mike’s second solution will turn off the rule for the wearing activity, which allows the check rules to be applied. However, since the check rules don’t automatically trigger an implicit take, you’d have to write a replacement rule (see #2).
I don’t have an I6 code solution. I6 code it like Latin to me – I can read it, but speaking or writing it is beyond me.
Would it be that the problem arises because the grammar for wearing in the Standard Rules is the following?
Understand "wear [something preferably held]" as wearing.
The “preferably held” token is what causes the implicit taking, I think.
Simply writing in your source
Understand "wear [something]" as wearing.
would solve the problem, since there will now be a grammar line for wearing without that “held” part.
Hmm, so Mike’s comments about the carrying requirements rule and its ordering (between the before and instead stages) and your reiteration of them are making me realize that I’m assuming too much about I7’s behavior based on my knowledge about I6.
If I create a juggler in I6 and give him a before rule for Wear, leaving the grammar (with ‘held’) unchanged, the before rule will never be triggered because the parser’s implicit take (due to ‘held’) will happen first.
If in I7, which we saw has the same underlying Wear grammar with ‘held’ in its I6 intermediate code, I do the same, the before rule will trigger prior to the implicit take.
I was viewing I7 as a layer on top of a perhaps mildly altered I6 standard library, but it seems like the changes are more significant than I thought.
(Ego quoque linguam Latinam multo melius lego quam scribo aut loquor. As is probably painfully evident from that sentence.)
Implicit taking occurs when the action is defined as “applying to one carried thing” AND the grammar for that action includes the “[something preferably held]” token. I’m pretty sure both these conditions must be true for the implicit take to happen.
The rule that actually causes the implicit take to happen is the “carrying requirements rule,” which is listed in the action-processing rules (NOT the before stage rule).
An implicit take can also be triggered manually with the “implicitly taking something” activity.
In the standard rules, there are actually only six actions that generate implicit takes: wearing, locking it with, unlocking it with, giving it to, showing it to, and throwing it at.
If I were going to to rearrange implicit takes so that they always happen during the check rules, I’d probably try something like this:
[code]Test Chamber is a room.
A jacket is here. The jacket is wearable. A closed locked container called the music box is here. A key is here. The key unlocks the music box. A boulder is here. The boulder is scenery.
A man called Gordon is here.
The carrying requirements rule is not listed in the action-processing rulebook.
The carrying requirements rule is listed before the can’t wear what’s not held rule in the check wearing rules.
The carrying requirements rule is listed before the can’t lock without the correct key rule in the check locking it with rules.
The carrying requirements rule is listed before the can’t unlock without the correct key rule in the check unlocking it with rules.
The carrying requirements rule is listed before the can’t give what you haven’t got rule in the check giving it to rules.
The carrying requirements rule is listed before the can’t show what you haven’t got rule in the check showing it to rules.
The carrying requirements rule is listed before the implicitly remove thrown clothing rule in the check throwing it at rules.
Test me with “wear Gordon / wear jacket / unlock box with key / show box to Gordon / drop box / give box to Gordon / throw jacket at Gordon / throw boulder at Gordon / drop key / lock box with key”.[/code]
I’m not disputing where the carrying requirements rule is enforced, but when I use RULES ALL, this is what I get:
Internal rules apparently aren’t mentioned.
Also, thanks for the solution. I hadn’t tested the other actions yet. Juhana’s extension will only test giving it to, showing it to, or throwing it at with inventory items, so there’s no chance it would test “throw gordon at boulder.”
Hey, guys. I know this doesn’t seem like a big deal, overall, but I asked Emily about this rule not showing up on RULES ALL. She felt it was potentially worth putting on Mantis, so knock yourselves out, and thank you for finding these little details - the devil hides in them!
It’s only a partial solution, but Small Kindnesses by Aaron Reed adds some rules to prevent taking unwearable things when the player says “wear grapefruit”. See the “Don’t perform implicit actions for doomed tasks” section for inspiration.
I ended up writing the following as a solution that eliminates the problem and makes the Wearing action work like other similar actions. I did similar things with Throwing, Showing and Giving.
[code]The carrying requirements rule does nothing when the current action is wearing.
The can’t wear what you haven’t got rule is listed instead of the can’t wear what’s not held rule in the check wearing rules.
Check an actor wearing (This is the can’t wear what you haven’t got rule):
if the actor is carrying the noun, continue the action;
if the actor is wearing the noun, continue the action;
carry out the implicitly taking activity with the noun;
if the actor is carrying the noun, continue the action;
stop the action.[/code]