Machine Learning (verbs) in Interactive Fiction?

Has there ever been any kind of (preferably open source or at least documented) effort to introduce machine learning to reduce the guess-the-verb problem?

I have been trying to do to something like this (xyz is the internal process)

> watch bird
** "watch" = ? **
=> I don't know what Watch means
> x bird
** "watch"=x(=examine) **
=> You see a bird
> watch cow
** watch = examine **
=> You see a cow

Of course, it won’t work this way (misspellings, player changing their minds between two commands, accidental usage when player meant something else) and I have been toying around this idea with approaches like delayed learning (you have to use the word multiple times), numerical ranking (computer keeping track of how similar the two words are), explicit confirmations (“Does watch means examine? {y/n}”), using a dictionary (so that player’s response actually validates the meaning stored already), etc. but nothing seems to work properly and seamlessly (closest was the dictionary one). Any pointers? (not necessarily related to Interactive Fiction but better if they are)

That approach doesn’t really deal with the guess-the-verb problem, though, since the computer can only figure out what the player meant when it’s too late (After they have successfully guessed the verb).

Yes, but if this is a feature of engine (instead of a particular game); next time when the player enters “watch” instead of “examine” in any game, they won’t need to guess it again. Or at least, so goes the theory…

This sounds tricky. It may be that treating “watch” as a synonym for “examine” makes sense in one game, but produces an unsatisfying or wildly inappropriate response in another game. I mean for the easy cases, various IF systems have these big standard libraries of verbs… and then if you want to make a game that’s any good you typically have to go through and figure out how to override or customize all of the responses that are trying too hard. I mean if it were easy, you could just download WordNet and shovel a crapton of prepackaged synonyms into your library/game/system/whatever and everything would be perfect forever, right?

I guess I could imagine something where your ML system trains over a very large number of transcripts that were collected along with like heart rate data from fancy smart watches or whatever, from some large number of games distributed on some platform where you can do that, and eventually it figures out how to tell which verbs it should map to which other verbs in which games in order to minimize the mean squared player blood pressure or whatever, such that it could actually make useful predictions for games that have been out for, like, less than a year. Maybe you could even do it just from transcripts, given enough data? First you train a system to recognize signs of player frustration by… I don’t know… presumably you need an army of grad students to go in and tag things somehow? Which is cheating, right? Because if you’re going to get a human to look at it, the human could be like, hey, people keep typing WATCH BIRD, but it doesn’t work, maybe we should add a synonym.

I don’t have much to add but your topic reminded me of this thread, https://intfiction.org/t/using-a-dictionary-database-to-build-a-smarter-parser/7782/1

This is the problem I am tackling with: how to get the computer to gain enough context to know when to replace by the synonym and when not. Right now, I am trying to do this by storing the kind of noun a particular synonym has been used with and creating some kind of “this object is a bit similar to that object in this way” kind of database, but I don’t see it working.

That’s what I thought at first :slight_smile: (see my attempt of using dictionary)

If only I was Google…

Thanks

My view of this is somehow telling the VM to report on an action from a VM perspective and not with prose.

Given this capability and assuming you can always throw away the results of a turn (save every last accepted player turn), the client/interpreter could build some logic to respond to the VM report in a logical manner. This might include looking up words, synonyms, grammar with 3rd party tools.

–dc

In Hadean Lands, “say”, “sing” and “invoke” are all synonims.

I don’t want to sound discouraging, but it looks an awful lot like spending a lot of energy fixing something that isn’t broken. It might not be possible to do this entirely machinewise; which is why beta-testing is always so important. That’s usually the stage where all the relevant synonims get implemented. By a consciencious author.

This is actually interesting, any good resources you might point to?

I think a number of people have worked on asking the parser questions in a meta-data manner. I’ve done only really simple things, but it is my long-term goal to build more of these types of things. I would like to be able to query the VM for many things without disrupting game play.

To be honest, what I’d really like is a terp that lets me revise code as I go. That is, if I hit a missing synonym while testing, I can add it on the fly.

watch cow
I don’t know that verb!
*watch means examine
OK verb added.

and the source code would automatically modify the relevant part, rather than me wasting time on a search.

This would be good for one-shot no-change-to-world-state comments, like snarky things.

eat rock
That is not possible.
"As delicious as it looks, you’re on a diet.
OK message set.

The latter part might be possible in Inform 7, sort of.

Keep track of the most recently issued Response:

The most recently issued response is a response that varies.
After issuing the response text of a response (called R): now the most recently issued response is R.

Add a table to keep track of the replacements:

Table of Response Replacements
original (response)    replacement (text)
with 10 empty rows.

Make a new action:

Response-replacing is an action out of world applying to a topic.
Understand "new response [text]" as response-replacing.
Carry out response-replacing:
    choose a blank row in the Table of Response Replacements;
    now the original entry is the most recently issued response;
    now the replacement entry is the substituted form of "[the topic understood]".
Report response-replacing:
    say "[bracket]Response replaced.[close bracket]".

(I don’t know if there’s a way to alter a response through a pointer? If so you could do this in another Carry Out rule, so that the new response is used for the rest of the play session.)
And finally print all of this when the player wants it.

To give new response code:
    say "Section Z - New Responses[line break][line break]";
    repeat through the Table of Response Replacements:
        say "The [original entry] is '[replacement entry]'.[line break]".

You could also print this to a text file if you liked. Either way it gives code you can copy-paste into Inform to change those responses.
Disclaimer: this is not tested.

You could also allow replacements just for specific actions, not full responses. Keep track of the action being performed (using a stored action), then print out Instead rules. This part would be significantly simpler. And a cleverly-written Instead rule could check the table for each action and give the new response if it found one, so changes would take effect “immediately” (i.e. without a recompile, though they wouldn’t be a permanent part of the game yet).

…now I’m intrigued by this idea. If I created an extension for this, would others find it useful? I personally test in the IDE so the source code is always at hand, but others might do things differently.

EDIT: Teaching new verb and noun synonyms would be possible in the same way. The commands would have to be phrased differently, as Inform doesn’t let you have a command applying to two topics, but you could use some of the I6 code from “oops” to store the misunderstood word, then have a command like “>means examine” that would add that word as a synonym for “examine” or whatever. (The I7 code it generated would be something like “understand the command ‘watch’ as ‘examine’.”.)

It’s also possible, if you’re using blorb files, to have a blorb dedicated to post-compile game transformations (input or output). This could be as simple as a list of regular expressions or something more complex.

I really like the idea that you could potentially generate inform code while playtesting a game. Threaded Conversation’s Conversation Builder pretty much does this when you ask an npc something they don’t know about - the game sidelines and lets you build what the response should be.