I7: A lack of "understanding"

[code]“Understanding” by RPR

This Place is a room. A machine is in this place. A lever is part of the machine.

A position is a kind of value. The positions are left, right and middle. The lever has a position.

Understand “center” as “middle”.

Instead of setting the lever to “left”:
If the position of the lever is left:
Say “The lever is already set to the left position.”;
Otherwise:
Now the position of the lever is left;
Say “You move the lever to the left position.”.

Instead of setting the lever to “right”:
If the position of the lever is right:
Say “The lever is already set to the right position.”;
Otherwise:
Now the position of the lever is right;
Say “You move the lever to the right position.”.

Instead of setting the lever to “middle”:
If the position of the lever is middle:
Say “The lever is already set to the middle position.”;
Otherwise:
Now the position of the lever is middle;
Say “You move the lever to the middle position.”.[/code]

This code does not compile. The problem is the "Understand “center” as “middle” statement. If I remove the statement and a player types “set lever to center” he gets a response that says “No, you can’t set that to anything,” which is quite misleading (because in fact he can set the lever to left, right or middle). Any suggestions would be appreciated. Thanks.

Robert Rothman

Your understand statements shouldn’t have quotes on the right side; to make it compile, remove the quotes around “middle.” But then the understand statement won’t do anything, because the setting action applies to a thing an a topic (a free-form text string, basically), so the parser isn’t even trying to understand the text as a thing or value. If you turn on the actions command, you’ll see that the action being carried out is setting the lever to “center” rather than setting the lever to center; even if you type “set lever to left” the action is setting lever to “left” rather than setting the lever to left.

The quick and dirty way to deal with this is just to rewrite your last rule so it catches “center” as well as “middle,” by changing the rule heading to this:

Instead of setting the lever to when the topic understood matches "middle" or the topic understood matches "center":

(There may be a nicer way to do this, but this was the first one I got to compile.)

And the reason you’re getting the misleading error message is that you haven’t written a rule to catch setting the lever to an invalid position, so when none of your rules applies it just falls through to the general “block setting it to” rule. You’d get the same message if you typed “set lever to up” or “set lever to foo.” You can easily take care of this by writing another rule for setting the lever to something invalid:

Instead of setting the lever to: say "You can only set it to left, right, or middle."

This is less specific than the rules for setting the lever, so it won’t block them, but more specific than the general block setting it to rule, so it’ll run when you set the lever to a non-choice. But the block setting it to rule is still there, so you’ll get that whenever the player tries to set something non-settable. (An aside I thought of while checking this; it’s probably kind to redirect any attempts to set the machine toward the lever. “Before setting the machine to: now the noun is the lever” should work.)

A less quick-and-dirty method would be to rewrite the “set” command so that it triggers an action that applies to a thing and a position rather than a thing and a topic; then your understand command would work (without that extra pair of quotes, of course). That would let you add additional synonyms much more easily, though it might also give rise to annoying “that noun did not make sense in that context” errors. (Also, I’m having a little trouble getting it to work in testing; but I think it should be possible.) [UPDATE: OK, I’ve got it to compile, modeling it on the painting action in ex. 53, “Early Childhood”; and it turns out to yield annoying “I didn’t understand that sentence” errors instead.]

I agree with Matt, why create a new KOV and then use an action which relies on a topic? I think it would be easier to create a new action which actually uses the position KOV:[code]This Place is a room. A machine is in this place. A lever is part of the machine.

A position is a kind of value. The positions are left, right and middle. The lever has a position.

Understand “center” as middle. [<-- note no quotes around the KOV]

Position-setting is an action applying to one thing and one position.
Understand “set [something] to [position]” as position-setting.
Understand “set [something] to the [position]” as position-setting.

Check position-setting (this is the can’t position-set something to the same position rule):
if the position of the noun is the position understood:
say “[The noun] is already set to the [position understood] position.” instead.

Carry out position-setting (this is the default position-setting rule):
now the position of the noun is the position understood.

Report position-setting (this is the report position-setting rule):
say “You move [the noun] to the [position understood] position.”.

test me with “set lever to the left / set lever to left / set lever to right / set it to middle / set it to the center / set it to center”.[/code]

Ah, this is nice because it doesn’t replace the built-in setting action. So the block setting it to rule is still there, and you don’t get “I didn’t understand that sentence” errors. Setting the lever to a non-position gets parsed as the built-in setting it to action, so you can give a more useful error by catching that action for the lever:

Instead of setting the lever to: say "You can only set it to [list of positions]."  [NB Not position-setting the lever]

Thanks. This is very helpful.

Robert Rothman

is even possible to use kinds of values inside an existing topic as it were, if you find that useful:

This Place is a room.  A machine is in this place.  A lever is part of the machine.

A position is a kind of value.  The positions are left, right and middle.  The lever has a position. 

Understand  "center" as middle.

Instead of setting the lever to "[position]":
	If the position of the lever is the position understood: 
		Say "The lever is already set to the [position understood] position.";
	Otherwise:
		Now the position of the lever is the position understood;
		Say "You move the lever to the [position understood] position.".

test me with "set lever to the left / set lever to left / set lever to right / set it to middle / set it to the center / set it to center".

A drawback is that this doesn’t recognize the commands that use the definite article, but you could fix that with some when-clause to the relevant effect in the rule preamble, such as:

Instead of setting the lever to when the topic understood includes "[position]":

or

Instead of setting the lever to when the topic understood matches "[position]" or the topic understood matches "the [position]":