Intercept parser errors

I am currently revisiting an “old” Inform 7 game I started a few years ago (It got put on hold due to “life” commitments). In the game I need an object (e.g. a coat) which is not a container but has a container as “part of” it (e.g. a pocket). If the player types: get [object] from coat. I want the parser to interpret this as get [object] from the pocket. But I can’t seem to intercept this with a before or instead rule? e.g before removing something (called the item) from the coat: try removing the item from the pocket instead. The parser has already failed with a “can’t see any such thing” error. Also removing seems a rather complex action as somewhere along the line it gets converted to a take action and therefore “take [object] from coat” would need to work too. Thing get even more complicated when “all” is used (as in, remove all from coat) as that fails within a parser “nothing to do” error and says “That can’t contain things”. Can anyone suggest a way to achieve something that would allow this.

Oh man, I ran into this exact issue in my game a couple of weeks ago. There are probably better ways to do it, but this worked for me:

Understand "take [something] from [something]" as removing it from.

Instead of removing something from the coat, try removing the noun from the pocket.

You might want other code here so the player can’t try to remove anything from anything else willy-nilly – or you could turn the second text token into “[the coat]” if you want to narrow things.

NB you shouldn’t use a Before rule because then after trying the Remove action, the Carry Out rule will fire and you’ll get an extra error message since the player’s already removed the thing (or you could do a Before rule that terminates the action I suppose).

Yeah, the “removing it from” action is awkward to deal with. It’s defined using [things inside], which entirely fails to recognize objects which aren’t inside the container. It’s hard to get anywhere from the parser error because the objects have not, in fact, been recognized.

Mike’s solution is reasonable. It doesn’t lead to any unexpected parsing behavior that I know of. But you should also add the synonyms:

Understand "take [something] off [something]" as removing it from.
Understand "get [something] from [something]" as removing it from.
Understand "remove [something] from [something]" as removing it from.
2 Likes

Thanks for the input. This has helped with the first part of the scenario and will now allow an “instead” or “Before” rule to intercept the “remove [object] from coat” and convert it to “remove [object] from pocket” instead. However, I still get the “nothing to do” error when trying “take all from coat” which displays as “that can’t contain things” - the parser failure hits before the Instead (and also a before) rule. Is there a way around? (If not then I will just use the method advised as this works for the most part) - Regards, AG

1 Like

For multiple objects, try

Understand "take [things] from [something]" as removing it from.

Thanks again, Mike.

That causes its own caveat, in that it tries to take everything visible from the coat (pocket) and not just objects inside the pocket. If I replace: take [things] from [something]" with take [things inside] from [something] (which seems to be a valid token) It goes back to the “that can’t contain things” (nothing to do) error.

This can be worked around by creating a new custom action for removing things from the coat:

Understand "take [things] from [coat]" as pocket-removing.
Understand "get [things] from [coat]" as pocket-removing.
Understand "remove [things] from [coat]" as pocket-removing.

Pocket-removing is an action applying to two things.

Carry out pocket-removing:
	try removing the noun from the pocket.
	
Rule for deciding whether all includes something not in the pocket while pocket-removing:
	it does not.

The Rule for deciding whether all includes is to prevent the coat and the pocket from being included in ALL when typing TAKE ALL FROM COAT.

On an unrelated note, you probably also want a rule like

Rule for deciding whether all includes things in the pocket while taking:
	it does not.

to avoid automatically taking everything out of the pocket (after first taking the coat) when the coat is in the room and you type TAKE ALL.

Edit: copy-paste fail.

1 Like

Thank you Petter, I have managed to now get something working as I want with a combination of all these responses. My game actually uses kinds so needed to be a bit more generic but with some manipulation I have now got this to work with both single item removal and a “take all” one too. Thanks for the “Rule for deciding whether all includes” tip - this helped me with another part of my game in which all was trying to take a persons features (eyes, nose etc) when typing take all ! - Once again, thanks for the excellent responses and assistance here - it was much appreciated. AG

That shouldn’t happen by default if you declare them as fixed in place and/or scenery – both of which seem like reasonable properties for parts of the body… (although taking parts will fail by default anyway, this should stop it even trying without needing the extra rule)

Doesn’t all exclude things that are part of something?

Sorry - I think I was getting confused over the examples using “take all from” - The following example shows what I meant.


“CoatTest” by AndyG

Understand “take [something] from [coat]” as pocket-removing.
Understand “take [things] from [coat]” as pocket-removing.
Understand “remove [something] from [coat]” as pocket-removing.
Understand “remove [things] from [coat]” as pocket-removing.
Understand “get [something] from [coat]” as pocket-removing.
Understand “get [things] from [coat]” as pocket-removing.

pocket-removing is an action applying to two things.

carry out pocket-removing:
try removing the noun from the pocket.

A boy is in the cloak room. The boy is a male person.
A nose is a kind of thing.
A nose is part of every person.

The cloak room is a room.

A vase is a container in the cloak room. In the vase is a flower and a stick.

In the cloak room is a coat. The coat is wearable.

A pocket is a container. It is part of the coat. In the pocket is a pen and a handkerchief.


“take all from coat” then attempts to take all things including parts (in this case - your nose and the boy’s nose)

However the rule:
Rule for deciding whether all includes things not in the pocket when pocket-removing: it does not.
sorts this out.

I only have one oddity after adding the above rule : “take all from coat” when the pocket is empty responds with “There are none at all available!” but take all from pocket respond with “The pocket is empty.” - it would be nice if these matched but not a big issue.

I was puzzled why pocket-removing would try to take the boy’s nose, but taking does not. In particular, none of the rules for deciding whether all contains something reject components of other things. (You can see this by using trace 4 and rules to see the list of things being considered and the rules that cause rejection.)

   Best guess the boy (582120)
[Rule "exclude people from take all rule" applies.]
   Rejecting it
   Best guess the vase (582152)
   Accepting it
   Best guess the coat (582248)
   Accepting it
   Best guess the flower (582184)
   Accepting it
   Best guess the stick (582216)
   Accepting it
   Best guess the pen (582376)
   Accepting it
   Best guess the handkerchief (582408)
   Accepting it
   Best guess your nose (582280)
[Rule "exclude indirect possessions from take all rule" applies.]
   Rejecting it
   Best guess the boy's nose (582312)
   Accepting it
   Best guess the pocket (582344)
   Accepting it
   Best guess yourself (582056)
[Rule "exclude people from take all rule" applies.]
   Rejecting it
   Best guess ran out of choices
   Made multiple object of size 8]
  [ND appended to the multiple object list:
  Entry 1: The vase (582152)
  Entry 2: The coat (582248)
  Entry 3: The flower (582184)
  Entry 4: The stick (582216)
  Entry 5: The pen (582376)
  Entry 6: The handkerchief (582408)
  Entry 7: The boy's nose (582312)
  Entry 8: The pocket (582344)
  List now has size 8]

Notice that the pocket and the boy’s nose survive this process, yet they won’t be included in the final multiple object list. It turns out, the parser hard-codes additional requirements that only apply to taking, which you can see in the trace here.

   Revising multiple object list of size 8 with 2nd nothing
   Token 2 plural case: number with actor 0
   Done: new size 6

I located the code in the I6 translation of CoatTest. It isn’t entirely clear to me what it is doing, but it will have the effect that components are never included in the object list for take all.

Since I was already looking through the I6 code, I tried tracking this down as well. This appears to be another special case in the parser, which has a set of error messages that are only used with removing from. So it looks like it is impossible to make pocket-removing behave entirely like removing from without modifying the parser itself.

You could do something like

Understand "take all/everything from [coat]" as empty-removing when the first thing held by the pocket is nothing.

Empty-removing is an action applying to one thing.

Carry out empty-removing:
	say "The coat pocket is empty."

Of course you would probably want to add the grammar lines for “get all/everything from” and “remove all/everything from” as well,

EDIT: There is a different rabbit hole regarding TAKE STICK AND VASE FROM COAT and TAKE ALL BUT STICK FROM COAT when the pocket is empty, but this is as far down as I’m prepared to go.

Here’s some additional strange behavior with all and pockets. This is using CoatTest from above, and is the same with or without the pocket-removing code:

>wear coat
(first taking the coat)
You put on the coat.

>x pocket
In the pocket are a pen and a handkerchief.

>take all from pocket
There are none at all available!

>take off coat
You take off the coat.

>take all from pocket
There are none at all available!

>drop coat
Dropped.

>take all from pocket
pen: Taken.
handkerchief: Taken.

Notably, this does not occur for inserting into, so it’s probably related to the special-case code in the parser for taking and removing. Just to make things stranger, take all from pocket does work when the pocket contains 1 thing.

Anyway, here is an alternative approach that avoids introducing new actions by introducing more ambiguity:

Understand "coat" as the pocket.
Does the player mean removing from the coat: it is very unlikely.
Does the player mean inserting into the coat: it is very unlikely.

Does the player mean removing from the pocket: it is likely.
Does the player mean inserting into the pocket: it is likely.
Does the player mean doing something to the pocket: it is unlikely.

Rule for clarifying the parser's choice of the coat: rule succeeds.

This seems to work pretty well. The actual set of does the player mean rules may need to be tuned further.

The rule for clarifying the parser’s choice is there to avoid printing (the coat) every time you do something involving the coat. That may also need to be narrowed.

The TAKE ALL FROM POCKET issue while wearing the coat is due to a bug in the “exclude indirect possessions from take all rule” from Standard Rules.

This has the definition:

Rule for deciding whether all includes things enclosed by the person reaching
while taking or taking off or removing (this is the exclude indirect
possessions from take all rule): it does not.

As far as I can tell, the or removing part does not work as intended and should not be there at all. It breaks TAKE ALL FROM carried containers.

In Counterfeit Monkey, I fixed this by replacing the rule entirely:

Rule for deciding whether all includes things enclosed by the player while taking (this is the new exclude indirect possessions from take all rule):
	it does not.

The new exclude indirect possessions from take all rule is listed instead of the exclude indirect possessions from take all rule in the for deciding whether all includes rulebook.

This seems to work in the current case as well.

Your fix does solve that particular problem. I am puzzled why taking off is there, since it does not work with all in the first place.

I notice your changed the person reaching to the player, which makes me wonder if this affects the player asking an NPC to do something. But some experiments show that this is somewhat broken out of the box: if you make the boy persuadable, and ask him to take all, he will attempt to take himself.

By adding an actor strategically, I can make the code using pocket-removing work when asking an NPC to take all from the coat. To take the understand-“coat”-as-pocket approach, I can make it work if I add the rules below, but I wonder if there is a better approach.

Does the player mean asking someone to try removing from the coat: it is very unlikely.
Does the player mean asking someone to try inserting into the coat: it is very unlikely.

I have a similar problem so this has been illuminating - thank you.

Where can I read the Standard Rules?

That depends on why you’re looking for them. :slightly_smiling_face:

The actual real Standard Rules themselves can be read by going to File → Open Extension → Graham Nelson → Standard Rules. But they’re not really documented and can be hard to read through unless you already know what you’re looking for. They also only tell half the story, as a great deal of things are implemented in the I6 code instead, which is less easily readable (though you can still find it if you go looking).

You might want to have a read through of the annotated rules; this is quite old (I’m not sure if there’s a newer version around somewhere) and many things have changed since then, but a lot of it does still apply, so this may help, especially if you compare the rules here with the real Standard Rules.

Having said all this, for most purposes a combination of looking in the Documentation and looking in the Index (especially the latter) gets you a long long way, without needing to look too closely at the Standard Rules themselves.

For example, clicking through Index → Actions → Taking shows you all of the Check rules controlling that action. While this doesn’t tell you the precise conditions it checks, usually this is fairly apparent from the names of the rules, and if not, once you know the name of the rule you can more easily locate it within the Standard Rules themselves. Better still, the Index automatically updates with any extensions you’ve included as well as rules from your own story.

To find that particular rule mentioned above, though, you need to look at the Rules tab instead, under the deciding whether all includes activity. Using the RULES debugging verb is another way to help locate which rules are affecting things in play.

I notice your changed the person reaching to the player

When replacing code in the Standard Rules, it is generally a good idea to stay as close to the original as possible, because you can never be sure what you’ll break otherwise. In this particular case, I disregarded that in order to make the new code clearer. I don’t recommend this. Fortunately, it seems to have caused no unwanted side effects, probably because the things you can order NPCs to do in Counterfeit Monkey are very limited.

My situation is that I have (using the equivalent things being discussed here) a coat with four pockets. I wondered whether I could amend a Standard Rule so that for “get all from coat” I could add the contents of first pocket, second pocket etc to the (empty) list of items found in the coat before the action starts. (My version of the coat can’t be worn so that aspect of it doesn’t apply.)

I’ll look through your advice when at the computer and see whether I get anywhere! Thanks.

(Edited to change “work” to “worn”.)