Dialogue tables by character and location

Referencing this thread (Dialogue tables automatically referenced by actor (and more)) but taking it a step further.

In my game where the player can be different characters, I’d like to choose from different NPC dialogue tables based on where that NPC is currently located and what character the player is playing.

Here’s some stripped-down code:


The Office is south of the Library. Character Select is south of the office.

The description of the Office is "The library is to the north and Character Select is to the south."

The description of Character Select is "Type the name of the character to play as:[line break]
- Kevin[line break]
- Roger"

Kevin is a person. The player is Kevin.

Susie is a person. Susie is in the Library. 
Roger is a person.

After reading a command while the player is in Character Select:
	if the player's command matches the regular expression "Kevin|kevin":
		say "You are now Kevin.[PlayerKevin]";
		reject the player's command.
	
To say PlayerKevin:
	Now the player is Kevin;
	Move the player to Office.

After reading a command while the player is in Character Select:
	if the player's command matches the regular expression "Roger|roger":
		say "You are now Roger.[PlayerRoger]";
		reject the player's command.
	
To say PlayerRoger:
	Move Roger to the Office;
	Now the player is Roger.

After asking Susie about a topic listed in the Table of SusieNPC_Kevin_Library when Susie is in the Library, say "[Response entry]".

Table of SusieNPC_Kevin_Library
Topic	Response
"library"	"'It has books, Kevin.'"

Table of SusieNPC_Roger_Library
Topic	Response
"library"	"'It has books, Roger.'" 

The After asking... bit is where the table switching needs to happen but I’m unsure of how to do that. Also, if I’m tackling this in the wrong way entirely, please lead me out of the woods.

I haven’t tested this so it might have bugs, but this might be one possible way of doing it :

Library is a room.
Kitchen is a room.

Kevin is a person in the Library.
Susie is a person in the Library.
Roger is a person in the Library.

When play begins:
	now the player is Roger.

After asking a person about a topic:
	let conv be a table name;
	let tfound be a truth state;
	let tfound be FALSE;
	repeat with N running from 1 to the number of rows in the Table of VariousResponses:
		choose row N in the Table of VariousResponses;
		if the CurrentRoom entry is the location of the player AND the PlayerName entry is the player AND the AskeeName entry is the noun:
			let conv be ConvTable entry;
	repeat with M running from 1 to the number of rows in conv:
		choose row M in conv;
		if the player's command includes Topic entry:
			say "[Response entry][line break]";
			let tfound be TRUE;
	if tfound is FALSE:
		say "Ummm......".


Table of VariousResponses
PlayerName	AskeeName	CurrentRoom	ConvTable
Kevin	Susie	Library	Table of SusieNPC_Kevin_Library
Roger	Susie	Library	Table of SusieNPC_Roger_Library
Susie	Kevin	Kitchen	Table of KevinNPC_Susie_Kitchen


Table of SusieNPC_Kevin_Library
Topic	Response
"library"	"'It has books, Kevin.'"

Table of SusieNPC_Roger_Library
Topic	Response
"library"	"'It has books, Roger.'" 

Table of KevinNPC_Susie_Kitchen
Topic	Response
"library"	"'It has an oven, Susie.'"

There are probably better ways!!!

Ade

Ade’s thing looks like it should work. There are probably a few ways to organize it, and which way would work best for you will depend on exactly how much variation you need and what the best way to organize the code turns out to be!

So basically the way I see it, the response could potentially depend on the identity of the PC, the identity of the NPC, and the location, as well as the topic. One thing you could do is make one giant table with columns for all those three things as well as the topics, and repeat through the table checking each row if it matches all three. This would probably be unwieldy.

What Ade does is to have a table with NPC/PC/location, repeat through that checking for all three, and then send that to a table that checks topics. This makes the individual topic tables nicer and easier to update, but it could wind up with a lot of tables.

You could also do a chain of tables. So assign each potential PC a table name; for each PC, have a table that lists the NPCs and assigns a table name to those (so now we have something like “Table of Roger_Susie”); and then the Table of Roger_Susie will have a column for the location and one for the topic, so you repeat through that checking to see if you match both.

One thing to think about is how you can organize this to have the least repetition. If Susie gives special responses to Roger in the library but gives the same responses to Kevin everywhere, you’ll want to make it so you don’t have to repeat Susie’s responses to Kevin for every room. (If every NPC gives different responses to every PC in every room… well, that seems like a lot of work.)

Some variations might be possible to handle with text substitutions. For instance, in your original code (which I’m sure was just a placeholder) the only difference in the responses was the use of the player’s name, and you can write a text substitution for that. (You’d have to say “[printed name of the player]” won’t work because “[the player]” will say “yourself.” Try “[The player] [are] [the printed name of the player]” and you’ll see what I mean.)

Another possibility is to use a rulebook to find an appropriate table name. So if Susie always gives the same answers except when she’s in the library, and she has one set of answers for Kevin in the library and another for everyone else, you can write rules to pick the appropriate table name. That might cut down on the number of duplicated tables.

Here’s an implementation of that:

The Office is south of the Library. 

Becoming is an action applying to one visible thing. Understand "[any person]" as becoming.

Check becoming the player:
	say "You're already [printed name of the noun]." instead.

Carry out becoming:
	[let oldself be the player;]
	now the noun is in the location;
	now the player is the noun;
	[now oldself is nowhere;] [commenting these out because leaving the oldself in the location gives us a way of moving characters around for testing purposes]
	try looking.
	
Report becoming:
	say "Now you're [printed name of the noun]."
	
The description of the Office is "The library is to the north."

Kevin is a person in the Office. The player is Kevin.

Susie is a person. Susie is in the Library. 
Roger is a person.

A person has a table name called the standard response table.

The standard response table of Susie is the Table of Susie's Standard Responses.
The standard response table of Roger is the Table of Roger's Standard Responses.
The standard response table of Kevin is the Table of Kevin's Standard Responses.

The conversation selecting rules are a person based rulebook producing a table name. [the person here is the interlocutor; we'll be able to get the player by checking directly]

A conversation selecting rule for Susie when the location is the library:
	if the player is Kevin:
		rule succeeds with result Table of Susie's Library Responses To Kevin;
	otherwise:
		rule succeeds with result Table of Susie's Library Responses.
	
Last conversation selecting rule for a person (called the interlocutor):
	rule succeeds with result standard response table of the interlocutor.

Instead of asking a person (called the interlocutor) about a topic:
	let the conversation table be the table name produced by the conversation selecting rules for the interlocutor;
	if the topic understood is a topic listed in the conversation table:
		say the response entry;
	otherwise:
		say "[The interlocutor] shrugs."

Table of Susie's Standard Responses
Topic	Response
"library"	"It has books, [printed name of the player]."

Table of Roger's Standard Responses
Topic	Response
"library"	"It has books, I guess."

Table of Kevin's Standard Responses
Topic	Response
"library"	"It has shelves."

Table of Susie's Library Responses
Topic	Response
"library"	"It's nice here."

Table of Susie's Library Responses To Kevin
Topic	Response
"library"	"I'm glad to see you here."

[This has a weird thing where, once you stop being Kevin, you can no longer refer to Kevin, but hopefully the way the conversation works is more apparent.]

1 Like

@McTavish and @matt_weiner, thank you both! This is extremely helpful. Both work well.

One thing though, Ade, if you have a topic about the NPC (so “Susie” in this case), you get two responses in one go: one about the intended keyword and one about Susie. Not the end of the world but odd.

1 Like