Threaded Conversation extension needs testers

I think the Threaded Conversation extension, which I took over development of for Emily Short, is nearly ready for full release. Before I submit it to the official extension site, though, I’d like to have several more dev-focused eyes look it over.

Hence, a kind of public beta: if you’re willing to try it out and send feedback, I appreciate it! I’m especially interested to hear how useful (or not) you find the documentation working through learning the system, but any comments would be helpful.

The extension files should be attached to this post. I can take reports by PM; or, message me for my contact email.

Questions/issues:

  • I’d like to list testers in the extension somewhere, as thanks. In this prerelease version, they appear in the last section, before the examples. OK? Too visible? And, it’s been a while since I first recruited these testers; I’ve already had one person not request to be listed, and many others have not responded lately; but my inclination is to err on the side of credit. What’s the etiquette here?
  • Menus/hyperlinks. One of ES’s original goals was to support combining this extension with menus or hyperlinks, but currently the code has no real hooks to facilitate this. I haven’t really ever looked into either type of system. Would there be much demand for this extensibility to be built-in?
  • Spelling. The extension uses American conventions in its documentation and examples, owing to the origin of its developers, but the documentation of Inform 7 is largely written in British English (and, to a lesser extent, so are its examples). For the moment at least, I assume this is fine.
  • Authorship. This extension obviously owes at least as much to Emily Short as myself, but Inform currently does not support change of stewardship of extensions very well, potentially breaking existing source code—including Alabaster’s—due to the author change. This is hopefully going to be improved in the next release of Inform 7.

see this page for latest version

The output of this seems familiar. Emily Short used this in Counterfeit Monkey, didn’t she?

I want to use this in a project I’m just starting, but I’m having a little trouble. I’ve got a radio, which can be tuned to different channels. Depending on the channel, the player can talk to different characters. I’ve tried putting the character in scope when Discussing, but it just tells me ‘that’s not a topic now’ or thereabouts. I’d actually expect it to tell me ‘you’re not talking to Gus’, as it does when Gus is standing right next to me and I try to ask Gus something without greeting him first.

I’d also like implicit greetings. Is there a way to re-enable the implicit greeting from Eric Eve’s conversation framework that this appears to be built on?

Yes, or more specifically, her older version from last year.

It’s hard to diagnose without code; can you post some of yours that isn’t working the way you want? I believe that implicit greetings should be working as well, though it’s a surprisingly tricky logic issue: the game can’t properly determine whether a given command is an attempt at discussing or not until the interlocutor has already been greeted, because the list of possible quips to discuss is stocked based on the identity of the current interlocutor.

The common ask/tell paradigm doesn’t have this same issue, because it deals with nouns and topics, which rarely change their known/unknown status, especially within the course of a conversation; Eric Eve’s standard epistemology model (or even none at all, as in the Inform default) can handle this on its own. In contrast, the availability of quips can change drastically from turn to turn, and for many different, quip-specific reasons.

Al right, I seem to have got it partially working. The problems seems to be with asking when there is no current interlocutor, and the error message it produces. If you type “ask bob something”, it tells you that “That doesn’t seem to be a topic of conversation at the moment.”, whether you’re talking to Bob or not. The behavior I’d expect is an implicit greeting if I used the command ‘ask bob something’ and was not already talking to Bob, and that having ‘bob’ in there would not make it fail when I was talking to Bob. (I understand it’s looking for a quip named ‘bob something’ in this case.)

"ThreadedConversationExample" by Blecki

Include Threaded Conversation BETA by Chris Conley.

Gus is a man.
Bob is a man.

The radio is a thing. The player carries the radio.

After deciding the scope of the player when discussing (this is the place radio interlocutor in scope rule):
	Place Gus in scope.
			
After deciding the scope of the player when saying hello to (this is the place radio interlocutor in scope when greeting rule):
	Place Gus in scope.

an unimportant question is a questioning quip.
The comment is "X, Y? Maybe Z?".
The response is "'Xyyzy, clearly,' says [the current interlocutor].".

The oblong box is a room. "You can reach Gus through your radio."
Bob is in the oblong box.

Both Bob and Gus behave the same in this example. I can make one use case work by understanding ‘bob’ as the quip, but I’d have to write understand rules for every combination of quip and character to do it properly, and it still wouldn’t take case of an implicit greeting.

Right, that’s what I mean: the code can’t determine if you’re trying to discuss, because there is no interlocutor. Ideally it would be nice to implicitly greet the person, then generate a new action to try asking them about the [something], but Inform doesn’t really allow that. This thread goes into some of the technical details.

But anyway, this doesn’t seem like improper behavior to me…? “Something” doesn’t refer to any quip defined in this code, so the error message is correct: that’s not a topic of conversation available, whether you’re talking to Bob or not.

And it shouldn’t be looking for a command named “Bob quip”: Understand "tell [someone] that/about [a typable quip]" or "ask [someone] that/about [a typable quip]" or "tell [someone] [a typable quip]" or "ask [someone] [a typable quip]" as discussing it with (with nouns reversed) when the second noun is the current interlocutor. handles that case.

But, hmm, it’s not. And I can’t see why. This minimized extension+your example works:[spoiler][code]“ThreadedConversationExample” by Blecki

[Include Threaded Conversation BETA by Chris Conley.]
Include conversation framework by Eric Eve.

a quip is a kind of thing.

A quip can be informative or questioning.

A quip has text called the comment. A quip has some text called the response.

The quip-repository is a privately-named transparent closed unopenable container.
When play begins: now every quip is in the quip-repository.

After deciding the scope of the player while discussing, discussing something with:
place the quip-repository in scope.

Understand the commands “ask”, “tell”, “say”, “discuss”, “answer”, “a”, “t” as something new.

Discussing it with is an action applying to two visible things.

Understand “discuss [a quip] with [someone]” or
“say [a quip] to [someone]” as discussing it with
when the second noun is the current interlocutor.

Understand “tell [someone] [a informative quip]” or
“ask [someone] [a questioning quip]” or
“tell [someone] that/about [a informative quip]” or
“ask [someone] that/about [a questioning quip]” as discussing it with (with nouns reversed)
when the second noun is the current interlocutor.
Understand the command “a” as “ask”.
Understand the command “t” as “tell”.

Understand “discuss [text] with [something]” or
“say [text] to [something]” as a mistake (“You’re not talking to [the noun].”)
when the current interlocutor is nothing or
the noun is not the current interlocutor.

Understand “tell [something] that/about/-- [text]” or
“ask [something] that/about/-- [text]” as a mistake (“You’re not talking to [the noun].”)
when the current interlocutor is nothing or
the noun is not the current interlocutor.

[instead of subjectifying something to:
try saying hello to the second noun.]

Check saying hello to the player:
say “Talking to yourself is unrewarding.” instead;

Rule for supplying a missing noun when the second noun is a quip: try discussing the second noun instead.

Check discussing something with when the second noun is not the current interlocutor:
abide by the greet a new interlocutor rule.

Carry out discussing it with:
try discussing the noun.

Discussing is an action applying to one visible thing.

Understand “talk about/-- [a quip]” and
“say [a quip]” and
“discuss [a quip]” as discussing.

Understand “change the/-- subject to [a quip]” and
“tell about [a informative quip]” and
“ask about [a questioning quip]” and
“tell [a informative quip]” and
“ask [a questioning quip]” as discussing.

Gus is a man.
Bob is a man.

The radio is a thing. The player carries the radio.

After deciding the scope of the player when discussing (this is the place radio interlocutor in scope rule):
Place Gus in scope.

After deciding the scope of the player when saying hello to (this is the place radio interlocutor in scope when greeting rule):
Place Gus in scope.

an unimportant question is a questioning quip.
The comment is “X, Y? Maybe Z?”.
The response is “‘Xyyzy, clearly,’ says [the current interlocutor].”.

The oblong box is a room. “You can reach Gus through your radio.”
Bob is in the oblong box.

every turn: showme the current action.

test me with “ask bob question/ask bob about question”.[/code][/spoiler]

That means somewhere between here and the full extension code, some of those understand lines are breaking down. And that’s annoying, because this section is pretty much the only part of the code that deals with understanding.

In the example, if you ‘ask bob unimportant question’ it responds ‘that is not a topic of conversation’.

How would you suggest replacing the ‘is not a topic of conversation’ with ‘you aren’t talking to anyone’ when the current interlocutor is no-one? Implicit greeting would be nice, but even as it stands, the response to something like ‘ask bob something’ when you aren’t already talking to bob is ‘that is not a topic of conversation’, which suggests the player that they can’t ask bob about it ever. A ‘you aren’t talking to anyone right now’ is a good prompt to get the player to initiate a conversation with bob and then try the question again.

If there’s a solution to the implicit greeting problem I’m going to find it. What if we did something like:

interlocutorless-quizzing it about is an action applying to one thing and one topic.
Understand "ask [someone] about [text]" as interlocutorless-quizzing when the current interlocutor is noone.

quizzing it about is an action applying to two things.
Understand "ask [someone] about [something]" as quizzing when the current interlocutor is not noone.

Carry out interlocutorless-quizzing it about:
   Now the current interlocutor is the noun;
   Reparse the player's command.

Carry out quizzing it about:
   Etc.

Expand with the details of your topic selection mechanism. Since the initial action accepts any text, it doesn’t need to know what topics are valid.

Actually it seems like

Understand	"tell [something] that/about/-- [text]" or
	"ask [something] that/about/-- [text]" as a mistake ("You're not talking to [the noun].")
	 when the current interlocutor is nothing or
	  the noun is not the current interlocutor.

should produce the error message I want except that it doesn’t appear to ever match a command.

I apologize for spamming your thread but this has to be possible.

I included Aaron Reed’s smarter parser because it implements command reparsing, and then I implemented it myself. Took me forever to figure out that the reason I couldn’t get it to work was because you already did it! Unfortunately, it doesn’t actually work. The actions are overriden by an ‘understand … as a mistake’ phrase. If you get rid of that phrase, the output is of the form:

You could ask [list of available topics].

You can't think of anything appropriate to say. 

You could ask [list of available topics].

Replace the line ‘now the reborn command is “[player’s command]”;’ with ‘now the reborn command is “ask [the topic understood]”;’ to work around the issue (Breaking tell, obviously) with ‘ask interlocutor about quip’ not working. The extra set of topics seems to be being produced by Conversation Framework, not your extension.

Another problem, though: Smarter Parser likes to intercept complicated input to be ‘helpful’, and these conversations tend to produce the sort of complicated input smarter parser likes to intercept. So you get weird error messages.

The following appears to work: (Again, sorry for spamming your thread.)

  • Remove the ‘understand “ask…” as a mistake’ phrase.
  • Modify the understanding of discussing it with to de-reverse the nouns.
Understand 	"tell [someone] that/about [a typable quip]" or 
	"ask [someone] that/about [a typable quip]" or
	"tell [someone] [a typable quip]" or 
	"ask [someone] [a typable quip]" as discussing it with when the noun is the current interlocutor.
	 
Rule for supplying a missing noun when the second noun is a quip: try discussing the second noun instead.

Check discussing something with when the noun is not the current interlocutor:
	abide by the greet a new interlocutor rule.

Carry out discussing it with:
	Say "N[the noun] SN[the second noun]";
	try discussing the second noun.

Why were they reversed? Am I missing something? Either way I don’t think the ‘supplying a missing noun…’ rule will ever be called as another understand rule matches commands without the noun.

  • Remove the ‘understand … as asking’ and ‘as telling’ phrases in the last bit that uses Smarter Parser. These just seem to be funneling all attempts to ‘ask someone about’ to an ‘expression of ignorance’ rule.

It now appears that ‘ask someone about something’ works in all cases. Implicit greetings also work as long as Smarter Parser is included too.

In the conversation builder, you’ve taken care of ‘have’ not being a fantastic word to have in an object name by replacing it with ‘hath’ (bravo, btw.) The same care needs to be taken with ‘when’. Might I suggest ‘wence’?

“Hath” is an archaic spelling of “has”, but “whence” (note spelling) means “from where”.

“Whan” would be sort of appropriate (see the Canterbury Tales) but completely confusing.

Might want to just go with “when-” and document it.

Oh, wow. “Discussing it with” is the action, hence the reversing: the action takes the form “discussing the question with Bob”, for example; so Inform needs to know when the acceptable syntax (as in “>ask Bob the question”) will put the interlocutor first, instead. But the problem here is actually related – the condition at the end, “when the second noun is the current interlocutor”, needs to reference the (first) noun instead of the second: apparently Inform does not reverse the nouns before that condition is checked. Which makes sense, now that I think about it. Thanks!

Also, don’t worry about spamming the thread, it’s fine. If there’s no intervening posts, though, you might want to just edit one post to write more, instead.

Actually, the Builder extension has a feature that handles the escaping of problematic names when building: Blecki is proposing another entry in the list. I’ll use “whenever” as its doppelganger: the idea is for something that plays as near the same role in a sentence as possible. I bet “while” would be another problem word, but “whilst” is an obvious replacement there.

As for implicit greetings, I’d prefer to minimize dependency on further extensions as much as possible…

Then I’d say either drop the ‘understand as a mistake’ rules into a ‘for use without smarter parser’ section, or cut the bit that uses smarter parser for implicit greeting entirely. Maybe release it as a separate extension for use with this?

Anyway it seems to be doing everything I want now. I would like better error messages for the player though. ‘X is not a topic of conversation’ comes up a lot when more specific error messages would be helpful to the player.

Done. See new version, attached.

That’s a good idea – I originally just added the “not a topic” error message to replace the “can’t see any such thing” library default message from when I went back to the off-stage container of viable quips (as that turned out to be the simplest way of handling quips’ scope).

What sorts of error messages would you like to see, as a base?

And thanks again for your help, it’s really taking shape!
Threaded Conversation BETA.i7x (136 KB)
Conversation Builder BETA.i7x (39.3 KB)

Yay. Here’s a new issue:

Sometimes the conversation builder will generate a performative quip. It seems to be doing this when it has to replace words like ‘what’. I hook that quip up to a subject expecting the player to be able to type ‘what makes something so great’ or ‘ask about something’, but since it generated a performative quip ‘ask’ doesn’t work on it at all. Which is quite unexpected for the player, since ‘ask what makes something so great’ seems perfectly reasonable.

For error messages:
When there is no current interlocutor, the error ‘you aren’t talking to anyone’ is much better than ‘that is not a topic of conversation’. It clues the player that they need to greet someone first.

The implicit greet using smarter parser appears to be broken again.

  • On the understand as an error rules, -For use without… needs to be (For use without…)
  • The rules that funnel ask/tell to the ignorance about stuff are still catching all input after the implicit greet. In fact, ‘ask [someone] about [something]’ seems broken in general. ‘ask something’ works, ‘ask about something’ works, ‘ask current interlocutor about something’ does not. This is troublesome because the implicit greet can’t work unless ‘ask someone about something’ works.

When not using Smarter Parser:

>talk to gus
You could ask gus such and such, etc

>ask gus about subject
You aren't talking to gus.

Say what? It seems to be because I’m asking about a subject, so none of the rules catch it. However, I was under the impression that the purpose of saying a quip mentions a subject was so that asking about that subject would trigger the quip? It actually seems to currently be impossible to trigger the ‘discussing it with’ action at all.

Alright. Removing the ‘when the noun is the current interlocutor’ etc from the discussing it with understand rules makes it work. There’s a rule there already to catch the case when the noun is not the current interlocutor and it can print a message. I also added a ‘when the current interlocutor is not nothing’ so the rules won’t interfere with the mistake rules. It seems that, if the player is talking to bob, and asks something of gus, the quips it selects from will be bob’s, so the command will have to be rejected another way. Are you certain the noun and the second noun are properly set by time the parser gets to the ‘when’ rule? I don’t think they are. It may be using the values from the previous command.

I’ve attached my ‘fixed’ copy.
Threaded Conversation BETA.i7x (136 KB)

Here’s a new version: hopefully those issues are fixed. At least, all except for:

Yep, that’s the technical issue preventing implicit greetings I mentioned on the last page. It’s kind of a catch 22: can’t determine if the attempt to discuss a quip is valid syntax without an interlocutor; can’t set the interlocutor unless a valid action was understood.

I think it’s partly because the Understand “say [a typable quip]” as discussing and related phrases are doing double duty: identifying from syntax what action the player has intended, and (through my “typable” adjective in this case) specifying which quips are valid to be used in it. But I don’t think those two functions can be separated.

You may be right.
Threaded Conversation BETA.i7x (136 KB)
Conversation Builder BETA.i7x (39.6 KB)

It should be pretty simple to resolve. In the carry out discussing it with, if the person we’re trying to talk to is not the current interlocutor, you can either reject the command entirely with a ‘you aren’t talking to them’ error, or if Smarter Parser is being used, you can implicitly greet the new interlocutor and reparse the command.

Hmm. When I replace the last section with this, though, the starting a conversation with it about action never gets understood. I haven’t used Reed’s extension before but the problem is in my code somewhere.

[code]Starting a conversation with it about is an action applying to one thing and one topic.

Understand “discuss [text] with [someone talk-ineligible]” or
“say [text] to [someone talk-ineligible]” as starting a conversation with it about (with nouns reversed)

Understand “tell [someone talk-ineligible] [text]” or
“ask [someone talk-ineligible] [text]” as starting a conversation with it about.

Carry out starting a conversation with it about:
implicitly greet the noun;
if the noun is the current interlocutor:
follow the relabel available quips rule;
now the reborn command is “[player’s command]”;
now sp reparse flag is true.[/code](or see attached)
Threaded Conversation BETA.i7x (136 KB)

It’s actually probably a good idea to yank the reparsing bit out of Smarter Parser and use it alone since anyone using this extension will have to disable Smarter Parser’s actual functionality anyway - it will replace your error messages with far less helpful ones.

It looks like you’ve forgotten the variations that include the word ‘about’. At a glance it seems like ‘ask [someone] [text]’ would catch that (about would just be part of the topic understood) but I think the parser might think the earlier ‘ask [someone] about [quip]’ is a better match.