"Understand '[thing]' as [a kind of thing]" missing spots

I’ve been working with a lot of privately-named things thus far (even though I’m only in my first room, ehe), and I noticed that every once in a while the parser won’t attach one of the “Understand ‘[thing]’ as [a kind of thing]” statements I’ve written to something in the game.

As an example:

1. I’ve defined a mirror as a kind of thing.
2. I’ve told inform to understand “mirror” as a mirror.
3. I have a privately-named mirror in the first room. I defined some adjectives for it and the parser understood “mirror” as it just fine.
4. I add another mirror, not privately-named, called the handmirror (one word) for testing. It doesn’t have to even be in the room, I’ve tried it both in the first room and a system’s room and it’s done what comes next.
5. Suddenly the game… stops understanding the first, privately-named mirror as a mirror because this other mirror exists, seemingly.
6. (In fact, if I write “frameless” it understands that, as that’s one of the adjectives, but using the trace command it definitely seems like “mirror” is now entirely NOT understood as this thing which is clearly still a mirror and comes up as a mirror in showme. It says “I only understood you as far as wanting to examine [the first mirror aka the frameless mirror]” and gives up because the addition of “mirror” to frameless is somehow an abberation now.)
7. If I manually add “understand ‘mirror’ as [the first mirror]” it understands both things (said frameless mirror and the handmirror) as mirrors just fine.

At first I thought it was because the mirror is privately-named, but I have several other privately-named things that inherit the understand statements of their kind just fine. And then I assumed it was because two mirrors existed, but I made chairs a kind of supporter and have two for testing… and chair is parsing expected!

Is this common behaviour? Some erratic, unfortunately bug? Does anyone know what would cause this?

My guess is that the compiler is interpreting the statement Understand "mirror" as a mirror. to be referring to a particular thing with mirror in its name instead of the mirror kind. (EDIT: My guess was wrong – see zarf’s explanation below.)

I see similar behavior in 10.1 with:

A mirror is a kind of thing. Understand "mirror" as a mirror.

A privately-named mirror called a handmirror is here.

A privately-named mirror called a frameless mirror is here.

In this case, >X MIRROR always picks the handmirror. If the declaration of mirrors is reversed, then >X MIRROR is interpreted to mean the frameless mirror, so it seems like it is the first-declared mirror that is given the name.

I was going to suggest:

  1. Consider the Use unabbreviated object names. use option.
  2. Consider using section boundaries in your code, as the compiler will preferentially match words within a particular section.

but neither of these has any effect, as far as I can tell.

It does look like a bug to me, especially in that the handmirror does not have the word mirror in its name.

1 Like

No, that’s not what’s going on.

Both objects do get the synonym “mirror”, as you can see:

>get mirror
Taken.

>i
You are carrying:
  a handmirror

>get mirror
Taken.

>i
You are carrying:
  two mirrors

The situation – with Otis’ example! – is that the two mirrors are considered indistinguishable. (They only have “mirror” in their synonym list.) Therefore GET MIRROR picks one at random (or really the first available one) without a disambig question.

2 Likes

fairly empty room
You can see two mirrors and a box (empty) here.

x mirror
You see nothing special about the handmirror.

put mirror in box
(first taking the handmirror)
You put the handmirror into the box.

close box
You close the box.

x mirror
You see nothing special about the frameless mirror.

Threw that snippet you posted into my secondary testing environment (a different file, scrubbed clean, but added a box for testing this), and while it definitely goes after the handmirror first it at least seems to understand the frameless mirror as a mirror for me after the handmirror is put into the box and removed from scope by closing it.

(I also tested by adding “understand ‘frameless’ as the frameless mirror” and funnily enough it decided to start asking “do you mean” THEN.)

…This being in contrast to how, even if the handmirror is out of sight, even if the handmirror isn’t even ENCLOSED BY THE LOCATION, its mere existence seems to strip inform of its established language of the frameless mirror, as a mirror, being understood with “mirror”. So I’m still horribly confused.

(Oh, and for reference: In my original code the frameless mirror is defined first, followed by the handmirror afterwards).

It does look like a bug to me, especially in that the handmirror does not have the word mirror in its name.

The fact that the handmirror technically doesn’t even have anything recognizable as a mirror token in the name certainly doesn’t help me figure out why this is, yeah.

As to the original question, I’d want to see specific example code before trying to analyze it. As you can tell, details matter.

I’m not sure what I can really pick out of this code to show it any better than the explanation does, unfortunately, since this whole thing is baffling enough that I hardly know where to begin.

A mirror is a kind of thing. Understand "mirror" as a mirror. A mirror can be proper.

CHARNAME'S frameless mirror is an unclean privately-named improper-named n-nailed down [<- this is a property don't mind this] scenery proper mirror [<- proper is a property of mirrors, not a kind of mirror] in CHARNAME'S Bedroom. 

The printed name of CHARNAME'S frameless mirror is "[if CHARNAME'S frameless mirror is unclean]smudged [else if CHARNAME'S mirror is overwhelmingly unclean]stained [otherwise]frameless [end if]mirror". 

Understand "sizeable/frameless" as CHARNAME'S frameless mirror. Understand "sizeable and frameless mirror" as CHARNAME'S frameless mirror. Understand "smudged" as CHARNAME'S frameless mirror when CHARNAME'S frameless mirror is unclean. Understand "stained" as CHARNAME'S frameless mirror when CHARNAME'S frameless mirror is overwhelmingly unclean.

The handmirror is a mirror in CHARNAME'S antique armoire [<- a container in this room].

I removed the bit that lets the game understand it as a mirror again for the purposes of this. Usually it goes “sizeable/frameless/mirror” now.

As mentioned, I tried moving the mirror to an entirely different room. Still removed the “mirror” understand language from the frameless mirror. And the frameless mirror IS understood as a mirror when the handmirror doesn’t exit.

Edit: Worth noting: These are basically the only times other than, say, examine text that mirrors come up in the code at all. I can’t find anything that would cause a weird conflict here.

So, for reference…

Without “sizeable/frameless/mirror” but instead “sizeable/frameless”:

1. While the handmirror is in the armoire, which is in the room:

2. While the handmirror is in a completely different room, which the player has also never been to:
image

Edit for extra information: When the “sizeable/frameless/mirror” variation is put back it still understands the handmirror as a mirror just fine, even if it prefers the frameless mirror for examining in the absence of any other descriptors:

image

Oh, right! The You can see two mirrors here. is a clue.

So, under-the-hood details for my own example (for those who are curious):

  1. The compiler does correctly associate the word “mirror” with the mirror kind.
  2. Declaring the mirror objects as privately-named strips all name information from their own I6 object declarations. As a result, they have neither name nor parse_name properties. However, both of them inherit the parse_name property from the mirror kind’s I6 class.
  3. The I6 routine Identical(), which is used to determine whether two objects are the same for gameplay purposes, will consult with the commonly-assigned parse_name routine, which tells the parser to try comparing the contents of their name properties instead.
  4. Since the two mirror objects don’t have name properties, they are determined to be identical.

From the parser’s standpoint, the result is similar to what you get from:

A coin is a kind of thing.

There are ten coins here.

in that when the player types >GET COIN, any coin is considered to be good enough, and it won’t ask which of the ten you mean.

1 Like

To make this clearer – the objects stop being indistinguishable as soon as you add some synonyms:

Understand "frameless" as the frameless mirror.
Understand "hand", "handmirror" as the handmirror.
2 Likes

From what I can see of your example code’s I6 output:

  1. A parse_name for the I6 class corresponding to the mirror kind is created, but it does not recognize the word “mirror” – all it does is check the name property.

  2. Because the frameless mirror is privately-named, it does not get a name property.

  3. The various Understand... lines for the frameless mirror are driving creation of an object-specific parse_name for the frameless mirror. The frameless mirror’s specific parse_name does not handle the word 'mirror' except as part of the phrase “sizeable and frameless mirror”.

  4. Because the handmirror is not privately-named, it does get a name property, which includes the word 'mirror'.

Here’s the specific code I was using, which simplifies yours a bit:

Mirrors
Bedroom is a room.

A mirror is a kind of thing. Understand "mirror" as a mirror.

A mirror can be overwhelmingly unclean, unclean or clean.

A frameless mirror is an unclean privately-named mirror in Bedroom. 

The printed name of frameless mirror is "[if frameless mirror is unclean]smudged [else if frameless mirror is overwhelmingly unclean]stained [otherwise]frameless [end if]mirror". 

Understand "sizeable/frameless" as frameless mirror. Understand "sizeable and frameless mirror" as frameless mirror. Understand "smudged" as frameless mirror when frameless mirror is unclean. Understand "stained" as frameless mirror when frameless mirror is overwhelmingly unclean.

An antique armoire is a closed openable container in Bedroom.

The handmirror is a mirror in antique armoire.

It looks like the I7 compiler first decides that, because it will need to recognize all mirrors via the dictionary word 'mirror', it will handle this by applying the word to the name property of each instance. Then it decides second that, if an instance is privately-named, it will drop the name property from that instance. This leaves any privately-named instance unable to respond to the dictionary word assigned to the kind. (This is clearly not the whole story, but that’s what it looks like it’s doing to me.)

I would say that this behavior implies that the privately-named property at the instance level is intentionally being given priority, but if one adds something like:

Understand "shiny surface" as a mirror.

then >X SHINY SURFACE will apply to every mirror including the frameless mirror. Is there a defined precedence somewhere for this type of conflict?

Note that, in the absence of the handmirror, then the parse_name routine for the mirror kind is generated in such a way that it does recognize the word mirror. The privately-named frameless mirror still gets its own private version of the parse_name routine, but that is also built to recognize the standalone dictionary word 'mirror'.

It seems like maybe this issue occurs only when

  • an Understand... statement for a kind specifies single words, and
  • some instances of that kind are privately-named while others are publicly-named.

(As an aside, if you haven’t reached that point in the documentation, I think you might appreciate the contents of WWI 17.15 Understanding things by their properties.)

1 Like

Ah!!! Thank you for your looking into it (as well as your patience)! This certainly helps. Shame that there’s a bit of a conflict here. I’m hoping it shouldn’t be quite as much of an issue once I’m outside of this room, but it’ll definitely be something to keep in mind.

If it does only happen under those circumstances, that definitely explains why it’s been so finicky. I wouldn’t call that an uncommon scenario, but it’s definitely one that’s specific enough that it’s been tripping me up in the process of trying to find the cause.

Also, I definitely have hit that section! The reason I’m specifying “stained” as only situationally applying to the mirror instead of making it a property-understanding-thing is that those things (AKA being smudged or stained) are based on the mirror in various states, quite specifically.

Understand “shattered” or “cracked” or “smashed” as broken. Understand “pristine” as unbroken.

In hindsight I suppose I can definitely consider the potential to apply adjectives to the property here, but since just about anything can be unclean I’ve been at least hesitant to go the shotgun approach so far. Partially since that would mean having “smudged” apply to, say, an unmade bed.

I appreciate you bringing it up, though! And actually, I’ve read through the entire documentation twice in the past few months (not including all of the times I’ve looked things up again in the process of making this). I think I’ve been doing fairly alright so far with figuring things out for myself when something very specific like this isn’t happening in the gears spinning throughout the background. When I say I’m on my first room, that probably sounds like deceptively little progress… but I’ve actually been working on getting some mechanics I need sooner than later in working order for most of the time, ehe.

(…That, and describing terrible chairs.)

I spent a little more time looking at this. I think the general rules are:

A single word associated to a kind becomes…

  • a dictionary word in the name property of any publicly-named instances of the kind if at least one publicly-named instance exists, or
  • word-matching logic in the parse_name routine of the kind if and only if all instances of the kind are privately-named.

A topic associated to a kind becomes…

  • word-matching logic in the parse_name routine of the kind, and
  • duplicate word-matching logic in the parse_name routine of any instance with additional topics associated to it (some of which may be derived from single words if all instances are privately-named).

Sample code:

A mirror is a kind of thing. Understand "mirror", "mir ror" as a mirror.

[Uncomment privately-named as needed for test scenario.]
A [privately-named] mirror called a handmirror is here.
A [privately-named] mirror called a frameless mirror is here.

[Uncomment as desired to observe in combination with the changes above.]
[Understand "hand mirror" as the handmirror.]
[Understand "frame-less" as the frameless mirror.]

Test me with "get mirror / get mirror / drop all / get mir ror / get mir ror".

Behavior is the same under both 6M62 and 10.1:

NAMING			WORD 'mirror'			PHRASE 'mir ror'		RECOGNITION METHOD
--------------	--------------------	-------------------		------------------------------------------------------------------

both public		recognized by both		recognized by both		'mirror' in name properties of both

both private	recognized by both		recognized by both  	'mirror' parse_name for kind only (objects are indistinguishable)

one each		publicly-named only		recognized by both		'mirror' (single word) in name property of publicly-named object only
																"mir ror" (topic) in parse_name for kind

I do think there is some kind of fault here. If I’m understanding correctly, the compiler looks for chances to transform single words associated to a kind into dictionary words within name properties of the instances for that kind. I assume that there are good run-time optimization reasons for this. It seems as though the exception is when all instances of the kind are privately-named, in which case the compiler seems to understand that name properties can’t be used and generates word-matching logic for the kind’s parse_name routine.

However, in the special case where both privately-named and publicly-named instances of the kind coexist, the privately-named versions no longer receive the benefit of the kind’s Understand... lines – but only when the phrase to be understood is written as a single word. This isn’t very intuitive or predictable. I can see arguments for either the Understand... line for the kind or the privately-named property of the instance prevailing in cases of a clash, but the logic should be consistent regardless of whether a single word or a topic is being considered.

1 Like

I would say without reservation that this is a bug, though my opinions on this sort of thing have frequently clashed with the developers’. I can’t think of any reason why an author would want this behavior—or even how to document it in a way that makes sense to people not familiar with I6. Inform goes out of its way to hide the details of parse_name from authors (indeed, that was one of its original goals, according to Emily Short) so requiring authors to understand it to make “privately-named” work does not seem reasonable.

3 Likes

…Now I’m curious which of these two to long-term list as the solution for anyone else struggling with these problems in the future. Thank you for being so thorough!!!

Side note but I threw together an example for what was extra confusing me in addition to this, because for some reason THIS, with a privately-named chair AND a publicly-named chair, works…

The Bedroom is a room.

A chair is a kind of supporter. Understand "chair/seat" as a chair. A chair is usually enterable.

CHARNAME'S chair is an improper-named privately-named chair in the bedroom. The printed name of CHARNAME'S chair is "office chair". Understand "office" as CHARNAME'S chair.

The testing seat is an chair in the bedroom.

Test me with "sit on chair / 1 / sit on testing chair".

(Ignore how boring these chairs are. I scrubbed even more stuff from them that was unrelated to the example this time around. Thanks to otisdog’s efforts the immediate cause has come to light, so I can replicate it more coherently.)

…And guess what, guess what? I just tested it because I had a horrible realization and it stops working for CHARNAME’S chair if you remove the “/seat” part.

The Bedroom is a room.

A chair is a kind of supporter. Understand "chair" as a chair. A chair is usually enterable.

CHARNAME'S chair is an improper-named privately-named chair in the bedroom. The printed name of CHARNAME'S chair is "office chair". Understand "office" as CHARNAME'S chair.

The testing seat is an chair in the bedroom.

Test me with "sit on chair / 1 / sit on testing chair".

So for clarity:

Understand “chair” or “seat” as a chair. ← Doesn’t work.
Understand “chair” as a chair. Understand “seat” as a chair. ← Doesn’t work.
Understand “chair/seat” as a chair. ← WORKS.
…And finally (for the sake of being thorough myself), understand “chair/seat” and “lounge” as a chair. ← Works for chair and seat, but NOT for lounge.

Well that’s another mystery solved.

It seems like having two things in the same understand statement, but SPECIFICALLY only when they’re in the same quotation marks, separated by a slash, allows it to be recognized even while only some things in the Kind are privately-named. I suppose due to some quiet overlap with the “word” Vs. “topic” thing you were discussing in how it handles this alternate language (in the sense that the documentation calls it shorthand for it, at least) for framing several Understand statements at once.

I should have expected it being transformed into a topic the second more than one word entered the mix at all, ehe. But hey! Maybe I can make my life a little easier by making use of this workaround. I certainly wouldn’t argue against there being some kind of bug here, since that’s even more inexplicable and less predictable than it was with “mir ror” working, if you don’t expect it.

Otis has put his finger on it.

Understand "<single-word>" as... always places <single-word> in the name property (rather than using a parse_name routine), which can be subsequently overriden by an object being declared as privately named (and therefore with no name property).

Conversely, Understand "<word1> <word2>" as ... will always use a parse_name routine because for such a definition, in order for the parser to make a match, both <word1> and <word2> must be typed in a command, and in exact sequence. Whereas when names are placed in a name property, any one or all of the names, in any sequence, and regardless of repeats, can be matched by the parser.

EDIT: Understand "<word1>/<word2>" as ... also always uses parse_name (although in theory the compiler could just stuff each of the words in the name property) although Understand "<word1>" or "<word2>" as... will use the name property.

2 Likes

Yeah, the second I started thinking about it I realized that even if I mentally didn’t consider “chair/seat” to be using “parse_name” as opposed to “name”, they probably were given what would otherwise be an inconsistency (and how the engine would have to read such a thing, regardless of how the documentation would describe it conceptually).

Once again, happy to have figured this out. Not knowing why or when it was happening was bothering me quite a bit, so thanks everyone! And hey: for the sake of not having to manually list every privately-named mirror that may arise as being understood as a mirror, at least now I know an exception (finding two single words to list at once) that can make my life a little easier. Problem extra solved.

Yes. The difference is pretty much the difference between text and topic. You’re seeing the distinction between them correctly. (And don’t worry – this is a common point of confusion.)

When I said “understood as a single word” above, I probably should have said “written as a single word” to minimize that confusion, though. (I’ll update it.)

1 Like

You can just (somewhat inelegantly) write Understand "mirror/mirror" as a mirror to force the use of parse_name in all mirrors, whether privately named or not.

2 Likes

Yes, essentially the compiler is omitting to create the necessary parse_name routine for a privately-named object inheriting a single-word name from a Understand "<single-word>" as a <kind> phrase- but only when one or more publicly named objects of the kind also exist.

EDIT: I’ve reported it.

2 Likes