How to trigger more specific parser errors?

I find that the parser sometimes defaults to the “You can’t see any such thing” error when I think it ought to be able to manage the “I only understood you as far as wanting to” error. I wonder why and I wonder if I can do anything to improve matters. The “you can’t see any such thing” error can be confusing, by leading players to believe an object is not available when it is. Here’s an example of the parser doing well (from a playtest session with my rather imaginative nephew):

>fight the militia by jumping onto its back
[Parsing for the verb ‘fight’ (2 lines)]
[line 0 * Routine(270612) noun → MistakeAction]
[line 1 * noun → Attack]
I only understood you as far as wanting to fight the militia.

This correctly encourages the player to believe that fighting the militia is in principle possible. But in the next example the parser didn’t do so well (“run back” works because I have made “back” understood as the west direction):

>run back towards the militia
[Parsing for the verb ‘run’ (14 lines)]
[line 0 * → Go]
[line 1 * noun=Routine(455461) → Go]
[line 2 * noun → Enter]
[line 3 * Routine(546190) noun=Routine(455609) → Enter]
[line 4 * Routine(546311) noun=Routine(455498) → Go]
[line 5 * Routine(546406) noun=Routine(455535) → Go]
[line 6 * Routine(546501) noun=Routine(455572) → Go]
[line 7 * ‘into’ / ‘in’ / ‘inside’ / ‘through’ noun → Enter]
[line 8 * ‘across’ / ‘along’ / ‘over’ noun → A78_traversing]
[line 9 * ‘across’ / ‘along’ / ‘over’ noun → A78_traversing]
[line 10 * Routine(270467) Routine(270488) ‘away’ Routine(546596) Routine(546639) Routine(546682) → MistakeAction]
[line 11 * Routine(270447) ‘into’ ‘the’ ‘arms’ ‘of’ ‘the’ ‘militia’ → MistakeAction]
[line 12 * Routine(270407) ‘down’ / ‘up’ topic → MistakeAction]
[line 13 * Routine(270427) ‘to’ topic → MistakeAction]
You can’t see any such thing.

I hoped instead for “I only understood you as far as wanting to go west” because I would like the parser to always respond to a command in the form “[a known verb] [a thing that works with the verb] [some other non-understood text]” with “I only understood you as far as wanting to [verb] [the thing].”

As you can see from the trace, I have set up quite a lot of other grammar relating to various actions and mistakes that might trigger from “run [text]”. But still for me the bottom line is that “run back” would have parsed successfully as a command, so I think “can’t see any such thing” is not the best error. Any ideas much appreciated.

Interestingly, after I just added yet another way to parse commands that can begin with “run”, I now get a different error message for the same player command (below). This is also a poor (albeit marginally better) error message. I’d like any player command in the form “[a known verb] [a thing that works with the verb] [some other non-understood text]” to result in “I only understood you as far as wanting to [verb] [the thing].”

>run back towards the militia
[Parsing for the verb ‘run’ (16 lines)]
[line 0 * → Go]
[line 1 * noun=Routine(456401) → Go]
[line 2 * noun → Enter]
[line 3 * Routine(548385) noun=Routine(457065) → Enter]
[line 4 * Routine(548506) noun=Routine(456438) → Go]
[line 5 * Routine(548601) noun=Routine(456475) → Go]
[line 6 * Routine(548696) noun=Routine(456512) → Go]
[line 7 * Routine(548791) scope=Routine(456549) → A89_distance_going]
[line 8 * Routine(548886) scope=Routine(456721) → A89_distance_going]
[line 9 * Routine(548981) scope=Routine(456893) → A89_distance_going]
[line 10 * ‘into’ / ‘in’ / ‘inside’ / ‘through’ noun → Enter]
[line 11 * ‘across’ / ‘along’ / ‘over’ noun → A78_traversing]
[line 12 * ‘across’ / ‘along’ / ‘over’ noun → A78_traversing]
[line 13 * Routine(271361) Routine(271382) ‘away’ Routine(549076) Routine(549119) Routine(549162) → MistakeAction]
[line 14 * Routine(271341) ‘into’ ‘the’ ‘arms’ ‘of’ ‘the’ ‘militia’ → MistakeAction]
[line 15 * Routine(271321) ‘down’ / ‘up’ topic → MistakeAction]
That noun did not make sense in this context.

I have made a full example which captures a part of what seems to be the issue:

The player is in a room called the testing room.

A thing can be stek. a thing is usually not stek.
A stek thing called the foo is in the testing room.
A thing called the bar is in the testing room.

Doodling is an action applying to one thing.
Understand "doodle [a stek thing]" as doodling.
Report doodling: say "You doodle [the noun]."

>doodle foo
You doodle the foo.

>doodle bar
You can’t see any such thing.

I think it’s rather suboptimal that the parser’s way of telling the player that a bar is not the kind of thing that can be doodled is to claim there is no bar present. Is there a way that I could improve this (without rewriting the parser!)?

As a general rule of thumb, you’re better leaving the parser a generous amount of leeway to recognise reasonable grammar lines and generate an action, avoiding parser errors altogether, then deal with fine details of what’s allowed and what’s not, and what’s reported, in the action rules themselves, where you have more control over what happens- in this instance responding differently to things which are not stek:

The player is in a room called the testing room.

A thing can be stek. a thing is usually not stek.
A stek thing called the foo is in the testing room.
A thing called the bar is in the testing room.

Doodling is an action applying to one thing.
Understand "doodle [something]" as doodling.
Report doodling: say "You doodle [the noun]."
Check doodling a thing which is not stek: say "[regarding the noun][Those] can't be doodled." instead.
testing room
You can see the foo and the bar here.

>doodle foo
You doodle the foo.

>doodle bar
That can't be doodled.

3 Likes

That makes a lot of sense, thanks. It solves my complaint that is specified in my toy example. I’m still stuck with the sub-optimal parser messages for my real case, because there is so much grammar I have added that it’s just not that simple, but I have a workaround:

Understand "run [text]" as a mistake ("I only understood you as far as wanting to run.")

It seems like understanding as a mistake is the final option the parser goes for after it has tried everything else, so this seems to work. I wouldn’t want to have to do this for all actions but it seems like it’s maybe only the few I overloaded with lots of extra grammar where the parser gives odd errors which I can’t fix using the suggested type of method.

It’s not quite so simple as that, and the documentation on this subject (17.22 Precedence) is confusing if not downright wrong. It suggests that ‘mistakes’ that match as grammar lines are considered before all other possibilities, but as your own experience has already shown, that’s not the case.

‘Mistakes’ which match as exact given text, like the example in the documentation, are given precedence over matching grammar lines involving tokens. So

Understand "take foo" as a mistake ("You can't take foos.").

takes precedence over

Understand "take [something]" as taking.

if typing ‘take foo’.
Also,

Understand "take [something]" as a mistake ("You can't take foos.").

still takes precedence over

Understand "take [something]" as taking.

But [text] tokens seem to be given lower precedence than more specific tokens like [something] or [number] and this ‘token priority’ overrides the precedence usually given to ‘mistakes’, which is why your code is working for you, i.e.

Understand "take [something]" as taking.

takes precedence over

Understand "take [text]" as a mistake ("You can't take foos.").

This ‘token priority override’ is somewhat inconsistent, because for example

Understand "take [a stek thing]" as taking.

does not take precedence over

Understand "take [something]" as a mistake ("You can't take foos.").

despite being a more specific token.

1 Like

Thanks, that was very useful. If your explanation is reliable, I’m safe in using Understand “action [text]” as a mistake, as long as I combine this with your advice to avoid over-specific tokens in understand grammar for real actions.

hmmm…

I guess Ben’s expected inputs can be construed as a form of “guess the verb” (in this case, a form of complex wording, (irl unacceptable in actual fighting, where complex order are easily misunderstood in the “din of battle”), not commonly used by IF players)

As actual Naval and military historian, I offer a simpler, realistic general solution: implement frontage (in this case, front, back, side) and extend (sorry for the I6 terminology here) attack as accepting the side to be attacked, getting a terser, simpler

attack the militia’s back

minor point, actually there was parser-based wargames:

Peter Turcan’s wargames

HTH and
Best regards from Italy,
dott. Piergiorgio.

I guess Ben’s expected inputs can be construed as a form of “guess the verb”

Do note, however, that I have not shown you any “expected inputs” (inputs necessary to solve puzzles), just real inputs from a playtest session (hence the reference to my imaginative nephew). My puzzles are not solved with any kind of complex guess-the-word input. I’m just trying to produce the optimum response to the kind of “incorrect” things players may say. My target audience is not IF experienced so I get a lot of this kind of thing while players are learning how to deal with the parser.

However, the tip about how to implement some combat details is interesting and the kind of thing I might use at some point, thanks.