Disambiguation with "any thing" (mild Improv: Origins spoilers)

Those who’ve played my ParserComp entry Improv: Origins will have noticed that it makes heavy use of the verb FIND, which is a superpower possessed by one the the NPCs in the game. Since by its nature you want FIND to find things that are out of scope, this required use of “any thing” instead of “something” in the action definition:

Finding is an action applying to one visible thing. Understand “find [any thing]” as finding.

Works great! Until it has to disambiguate, and here my troubles began:

>clapper, find phone
Which do you mean, the phone, the holographic phone, or the phone

I have tried digging through both the built-in Inform 7 docs and Jim Aikin’s excellent Inform 7 Handbook, I have tried beating on the bug with kludges (Does the player mean doing something with the cellphone when the cellphone is not enclosed by the location of the player: it is unlikely.), I have looked at Jon Ingold’s Disambiguation Control extension (cool, but doesn’t look to solve this particular problem), I have tried burning sage. Nothing has worked so far.

Is there a written explainer somewhere of exactly how Inform 7 disambiguation works, step by step? Or, failing that, does anybody have a bigger kludge that I can hit this with? Clapper has more games to appear in, and she is getting very impatient with my limited coding skills.

The whole thread is interesting, but this post in particular explains the mechanic

1 Like

Yep, here’s how it works, incorporating some things I learned later in that thread.

An object gets:

  • 1000, 2000, 3000, or 4000 points for the outcome of the “does the player mean” rules (or more generally the ChooseObjects routine)
  • 500 points for being “good”, which is never actually used anywhere
  • 100 points for not having the I6 concealed flag, which is only ever used for the player character by default, but can be set by making a thing “undescribed”
  • 60 points for being in the best location (usually held)
  • 40 points for being in the next-best location (usually the player’s location)
  • 20 points for not being a direction
  • 10 points for not being scenery
  • 5 points for not being the actor
  • 1 point for matching the gender, number, and animacy restrictions of a word in the input (this matters for e.g. German where the gender of the article should be taken into account)

I actually read that “Game not disambiguating” thread! It did not help me, but I’m willing to give it another look.

I guess my question is twofold:

  1. Is there a way to give disambiguation precedence to items that are contained within the location of the player but are not located there? (An item within a closed container, say.) I did try this (all the phones are of the kind “phone-thing”):
    Does the player mean doing something to a phone-thing when the noun is enclosed by the location: it is likely.
    To no avail.

  2. Is there a way to circumvent disambiguation entirely if none of the objects are enclosed by the location, and give a response like “You can’t find anything like that here?” Or does the parser insist on disambiguating first even if it’s “Which do you mean, Amelia Earhart or Jimmy Hoffa?”

Here are a couple other ideas that might be helpful – these are less about messing with the disambiguation algorithm and more about brute-force managing what’s even an option in the first place, which might be simpler? At least this stuff might help you whittle down the problem to something that’s more manageable with the more finely-tailored tools.

First, instead of making the action apply to [any thing] – which as you’ve found out can be terrifyingly broad – you could define a new either/or property, like findable/unfindable, and understand “find [any findable thing] as finding.” Then if you’ve got various placeholders or sub-components that the player should never be trying to mess with, you can just tab them as unfindable. Alternately, you could manage this dynamically through the game – like, maybe an item only becomes findable once someone mentions it in conversation, or it gets dropped in Mount Doom and goes poof. You can just append a “now the foo is un/findable” to the appropriate rule.

Second, it might work to be more specific with the object names that you’re using, or even make them privately-named, so that you have full control over what grammar will resolve to the object. So for example if you have a phone panel on the back of a pay phone, you could name it phone_panel in your code and have an understand statement like “understand ‘pay/-- phone/-- panel’ as the phone_panel” to make it easy for the player to interact with it but without triggering disambiguation hell.

Here’s a tiny example of both of these in action to play around with, in case that’s helpful.

Warehouse is a room.  Annex is east of warehouse.

A thing is either findable or unfindable.  A thing is usually findable.

The pay phone is in the warehouse.  The flip phone is in the annex.  The holographic phone is in the warehouse.  It is unfindable.

The phone_panel is part of the pay phone.  Understand "pay/-- phone/-- panel" as the phone_panel.  The printed name of the phone_panel is "phone panel".

Understand "find [any findable thing]" as finding.  Finding is an action applying to one visible thing.

Carry out finding:
	Say "The [noun] is in the [location of the noun]."
After examining the holographic phone:
	Now the holographic phone is findable.


Daniel (Mike, too) is a much better source for this subject, but you can mess with scope:

room1 is a room.
After deciding the scope of the player when the location is room1: place the contents of the box in scope.

a box is in room1.
the box is a closed openable container.
a right frob is in room1.
a wrong frob is in room1.
a boxed frob is inside the box.

does the player mean doing something to the boxed frob: it is very likely.

Before taking the boxed frob:
	try opening the box.


You can see a box (closed), a right frob and a wrong frob here.

>take frob
(the boxed frob)
You open the box, revealing a boxed frob.


Might need to take preventative measures to stop unwanted actions.

1 Like

So is your goal to only have “find” apply to objects within the current location?

Definition: a thing (called the item) is local if the location of the item is the location of the player.
Understand "find [any local thing]" as finding.

If you want to be especially slick:

Understand "find [text]" as mistaken-finding.
Check mistaken-finding: say "You have no idea where a '[topic understood]' might be." instead.

This captures any attempt to find something that’s not in the location—or even something that doesn’t exist in the game world (“find keys” which are in another room and “find kjshfkjshfdkjsdf” will get the same response).

1 Like

I think the problem, or at least a part of the problem that needs to be considered, is that in your desired scenario, it is an NPC that is supposed to be doing the finding, not the player. A rule like “Does the player mean doing something … when …” will not apply to that scenario, as far as I see.

The rule should rather be something along the lines of:

Does the player mean asking a person to try finding something which is enclosed by the location: it is likely.

The following code:

Finding is an action applying to one visible thing. Understand "find [any thing]" as finding.

Carry out an actor finding:
	say "[The noun] is in [the holder of the noun]."

Persuasion rule for asking a person to try finding something:
	persuasion succeeds.
Does the player mean asking a person to try finding something which is enclosed by the location: it is likely.

The Lab is a room.

Robby is a person in the lab.

The box is a closed container in the Lab.
The red gadget is in the box.

The Corridor is south of the Lab.
The blue gadget is in the Corridor.

… produces this output:

You can see Robby and a box (closed) here.

>robby, find gadget
(the red gadget)
The red gadget is in the box.

>robby, find blue
The blue gadget is in the Corridor.
1 Like

Oh, that’s not a bad idea — will try it, thanks! What I ideally would want would be some sort of default inheritance property that can be overridden (if the foo is nowhere, it is unfindable), but that may either not be possible or be more trouble than it’s worth.

1 Like

Daniel and St. John snuck in while I was typing — those are both excellent ideas as well. Let me try applying all of these and report back.

1 Like

Combining Mike, Daniel, and St. John’s advice above seems to have done the trick. Here’s what I ended up with:

Definition: a thing (called the item) is local if the location of the item is the location of the player.

Finding is an action applying to one thing. Understand "find [any local thing]" as finding. Understand "clap for [any local thing]" as finding. Understand "help me find [any local thing]" as finding.

Mistaken-finding is an action applying to one topic.

Understand "find [text]" or "clap for [text]" as mistaken-finding.

Instead of asking Clapper to try mistaken-finding: 
	say "She claps her hands together twice. Nothing happens.[paragraph break]'Must be out of earshot,' [Clapper] says." instead.

Thanks, all! I will now go celebrate not having to understand how Inform disambiguation works.