Twine2 Sugarcube2 - dialogue keywords

Hi,
New to Twine2 but making good progress. Currently using Sugarcube2 and tinkering with making a ‘dialogue’ feature where the player can type in responses using the textbox macro.

So first of all I get it to work with simple ‘if/elseif’… but it will only accept ‘exact responses’. Next I made it work with ‘if/elseif’ combined with the either(…, …, …) but again it will only work with exact responses.

Is there a way to make it ‘pick out’ if one of those keywords appears anywhere in the players response (and can I make the feature not case-sensitive?)

example:
Carhacter asks ‘where are you from?’ and the player can respond in the textbox that they are from Europe. (so in my either list I might have “Europe”, “europe”, “France”, “france”, “Italy”… etc.)

If the response is one word answer then easy enough but what if they respond:
“I am from xxx” … is there a way to make my if/elseif assign a response triggered by the keyword of that sentence?


Thanks if advance.

(Moved this to the “Twine” category: the “Dialog” category is for a different programming language.)

Thank you,
sorry I couldn’t see where to post it

Writing a text parser (like those used in Interactive Fiction / gaming engines like Inform / TADS / ADRIFT) is not a simple thing, especially if you want it to understand more natural language like statements like “I am from xxx”

If you are considering making a Text Parser based project then I suggest looking at the engines that come with such functionality built-in. You may also be interested in reading the Progress of the Parser thread on this forum.

1 Like

Well, first of all, if you’re looking for country names, you should ask, “What country are you from?” Otherwise people might answer what state or province they’re from or what city they’re from. (You might also want to say, “What country do you currently reside in?”, since “What country are you from?” could be interpreted to mean, “What country were you born in?”, “What country did you grow up in?”, or “What country do you currently reside in?”, which could all be different answers.)

If your responses depend on specific country names, then you could create an array of country names, and then search the string for those names. For example, you could put this in your JavaScript section:

setup.countries = ["Europe", "France", "United States of America", ..., "United States", "America", "USA", "US"];
setup.getCountry = function (txt) {
	for (var i = 0; i < setup.countries.length; i++) {
		if (txt.toLowerCase().indexOf(setup.countries[i].toLowerCase()) > -1) {
			return setup.countries[i];  // Return country name
		}
	}
	return txt;  // Country not found
};

The .toLowerCase() method will make sure that the search ignores any capitalization issues. Also, because setup.countries and setup.getCountry won’t change, they’re put on the setup object variable so that they’ll be accessible from both JavaScript and SugarCube code and won’t waste space in the game’s history.

Note that, when you fill in the rest of the country names (where the “…” part is), you’ll want to put any country names which could be a subset of another country’s name, such as how “US” is a subset of “Belarus”, at the end of the list. Generally the rule should be that longer names go in the front of the array, and smaller ones at the end.

Keep in mind though, that this code is pretty simple and may get “false positives”. If they type in “my house”, then it will find the “US” in “house” and return “US” as the country name. If that will be a problem, then you’ll need to modify the code to make sure it isn’t finding the name within other words.

Also, if the getCountry() function doesn’t find a country name, then it will just return the original string. You could change that if you want to be able to tell when a country name isn’t found. (Just change the “return txt;” line into something like “return 'unknown';” instead.)

Now, for example, if the text to be searched is in a variable named _response, then you could get the country name like this:

<<set $country = setup.getCountry(_response)>>

That said, a far simpler solution would be to use the <<listbox>> macro, and have it contain a list of country names they could pick from. There are also trickier solutions, where you could have the code attempt to guess the country name being typed in, and have that appear in a dropdown below the text entry line. If you were going to do that, I’d recommend using something like the jQuery UI Autocomplete Widget.

Hope that helps! :slight_smile:

Thank you both! I’ve been dabbling with Twine2 the past couple of weeks and have quietly learnt so much from you two in the various tutorials, codes and comments on the web.

Greyelf, if the main theme of my game were to be more dialogue based then I’d have a look at another option, but really this is just a conversation type feel I wanted to create at the beginning as a way of ‘mining’ information to bring back up later in the game.

What I’ve done so far works well but I’ve found myself revisiting the part to use it as a learning experience and develop better methods that include more opportunities. The answers help me to steer the player towards certain routes.

Thank you HiEv, I’m going to look at what you’ve suggested and try to implement it. Great tip about US being in Belarus! I hadnt thought of that.