Make "asking someone about a topic" supersede "asking someone about any thing"?

In short, was wondering if there was a way when using two actions (one asking a person about a topic, one asking a person about any thing), to force the game to check the topics first before moving onto the second action? I’m hoping it is easy and I’m just wracking my brain over something simple =P

I used a pretty basic way of using the ask command:

[ If there is a topic that exists, give the reply matching it ]
After asking a person (called the NPC) about a topic listed in the Convo Table of the NPC:
	say "[reply entry][line break]".
	
[ First row of convo table should be what is said if the NPC has nothing to say about the topic - basically an error, no topic found message in a story-friendly way ]
Report asking someone (called the NPC) about:
	choose row 1 from the Convo Table of the NPC;
	say "[Reply entry][line break]";
	
Understand "Talk to/with [something] about [text]" as asking it about.

The block asking rule is not listed in the report asking it about rulebook.

That part works fine. However, I also wanted to add the ability for the player to ask the person about any thing in the world. The issue I am having is if I want a topic (text) to be used even if there is an object that also may have that text or part of it.

An example would be asking a character about “party/celebration/festivities”. Having that alone as a topic in their conversation table works great. But when I add, say a “party streamer”, the game will assume I mean the object and use the new action (which I called inquiring it about) instead.

What I’m looking for, if possible, is a way to go through the conversation table first, if it fails, then move on to the inquiry action (and it’s associated inquiry table).

I know I could just use the topic route and make a topic for every object, but I think that would require making loads of text similar to:

Understand "party streamer", "pink streamer/streamers", "streamer/streamers" as "[PartyStreamerTopic]".

for each object to handle all the variety of possible text combinations used in “Understand xxx as object.” so it would catch them all.

If there was some way to convert the topic to an object (or an attempt at it), I could check for the “ask about topic”, and if none is found, then “try inquiring the noun about” the object (which was a noun) or at least check for it and assign it to a variable and then inquire about that, but I don’t know if that is possible

Does that make sense? Sorry for the ramblings, but if you have any ideas or where I should look, let me know. Thanks in advance!

Edit: I marked @otisdog 's first answer as the solution, as it answered the specific question I was asking. It should be noted, however, for anyone reading this in the future, it might be worth simply using objects instead of topics at all as @rileypb to avoid the issue altogether.

Here’s a version that makes use of the Subcommands extension by @Draconis.

There’s some sort of issue with the values for the I6 variables consult_from and consult_words being stomped on, probably while checking the conversation table entries for a match in the topic column. (EDIT: Nope, these variables are just never being set in the first place. See below.) The workaround is crude; I’m just not up for tracing the actual issue this morning.

"Party Talk"

Include Subcommands by Daniel Stelzer.

Place is a room.

A person has a table name called convo table. The convo table of a person is usually Table of Default Responses.

Table of Default Responses
topic	reply
"nothing"	"'I'm not qualified to discuss that.'"
"weather"	"'Yep, it's happening.'"
"party/celebration/festivities"	"'It'll be fun.'"

Inquiring it about is an action applying to two visible things. Understand "ask [someone] about [any thing]" as inquiring it about.

[ If there is a topic that exists, give the reply matching it ]
After asking a person (called the NPC) about a topic listed in the Convo Table of the NPC:
    say "[reply entry][line break]".
    
[ First row of convo table should be what is said if the NPC has nothing to say about the topic - basically an error, no topic found message in a story-friendly way ]
Report asking someone (called the NPC) about:
    choose row 1 from the Convo Table of the NPC;
    say "[Reply entry][line break]";
    
Understand "Talk to/with [something] about [text]" as asking it about.

The block asking rule is not listed in the report asking it about rulebook.

Report inquiring someone (called the NPC) about:
    say "'I probably have something to say about [the second noun], but it's not clear what.'"


Alice is a woman in Place.

Bob is a man in Place. The convo table of Bob is Table of Bob Talk.

Table of Bob Talk
topic	reply
"nothing"	"'Maybe ask Alice?'"
"weather"	"'Sure is hot.'"
"party/celebration/festivities"	"'I'm looking forward to it.'"

The player carries a party streamer.

To decide whether (snip - snippet) can be found in (tab - table name):
    repeat through tab:
	    if snip matches the topic entry:
		    decide yes;
    decide no.

To decide which number is snipval of (snip - snippet):
    (- {snip} -).

[expose I6 variables that get stomped]
consultfrom is a number that varies. The consultfrom variable translates into I6 as "consult_from".
consultwords is a number that varies. The consultwords variable translates into I6 as "consult_words".

Instead of inquiring someone (called NPC) about something:
    let sub be the subcommand of the second noun;
    if sub can be found in convo table of NPC:
	    [reset stomped I6 variables]
	    now consultfrom is snipval of sub divided by 100;
	    now consultwords is the remainder after dividing snipval of sub by 100;
	    try asking the NPC about sub instead;
    otherwise:
	    make no decision.

Test me with "ask alice about party / ask alice about party streamer / ask alice about streamer / ask alice about festivities streamer / ask bob about celebration / ask bob about party / ask bob about party streamer"
2 Likes

I don’t use topics usually. I make everything that isn’t a thing already into a thing with:

A subject is a kind of thing. 

And make a subject for anything that isn’t already a thing. If you want those subjects to be used first, use the natural rule ordering:

Instead of asking someone about a subject:
1 Like

@otistdog Thanks for the information and lead to follow. I’ve never really touched any i6 stuff, and I’m quite a novice when it comes to that stuff,so it may take me a while to parse what is actually happening and sort through the extension to see how it is working.

But I’ll definitely give it a try to see if I can figure it out when I get a chance in the next couple of days.If I’m unable to, it’s still at least an interesting bit of info.

@rileypb Thanks for that! A pretty simple solution, no doubt. Objects I’d imagine are more complex than simple text, but when dealing with such small file sizes anyway, I can’t imagine making it making a huge difference anyway.

It would definitely make things simpler being able to use “Does the player mean”/“Instead of”/etc for deciding which a player should ask about based off actual objects.

I would suggest looking at Conversation Framework by Eric Eve. It’s where I got this technique.

1 Like

The whole point of extensions (in theory) is that you don’t have to worry about how they’re implemented, though I admit that I’m like you and prefer to understand how they work.

The Subcommands extension gives each object a property to hold a snippet value, and this is set when the parsing machinery decides that a given object matches some words of player input.

Snippets are what are processed in place of one of the nouns for actions that handle topics, such as the asking it about action. A snippet is a shorthand representation of a section of player input. Two pieces of information are encoded: 1) a position for the starting word and 2) a number of words. A snippet’s value stores both by calculating (100*starting position)+(number of words), so a value of 304 means “the four words starting at the third word of input”. If the player’s command is >TALK TO ALICE ABOUT INVITATION LIST, then the snippet that represents the topic understood will be 502 (i.e. the two words starting at the fifth word). For >ASK BOB ABOUT CONFETTI, the topic understood will be the snippet 401.

When parsing the grammar line (i.e. Understand line) for an action that uses a topic, these same two pieces of information are stored separately in the global variables consult_from and consult_words respectively. I realize now that the issue is that these variables are not being stomped – instead they’re never being set when the grammar line that matches is for the inquiring it about action, because that action uses a noun instead of a topic. The workaround just sets these to the values that they would have had if the grammar line for an asking it about action had been processed.

Since you seemed to want to be able to handle both topics and objects in conversation, and since you asked for a way to prioritize topics over things in cases where player input was ambiguous, that’s exactly what the example I gave does. When handling an inquiring it about action, the subcommand of the second noun (i.e. the snippet holding the words referring to it in player input) is checked against the NPC’s conversation table to see if there is a match. If there is, then the Instead rule doing the check reroutes action processing to an asking it about action for that snippet. Otherwise, the processing would continue for the inquiring it about action.

I personally find dealing with topics to be annoying and agree that there is much to be said for making all discussion driven by special-purpose objects.

3 Likes

@rileypb Thanks for that! I’ll be sure to give it a look over.

@otistdog Yeah, guilty as charged. If it is something terribly complicated or over my head, then I’m just glad it works (extensions, add-ons, whatever the case may be). But if I can I like to at least have an idea of what it does.

Thank you very much for taking the time to go through all that. The explanation you gave makes total sense. I could follow what you were saying quite easily and you answered my question perfectly.

I do see how objects would be a nice alternative, though. As for why I wanted it my way - well I suppose it is because I learned the ‘ask about topic’ long ago when I first tried Inform, so I just stuck with it. Then when I found a new issue I needed to tackle, I was trying to find a way to shoehorn it in.

But if creating objects just for the sake of avoiding all the clutter and simply doing a very small rework to use objects for everything is that much easier, I may go that route.

Thanks to both of you again for all the help!

@Draconis Oh and thanks for the heads up! I glanced very briefly Chapter 27.14 about using Inform 6 with Inform 7 after reading the replies in this post. It’s nice to know of a way to tidy it up if it comes to using it!

If you want to encapsulate all the I6 magic so you don’t have to worry about the details:

Include (-
[ SetConsultWords snip ;
    consult_from = snip / 100;
    consult_words = snip % 100;
];
-).

To set consultation variables to/for (S - a snippet): (- SetConsultWords({S}); -).

Then you can just “set consultation variables to the subcommand of the second noun”.

I’m not sure why I7 doesn’t set these variables when you “try” an action involving a topic, though.

1 Like