Setting Action Variables is Misbehaving

Okay, so maybe it’s not misbehaving; maybe I just don’t know what I’m doing.

I’ve been bashing my head against this for a few days and I can’t seem to figure out the behavior of setting action variables. It seems like it’s working properly in a superficial sense, but improperly when used in practice.

Example:

[code]House is a room.
Dummy is a person in House.

An appendage is a kind of thing. An appendage is a part of every person.
Understand “hand/foot/leg/arm/head” as appendage.

Setting action variables when the noun is an appendage which is part of a person (called holder):
now the noun is the holder.

After doing something other than looking:
say “[The noun] was the target of [our] action!”
[Problem: Why does “touch dummy’s head” not say “Dummy might not like that.” when this statement is used?]
[Problem: This reports the noun to be Dummy regardless of whether the parser received ‘dummy’ or ‘dummy’s head’ (as expected), yet the statement below still does not properly go into effect.]

Before doing something to a person:
say “[The noun] does not interest [us] in the slightest.” instead.

[Problem: If setting action variables happens previous to the Before statement checks, then why does “kiss dummy’s head” return a different response than “kiss dummy”? Shouldn’t ‘dummy’s head’ really be treated as just ‘dummy’ at that point, so far as Inform understands? Isn’t that the very point of Setting Action Variables?][/code]

As explained in my comments, why the inconsistency between what Inform reports as the noun after substituted through Setting Action Variables and how it is applying rules to that same noun?

Okay, a few problems.

  • The “You can only do that to something animate” error is generated before setting action variables. It’s not a check rule; it’s a grammar limitation. To avoid this, either redefine the KISS grammar or make the appendage animate.

  • The noun and second noun are not action variables. They’re global variables. The setting-action-variables rulebook is not for changing the noun; it’s for initializing action variables which are not initialized by the parser.

Noun and second noun are tied into the action system in deep and annoying ways, so it’s nearly always a mistake to try to set them. You will find life much easier if you use a “Check kissing…: instead try kissing the holder” pattern. Even though that requires naming each action separately.

Yeah, I realized that kissing error was based in a parser error, I just didn’t expect to receive it since I thought the noun would have been replaced with an animate noun at that point.

So action variables would be for an object implied or omitted, rather than something read from the parser?

Hmm… this seems like a big stumbling point for me because I would have to supply a Check rule for every single action in my code if I wanted a 1:1 correspondence between a part and a holder of the part. That seems like a giant nightmare.

I guess I’m looking for a statement like “Before doing anything to an appendage, try the action on the holder of the appendage instead.” but I don’t know how to phrase it.

No, action variables are for stuff like “the door gone through” or “the container exited from”.

Implied and omitted objects are variously handled by implicit taking, supplying a missing noun, or does-the-player-mean rules.

Here’s how I ultimately handled this problem, for anyone interested…

[code]
House is a room.
Dummy is a person in House.

An appendage is a kind of thing. An appendage is a part of every person.
Understand “hand/hands/foot/feet/neck/back/leg/legs/arm/arms/head/mouth/knees/chest” as appendage.

Before doing something to a person that is not the player:
say “[The noun] does not interest [us] in the slightest.” instead.

Before doing anything:
if the noun is an appendage (called limb) that is part of a person (called host):
now noun is host;
try the current action instead;
if the second noun is an appendage (called anotherLimb) that is part of a person (called secondHost):
now second noun is secondHost;
try the current action instead.

[Now “touch dummy” or “touch dummy’s head” work the same, except for “kiss dummy’s head” or “ask dummy’s head about puppies” because the appendage would need to be animate to avoid the parser error. This makes sense for kissing, but talking to a body part makes little sense, so… we need to rewrite kissing]

Understand the command “kiss” as something new.

Better kissing is an action applying to one thing.
Understand “kiss [something]” as better kissing. Understand the commands “smooch” and “peck” as “kiss”.

Check an actor better kissing (this is the better kissing yourself rule):
if the noun is the actor:
if the actor is the player:
say “[We] [don’t] get much from that.” (A);
stop the action.

Check an actor better kissing (this is the block better kissing rule):
if the actor is the player:
say “[The noun] [might not] like that.” (A);
stop the action.

Check an actor better kissing a thing that is not a person (this is the can’t better kiss non-people rule):
if the actor is the player:
if the noun is not a person:
say “[We] [don’t] get any pleasure from that.” (A);
stop the action.[/code]

Incidentally, I am unsure how to make a non-person object “animate” as I’m under the impression that it’s a property tied solely to people. If any object can have the “animate” property, how can that be set?