Making shorthand for "ask about"

Hey All-

I’d like to have A be shorthand for ASK ABOUT. This turn out to be complicated, since I’m trying to eliminate having to type the askee’s name as well. If there is only one NPC near you, I’d like the player to be able to do this:

A DOG (instead of ASK BOB ABOUT DOG)

and the game will know to ask Bob. This seems like a way more player-centric way to go about talking. Obviously, if there is more than one NPC about, the player will have to clarify, but this won’t often be an issue for me. The shorthand A is easy to code, but getting rid of the BOB ABOUT part is beyond me. Help?

3 Likes

Something simple is to use a value that varies to store the presumed target of the question. A quick example:

"Conversation Partner"

Place is a room.

The conversation partner is an object that varies. [object to allow for nothing]

Setting action variables for asking someone (called CP) about something:
    now the conversation partner is CP.

Alice is a woman in place.

Bob is a man in place.

Abbreviated asking is an action applying to one topic. Understand "a [text]" as abbreviated asking.

Check abbreviated asking when conversation partner is a person and the player cannot see the conversation partner:
    say "[The conversation partner] seems to have left." instead.

Definition: A person is non-self if it is not the player.

Check abbreviated asking when the conversation partner is nothing and the player can see a person:
    let new CP be a random non-self person that can be seen by the player;
    if new CP is nothing:
	    say "There's nobody here to ask that.";
    otherwise:
	    now conversation partner is new CP;
	    say "(asking [the new CP])[command clarification break]".

Carry out abbreviated asking:
    try asking the conversation partner about the topic understood. 

After waving hands:
    say "Alice waves back and departs.";
    now Alice is nowhere.
3 Likes

That’s fabulous. Thank you.
One weird thing: when you A SOMETHING when you’re alone, this is the response:

>a something

There's nobody here to ask that.

You must supply a noun.

Can I get rid of the “You must supply a noun?”

1 Like

Also, it gets stuck on the first asked NPC, but adding these lines cured it, unless that’s a bad idea for some reason:

Check going somewhere:
	now the conversation partner is nothing;
	continue the action.

It also isn’t prompting the player to clarify between 2 NPCs-- it just picks one. I modified the carry out rule this way:

Carry out abbreviated asking:
	if more than one person is visible:
		say "Which person do you want to ask?";
	otherwise:
		try asking the conversation partner about the topic understood.

and that works, but it still gives this:

>a something

(asking Bob)

Which person do you want to ask?
1 Like

For future reference, “quick” should be read as “insufficiently tested.”

The stray output after the “nobody here” message is because I forgot to add instead to the say statement, so:

Check abbreviated asking when the conversation partner is nothing and the player can see a person:
    let new CP be a random non-self person that can be seen by the player;
    if new CP is nothing:
	    say "There's nobody here to ask that." instead;
    otherwise:
	    now conversation partner is new CP;
	    say "(asking [the new CP])[command clarification break]".

Clearing the conversation partner when changing location is definitely a good idea.

Trying to force a disambiguation is something I thought about, but it’s more difficult than it sounds. Disambiguation is handled by the parser, not the action processing machinery, so there’s no way to force it with a try... command.

2 Likes

OK, I thought of something. How about adding the following:

Understand "person" as a person.

After reading a command when conversation partner is nothing:
    if the player's command matches the regular expression "^a\s+(.*)":
	    let replacement command be "ask person about [text matching subexpression 1]";
	    change the text of the player's command to replacement command.

[EDIT: Updated to improve the regular expression match; the earlier version was too specific about the number of spaces and not specific enough about position of the match.]

which yields interaction like:

>ACTIONS
Actions listing on.

>A SITUATION
Who do you mean, Alice or Bob?

>ALICE
[asking Alice about "situation"]
There is no reply.
[asking Alice about "situation" - succeeded]
3 Likes

Did the above solve the problem for you? If not, here’s a reorganized version (with a proper test me scenario) that seems to match what you originally asked for:

"Conversation Partner"

Place is a room.

Other Place is east of Place.

Yet Another Place is east of Other Place.

The conversation partner is an object that varies. [object to allow for nothing]

To decide whether the conversation partner is missing:
    if the conversation partner is a person and the player cannot see the conversation partner:
	    decide yes;
    otherwise:
	    decide no.

Definition: A person is non-self if it is not the player.

To decide whether a new conversation partner is available:
    if the conversation partner is nobody and the player can see a non-self person:
	    decide yes;
    otherwise:
	    decide no.

To decide whether there is more than one new person to ask:
    if the conversation partner is nobody and the player can see at least two non-self people:
	    decide yes;
    otherwise:
	    decide no.

Setting action variables for asking someone (called CP) about something:
    now the conversation partner is CP.

Alice is a woman in Place.

Bob is a man in Place.

Carl is a man in Other Place.

Abbreviated asking is an action applying to one topic. Understand "a [text]" as abbreviated asking.

Before abbreviated asking:
    if the conversation partner is missing:
	    now the conversation partner is nothing;
    if a new conversation partner is available:
	    let new CP be a random non-self person that can be seen by the player;
	    now conversation partner is new CP;
	    say "(asking [the new CP])[command clarification break]".

Check abbreviated asking when the conversation partner is nobody and the player cannot see a non-self person:
    say "There's nobody here to ask that." instead.

Carry out abbreviated asking:
    try asking the conversation partner about the topic understood. 

After going when the conversation partner is missing:
    now conversation partner is nothing;
    continue the action.

Understand "person" as a person.

After reading a command when there is more than one new person to ask:
    if the player's command matches the regular expression "^a\s+(.*)":
	    let replacement command be "ask person about [text matching subexpression 1]";
	    change the text of the player's command to replacement command.

[for testing output convenience]
Report an actor asking something about (this is the general reply rule):
    if the actor is the player:
	    now the prior named object is nothing;
	    say "[The noun] makes a few pithy comments about [the topic understood]." (A);
    stop the action.

The general reply rule substitutes for the block asking rule.

Test me with "a dog / alice / a cat / e / a dog / a cat / e / a dog / w / a dog / w / a dog / bob".

If there is more than one possible addressee for the question, a disambiguation prompt is provided. If there is only one possible addressee, then the player is notified of the establishment of a conversation partner. If there is nobody to ask, they are notified of that. If the previous conversation partner is available, the command is treated as though they had typed a normal >ASK [SOMEONE] ABOUT [SOMETHING] command.

Thanks for all this! Yes, it’s extremely useful. I’m trying to figure out all the commands that people might use for asking someone about something: A TOPIC, A ABOUT TOPIC, ASK TOPIC, etc, and redirect all of those. One thing I have learned in my short career is that the command you give people is not intuitive to everyone and you should be generous with options. So this is super useful, not just for this project, but for generally seeing the syntax you’re using here.

1 Like

I feel the need to reiterate my usual warning about parsing out actions in “after reading a command” rules. With this code, for example, I can’t “X ME THEN A TOPIC”.

Unfortunately, I haven’t been able to figure out an alternative. I thought this would work:

Discussing it with is an action applying to one topic and one thing.
Understand "a [text] with [someone]" as discussing it with.
Report discussing a topic with someone: say "You talk to [the second noun] about [the topic understood] for a while."

My understanding was that, if the only available grammar line required another noun, that would get the disambiguation question. For example, “UNLOCK DOOR” would attempt to disambiguate because the grammar line is “unlock [something] with [something preferably held]”.

But, that doesn’t seem to work with topics. And I can’t leave out the “with”, since the parser needs to know where exactly the boundary falls between a [text] token and something else.

Draconis makes a good point.

The regular expression can be updated to allow correct handling of multiple-command input (to an extent), but it’s an inherently problematic approach.

It’s only “to an extent” because there is an inherent issue with the parser’s handling of topics that appear at the end of a grammar line (i.e. after any other words used to recognize the command). As seen in a recent thread on the I6 forum, the token that recognizes topics does not recognize command separators such as “.” or “then”, so it simply converts all remaining input to the topic. Thus, for a command like >X ME THEN A DOG THEN JUMP, the parser will decide that the topic understood for the second and final command will be "dog then jump".

His proposal to mimic the answering it that action’s grammar is interesting, but, as he notes, it doesn’t work by default. The reason is that the answering it that action (aka ##Answer in I6) gets special treatment within ParseToken__():

      TOPIC_TOKEN:
        consult_from = wn;
        if ((line_ttype-->(token_n+1) ~= PREPOSITION_TT) &&
           (line_token-->(token_n+1) ~= ENDIT_TOKEN)) {
           	RunTimeProblem(RTP_TEXTTOKENTOOHARD);
           	return GPR_PREPOSITION;
    	}
        do o = NextWordStopped();
        until (o == -1 || PrepositionChain(o, token_n+1) ~= -1);
        wn--;
        consult_words = wn-consult_from;
        if (consult_words == 0) return GPR_FAIL;
        if (action_to_be == ##Ask or ##Answer or ##Tell) {				! <--- HERE
            o = wn; wn = consult_from; parsed_number = NextWord();
            wn = o; return 1;
        }
        if (o==-1 && (line_ttype-->(token_n+1) == PREPOSITION_TT))
            return GPR_FAIL;    ! don't infer if required preposition is absent
        return GPR_PREPOSITION;

It’s possible to set up the abbreviated asking action in the manner that Draconis suggested:

Abbreviated asking is an action applying to one thing and one topic. Understand "ask [text] of [someone]" or "ask about [text] of [someone]"  as abbreviated asking (with nouns reversed).

Understand the command "a" as "ask".

Carry out abbreviated asking:
	try asking noun about the topic understood.

and to also modify the special case code in ParseToken__() to include abbreviated asking:

...
if (action_to_be == ##Ask or ##Answer or ##Tell or (+ abbreviated asking action +) ) {  ! <--- HERE
	o = wn; wn = consult_from; parsed_number = NextWord();
	wn = o; return 1;
}
...

but there are some drawbacks:

>A DOG
Whom do you want to a that of?

>ALICE
Alice makes a few pithy comments about dog.

>A DOG
Whom do you want to a that of?

The verb word of "a" is used in the partial command, which can be addressed elsewhere with I6 tinkering if desired. The default prompt does not list candidates for disambiguation as desired. More problematic is that the grammar line now demands a noun so one must be specified to the parser in order to satisfactorily complete the grammar line. A rule for supplying a missing noun can’t help because it’s illegal to specify a reversed grammar line without including two parameters – as the Problem Message that you get states: “[Y]ou can’t use a ‘reversed’ action when you supply fewer than two values for it to apply to, since reversal is the process of exchanging them.”

I did finally get this to work as desired without using an after reading a command text substitution… by using a GPR-based text substitution, which has the advantage of only making changes when the input positively matches the desired grammar as well as that of letting the parser deal with multiple command processing (though still suffering from the run-on topic problem).

An interesting problem. Thank you for asking it; I found some new routes through the parser maze while pondering it.

1 Like

Yes, an old project that’s sat on the back burner for a long time now is exposing the PrintCommand, PrintInferredCommand, and PrintVerb machinery to the I7 level. The hard part is that I7 has no real concept of a dictionary word and it’s a lot harder to write PrintVerb without that.

Thank you for this thorough investigation! I didn’t know that asking, answering, and telling had that special hack there. I have to wonder why it’s done that way. Why not just make this the default for TOPIC_TOKEN?