Dealing with objects that aren't in scope

I have a need to allow a command which delivers information about objects that are not necessarily touchable. So I define a verb , say discussing. Simply, ignoring error detection.

[code]Discussing is an action applying to one thing
Understand “Discuss [Any Thing]” as Discussing.

check Discussing:
Repeat through the Table of Discussions:
if noun is subject entry:
say “[data entry]”;
stop the action;
say “Nothing to discuss about [noun]”.[/code]

The table of discussions is a two column table, with columns subject and data.

It works fine if the subject is touchable, but gives “You can’t reach into .” For anything else.

What’s the best way round this? I previously implemented a similar action by parsing the command line, but that seems clumsy.

Gotta be “Discussing is an action applying to one visible thing.”

Basically, “applying to one thing” means it needs to be touched. “Applying to one visible thing” means it only needs to be visible. And “[any thing]” means “assume the player is omniscient and can see everything when doing this”.

Thanks a lot. I knew there was a way round!

just to be nitpicky: The first line should end with punctation.

There is also this:

This nonsense word should have been handled by the check rule, but it seem some build-in code stops it before that, giving that rather geeky response.

Thanks, Spoff. The discuss example was a simplified version of what I’m actually doing, and your pointers were welcome.

Since you are looking the noun up in a table, you could do:

[code]
Discussing is an action applying to one topic.
Understand “Discuss [text]” as Discussing.

check Discussing:
Repeat through the Table of Discussions:
if topic understood includes subject entry:
say “[data entry]”;
stop the action;
say “Nothing to discuss about [topic understood]”.[/code]
This will solve the issue spoff mentioned. The subject column of your Table of Discussions will have to be a topic column, but the player will be able to discuss pretty much anything you put in the table whether a corresponding object exists, is visible or not. Of course, if you also need to refer to properties of a specific object, you’d have to have another table column with the object name.

That sounds like a good idea - but how do I check if a topic and a thing matches?

[code]Chapter - people

A person has a table name called things-someone-talks-about.

Chapter - offstage

Weather is a thing.
Understand “sky”, “sun”, and “clouds” as weather.

Chapter - World

Meat Garden is a room.

The fatpicker is a thing in Meat Garden.
Ishna is a woman in Meat Garden.

The things-someone-talks-about of Ishna is the Table of things-Ishna-talks-about

Table of things-Ishna-talks-about
asked-thing reply
Weather “‘It is nice, sure.’”
fatpicker “'That’s not something I personally use. I just have it around, if someone else should happen to need it … ain’t indicating that you would…”
Ishna “You mean me?’”

Left feet is a room.
Left feet is west of Meat Garden.

Chapter - Ask action

Understand the command “ask” as something new.
Quizzing it about is an action applying to one thing and one topic.
Understand “ask [someone] about [text]” as quizzing it about.

check quizzing someone (called asked-one) about a topic (called conversation-topic):
let the active-dialog be the things-someone-talks-about of the noun;
let replyprovided be false;
Repeat through active-dialog:
If asked-thing entry KINDA SOMEHOW MATCHES conversation-topic:
say “[reply entry][paragraph break]”;
now replyprovided is true;
If replyprovided is false:
Say “Here is should see if it matches certain non-object things”;
[/code]

For my purposes, the only things to be ‘discussed’ are things in the game. It’s really a sort of detailed description lookup. So the ‘That noun did not make sense in this context’ is ok for me.
However, would the ‘if topic understood includes subject entry:’ work for the alternate (i.e. Understand ‘x’ as y) names of the subject as my current code does? It doesn’t seem so to me.

As I mentioned, the subject entry of your table of discussions would have to be changed to a topic column (§16.13. Topic columns), which can include alternates. The difference is, the subject entry would have to include all of the alternates. (Please note that a topic column must either be named “topic” or you must specify the data type.)

The pile of fish is a thing in the Boat. Understand "fish" or "herring" as the pile of fish.
The bush is a thing in the Park. Understand "bush" or "rhododendron" or "azalea" or "shrubbery" as the bush.

Table of Discussions
subject (topic)                          data (text)
"fish/herring/mackerel"                  "Smells kind of fishy to me."
"bush" or "rhododendron" or "azalea"     "A fine example, well worthy of the Knights Who Say Ni."

Note note that “DISCUSS SHRUBBERY” would fail because it’s not a topic in the table, while “DISCUSS MACKEREL” would work even though it’s not an alternate name for the pile of fish recognized by Inform.

Subject columns can be matched with “If asked-thing entry INCLUDES conversation-topic”. Inform will look to see if any of the strings in the topic column can be found in the input string.

On this approach, though, “discuss the mackerel” would fail, because “the mackerel” isn’t a topic in the table. You’d really like to be able to catch all the synonyms for the things you’re talking about, including ones that are automagically understood by the Inform parser, without having to put them all in the topic column–putting them in the topic column unnecessarily duplicates the work that the parser does. (And if you want “discuss mackerel” to work, you can just make “mackerel” a synonym for the fish–it’d be weird for “discuss mackerel” to work but “examine mackerel” to fail.)

Basically, if you only need to discuss things that are in the game, it’s probably a good idea to go with the “[any thing]” formulation and forget trying to frame everything in terms of a topic. If you don’t like the “That noun did not make sense in this context” message, you can trap “discuss splarpf” with a new action that applies to text–this will only get tried if Inform has failed to match whatever the player typed against any object.

[code]Discussing is an action applying to one visible thing.
Understand “Discuss [Any Thing]” as Discussing.

check Discussing:
Repeat through the Table of Discussions:
if noun is subject entry:
say “[data entry]”;
stop the action;
say “Nothing to discuss about [noun].”

Lab is a room.

There is a rock. There is a roll. There is a banana.

Table of Discussions
subject data
rock “Rock! Rock!”
roll “Roll! Roll!”

Non-object discussing is an action applying to one topic. Understand “discuss [text]” as non-object discussing.

Instead of non-object discussing: say “Nothing to discuss about [topic understood].”

Test me with “discuss rock/discuss roll/discuss banana/discuss spalrpf”.[/code]

(The reason you get “That noun did not make sense in this context” is that “You can’t see any such thing” doesn’t make sense when you have an [any thing] token in the understand line–you could discuss something even if you can’t see it. So you get a different error message. In the original case, this doesn’t get caught by the Check rule because the command isn’t even getting parsed as an action of discussing a thing, so the rules for discussing don’t run.)

Matt, I think you’ll find that “discuss the mackerel” will work because the topic understood will be “the mackerel” which includes the word “mackerel”, a topic in the table.

As I said originally, this is an alternate way of accomplishing the task, especially if you’re using a table to look up detailed descriptions. You could just as easily make the detailed description a text property of the object, and then you wouldn’t have to bother looking it up in the table.

A thing has some text called detail. The pile of fish is a thing in the Boat. Understand "fish" or "herring" as the pile of fish. The description is "Smells kind of fishy to me." The detail is "An incredibly detailed description of the pile of fish in which not only are the different species of fish described, but the entire history of fish -- including a recipe for trout a la creme -- is given."

Oh right, I overlooked that your code said “includes.” Though this can catch too many things–I believe “discuss oafish lout” will give you the response for “fish,” since “oafish lout” contains “fish.”

OK, but I think it isn’t a good idea to hard-code synonyms as topics when they could accomplish the same thing by using the parser to determine what object is being referred to. It makes it harder to catch all the synonyms, it involves a lot of extra work to do so (when you add a synonym you have to add it in two places), and you wind up with inconsistencies in the ways that the parser handles objects. Better to just use the parser to parse names, if you can.

You do have a point that in this case you could just make the detailed description a property of the object, but there might be a couple of reasons why you’d want a table–if there’s something with no detailed description then you’d wind up having to make a special test for it, and also sometimes it might just be more convenient to use the table to keep all the detailed descriptions in one place in your code.

You can choose “the topic understood includes the topic entry” or “the topic understood matches the topic entry”. Both will try to match a word in the topic column to a word in the string. I have found no difference either way. In both cases “discuss fish” matches a table row and “discuss offish lout” does not match a table row. Just wanted to clarify that, not argue the point.

Oh yes, you’re right about “includes” working wordwise. Sorry about that. Snippet matching (as opposed to indexed text matching) always confuses me; I should test the code before I make assertions about it. (Having tested it, I think you will find that if you change “includes” to “matches” then “discuss the mackerel” won’t work.)

Little did I suspect when I typed my naïve topic starter that I would reveal such a wealth of cleverness. Thank you all for DISCUSSING this topic!

I found a glitch with the (modified) code I prototyped earlier:

[code]Discussing is an action applying to one visible thing
Understand “Discuss [Any Thing]” as Discussing.

check Discussing:
Repeat through the Table of Discussions:
if noun is subject entry:
say “[data entry]”;
stop the action;
say “Nothing to discuss about [noun]”.[/code]

I have two items in the game, say “metal door” and “metal hut”, neither of which are subject entries in the Table of Discussions.

[b]>discuss metal door
Which do you mean, the metal door or the metal hut?

door
Which do you mean, the metal door or the metal hut?
[/b]
Even if I put them in the table, I get the same:

If I say

Discuss door

It comes up with :
Which do you mean, the metal door or the metal hut?

However, if I do:

>Discuss hut
It’s a hut

Or

>Discuss metal hut
It’s a hut

I guess that works because there’s only one hut, but several doors. However, I’m puzzled.

Now, I can correct the problem by careful naming i.e. No duplicated adjectives, but the mechanism escapes me.

An earlier formulation from a previous game, which parsed and grepped the input line, may have been inefficient, but I didn’t get these weird effects.

Hmmm, what you’re describing shouldn’t happen just because there’s more than one door, and it shouldn’t have anything to do with what’s in the table. (When there’s a disambiguation, the game hasn’t yet got to the point of processing the command into an action, so it won’t be checking the rules or looking at hte table.) So for instance this:

[code]Discussing is an action applying to one visible thing.
Understand “Discuss [Any Thing]” as Discussing.

check Discussing:
Repeat through the Table of Discussions:
if noun is subject entry:
say “[data entry]”;
stop the action;
say “Nothing to discuss about [noun]”.

Table of Discussions
subject data
rock “Whatever.”
metal door “Door!”
metal hut “Hut!”
Iron door “Another door!”

There is a rock. There is a metal door. There is a metal hut. There is an iron door.

Lab is a room.[/code]

works as expected.

The sort of disambiguation loop you describe comes about when every word that can be used to refer to the door can also be used to refer to the hut. So, if I add this line:

Understand "door" as the hut.

then we will get the situation you describe, where no matter how many times you type “door” the game asks if it might be the hut… because “metal door” could refer to the door or the hut, the way we’ve defined it. This is particularly likely to happen when one name entirely includes another–if you have a “metal door” and a “door” then you’ll never be able to disambiguate the door.

So when you encounter a problem like this, it’s a good idea to look very carefully at your understand statements and see if you’ve accidentally defined something something that lets “door” be understood as the metal hut. (Careful naming is also a good idea.)

> matt w Genius! You even described the exact line (Understand “door” as the hut.) that caused the trouble.The Understand phrase was there because the hut has a locked door that can never be opened, and I didn’t want to go to the trouble of describing it as a part of the hut or separately. And there was a metal door elsewhere in the game. I’ll be less lazy in future.

Thank you. I am repeatedly in your debt.

Wow, thanks! That was just a guess as to the line.

If you still want to have the word “door” understood as the hut most of the time, you can restrict the Understand statement:

Understand "door" as the hut when the hut is in the location.

But now, if you try “discuss metal door” in the presence of the hut, it automatically chooses the hut (you don’t get a disambiguation loop because Inform chooses things in the location first if it can, I think). We can fix that with a Does The Player Mean rule:

Does the player mean discussing the metal hut when the player's command includes "door": it is unlikely.

And of course we have to test it, because DTPM rules rarely work the way I want them to on the first or fifth try:

[code]Discussing is an action applying to one visible thing.
Understand “Discuss [Any Thing]” as Discussing.

check Discussing:
Repeat through the Table of Discussions:
if noun is subject entry:
say “[data entry]”;
stop the action;
say “Nothing to discuss about [noun]”.

Table of Discussions
subject data
rock “Whatever.”
metal door “Door!”
metal hut “Hut!”
Iron door “Another door!”

There is a rock. There is a metal door. There is a metal hut. There is an iron door. Understand “door” as the hut when the hut is in the location.

Lab is a room. Exterior is north of Lab. The metal hut is in Exterior.

Does the player mean discussing the metal hut when the player’s command includes “door”: it is unlikely.

test me with “discuss door/metal/n/x door/discuss door/metal/discuss door/metal door/discuss door/metal hut”.[/code]

And it’s one of those rare occasions! The “(the metal door}” after command 8 isn’t quite desirable but it’s better than things not working.