Unlocking Keywords

So. Keywords in TADS. I did it. But I did it badly. And now before I make another game using them, I want to see if I can do them properly.

Basically, I used exactly the same method to implement keywords that Aaron Reed did in Blue Lacuna - namely, I implemented an action like this:

VerbRule(Keyword) singleDobj | 'keyword' singleDobj | 'use' singleDobj : KeywordAction verbPhrase = 'keyword (what)' ;
I was surprised that lifting code from Inform 7 to TADS worked as well as it did. But it has a lot of problems.

Say you’re in a location which is empty except for a single takeable object. A coin, maybe. A desirable exchange would be:

At the very least you’d like to see:

But what you actually see is:

Whoops. Obviously, the parser is matching this to the keyword action. It sees the command as “>singledobj” where singledobj is “take”, which is not a visible object.

I should add that this confusion is not universal, typing “take coin” explicitly will work. It just seems that the parser assumes that a valid command is more likely than a command for a non-existent object, which is more likely than an incomplete or implicit command.

Inform seems to prioritise the last two situations (at least when it comes to keywords) the other way around, which isn’t without its problems, but at least allows authors to implement keywords without also sabotaging the standard behaviour of the parser.

Is there a way around this? Ideally I’d like to be able to use keywords and retain normal commands. Hell, I’d like to be able to use keyword actions to refer to topics, but I can only imagine the mischief that would cause (I got around this using conversation nodes and special topics, but that comes with its own headaches).

Alternatively, if I can’t rehabilitate the parser, I want to euthanise it. Could I use the TADS parser’s matching and disambiguation without first checking for verbs? Essentially just skip straight to searching for a direct object or topic that’s in scope/known about and then call a method on it?

Looks to me like the VerbRule you’ve written will match any single word that doesn’t have other grammar – ‘take’, ‘wear’, ‘use’, ‘hit’, and so on. Essentially, the parser is doing what you requested by defining the grammar of that VerbRule.

Another way to implement keywords would be by making them verbs. For instance, if you want ‘coin’ to be a valid keyword, with the implicit action ‘take’, write a VerbRule (CoinTake) with an an execAction that first checks whether the coin object is in scope and then, if it is, causes the indicated action, otherwise printing out a suitable error message, such as mainReport('You see no coin here. ');.

This is more work, but it strikes me as easier to control. You could spiff it up in various ways – for instance, if the coin is already in the player’s possession, the same command might trigger an examine action instead. Or, if the player is in the room with the vending machine, ‘coin’ might translate to ‘insert coin in slot’.

–JA

That certainly is one solution, and one I used for some keywords in Walker & Silhouette, but it is a lot more work.

I like to define consistent actions on whole classes of objects, which this method precludes. And if I’m going to have to change my game-making process to implement the world in a rules based fashion, I might as well just use Inform 7 (which, funnily enough, in this case would allow me to use more OOP).