How to make the parser always ask which do you mean?

The question is in the title. To explain it further, here’s a use case:

A sword is a kind of thing.
Sword1 is a sword. Sword2 is a sword. Sword3 is a sword.
The armory is a room.
Bob is in the armory. The player is in the armory.
Bob is carrying sword1. The player is carrying sword2. Sword3 is in the armory.

The problem is, if the player’s command is >look sword… the parser seems to always assume it means to look at the sword the player is already carrying. Now, with more fleshed out code, the descriptions and printed names of these things might be more fleshed out, but as you can see, I am trying to use assemblies of kinds, so sometimes the swords will still be described very similarly, or exactly the same.

Commands like >look Bob’s sword work, (possibly because of code I have elsewhere that give’s ownership to things?) but I have no idea how the player in this case would be able to target the sword that isn’t held by anyone by default in this use case. So, I tried adding some “does the player mean” stuff, but I can’t get it right. I can affect the behavior, but I can’t get it to where in any use case combination of swords on the ground or held by various characters that >look sword will always pull up a “which do you mean?”

In my opinion, it should always trigger a which do you mean if there are two of a kind of thing visible and the command doesn’t specify the exact description of the item. I am using numbered disambiguation, and other code to always make it so a person holding a thing get’s their name printed with it, so using assemblies this way should be fine as long as this numbered prompt always comes up… but it doesn’t.

Here is the last attempt at the does the player mean I was trying:

Does the player mean doing something with a thing held by the player: it is unlikely.
Does the player mean doing something with a thing held by a visible person that is not the player while a visible person that is not the player is holding a thing: it is possible.
Does the player mean doing something with a thing not held by a person while a visible person that is not the player is holding a thing: it is possible.

My code above was the product of going nuts. The below still doesn’t work, but is probably less insane:

Does the player mean doing something with a thing held by the player: it is unlikely.
Does the player mean doing something with a thing not held by a person: it is possible.
Does the player mean doing something with a thing held by a person that is not the player: it is possible.

A which-do-you-mean question won’t be of any use unless there is some word in each of the names of the objects that can serve to distinguish it from the others. Suppose you enter the command X SWORD and the parser answers ”Which do you mean, your sword, Bob’s sword or the sword?” There will still be no way for the player to choose the sword called simply “sword” (since the two other swords are also partly called “sword”). You need to give the last sword a name that allows Inform to distinguish it from any other sword.

In the case you give code for:

–you actually already give the three swords distinct internal names (“Sword1”, “Sword2”, and “Sword3”). The simple way out then would be give them distinct names that the player is allowed to use.

I understand that this is not the kind of answer you want, but it would be playing along with the way Inform 7 already works – and why not?

Well, supposing you have a good reason for why not – I once wrote some code that makes Inform understand Printed Names (and the printed names of things can of course perfectly easily be changed dynamically). You’ll find it here: <[url]]>.
Be warned, though, that this way of doing it (and it was the only way I could come up with) comes at a performance cost that can be quite noticeable, at least if the names of things are long.

I want to revisit this… I really can’t rely on the player knowing the names of things, because I’m using assemblies and giving items descriptive properties, and then creating an indexed text and using that as the printed name. This means that “a perfect sword”, “a rusty sword”, “Bob’s sword”, “your sword” can all be in the same place.

I forgot to add in my example that ‘Understand “sword” as a sword.’ is part of the equation, so no matter what the exact name of the thing is I want the player to be able to enter “take sword”, and always get a list of swords in the location. Again, no matter what “Does the player mean” I try, there are some use cases where the parser just goes ahead and decides it thinks it knows which sword is meant by “take sword”… it want to make sure that if there are ever more than one possible match, the parser doesn’t try to decide which one on it’s own, but always asks for which is meant.

For the code you wrote, Felix, it isn’t that the game doesn’t understand the printed names of the items that bothers me. I actually don’t need the player to type in “take perfect sword” because I intend for there to possibly be much longer names for things like “a dulled, leather-hilted broadsword” or “a +2, perfect, silver-hilted, rune-engraved katana of laceration” to be things that can be generated by adding properties. The actual names of the items under the hood might be “sword1” and “sword17”, or even just “item1” and “item17”. I’m not looking to hand-place and specially name every item, and am trying to develop a framework for making items with descriptive meaning via programmatic process. I don’t expect, or even want, the player to know all of this, and obviously they wouldn’t be able to type in “take sword17”, as they’d have no idea of that.

So, what I’d like play to work like is for the player to type the generic name of a thing they want to do something with, and always be presented with a list of options of potential matches to disambiguate from. Just “take sword” for when you want to take a sword, any sword. The one exception is if the item is held by a person, then “take your sword” or “take someone’s sword” works (and that already works in my code too) to directly take a specific item because it is held.

I realize this may not be very “Inform” way of doing things, but it’s the kind of game I want to make. Despite some issues, Inform is still the best I’ve worked with trying to get a game off the ground, so I want to push for what I am trying for here to the limits…

I found Disambiguation Control by Jon Ingold to do the trick if I make changes to the suggestions rules and add new ones. Thanks Jon! The core functionality does basically what I was asking and is beyond my abilities, but the specifics make different assumptions about what are good and bad suggestions than my approach needs.

I also need Numbered Disambiguation Choices by Aaron Reed for this, but there was an incompatibility where the person asked was considered a macguffin as in “What do you want 1) Bob to take: 2) the sword …”. I fixed that to be “What do you want Bob to take: 1) the sword …” with adding the “that is not the person asked” in the code here:

Before printing the name of something (called macguffin) that is not the person asked while asking which do you mean (this is the Numbered Disambiguation Choices preface disambiguation objects with numbers rule):

Now, all appears to be working as I hoped for each of the suggestions I alter to my needs. I’ll keep poking at it, but it seems like things are on track.