The problem is that the only available information is where the unrecognized text starts. This is pretty deeply buried (requires some I6 hacking to get access to it).
But even beyond that, it’s potentially messy to make use of. If the player has typed “TAKE DSFG”, the parser has gotten up to word 2, so an error like “You can’t see any dsfg here” is sensible. But what if the player typed “DROP GOLD COIM IN WELL”? Should the error be “You can’t see any gold here”? (The first word.) Or “You can’t see any gold coim in well here”? (All the words, but now the parser is making itself look stupider than it is.)
The parser could also have tried several grammar lines. “PUT ON HAY ON WYE” could be parsed a couple of different ways. The parser is good at finding the correct one if there is a matching object. (I don’t know why you’d wear a Welsh city known for bookstores, but the parser is down for it!) But if there isn’t a matching object, it’s ambiguous where the unrecognized text starts! At best you’re going to get the unrecognized-start marker of the parser’s most recent attempt.
Thanks, both of you. Now that we’re talking about it, I imagine it would be hard to account for certain cases. The player might expect a plural-named thing, or a specific article. There are probably other things to account for, too.
Still, it’s fun to think about this stuff. Thanks again.
Now, for the specific case when the word isn’t in the game’s dictionary, you can do a little bit better. BadParser’s code is good for that, and some games will use this to explicitly say “I don’t know the word ‘coim’” in response to TAKE COIM or whatever.
An alternative implementation, since in my experience snippets are a lot faster than text manipulations:
To decide what snippet is the/-- unrecognized word: (- (oops_word*100+1) -).
But, this is no help if the word is in the game’s dictionary, but doesn’t refer to any object that’s currently available (TAKE COIN when the coin is in the other room). That’s where you run into the issues Zarf brings up.
or, for everything after an understood verb: To decide what snippet is command after the verb: (- (oops_from * 100) + 1 + ((players_command % 100) - oops_from) -)
…but I agree all around that an approach like this would create more problems than it solves. How about the case where the player has seen the gold coin, moved on, forgotten they hadn’t picked it up, and tried examining it? “Either the coin is elsewhere or beneath my notice.” would feel more disappointing than “You can’t see any such thing.”… What do you mean “Either?” You know the coin is elsewhere, silly game! The player character knows it’s elsewhere!
“You can’t see any such thing.” isn’t terrible and to whatever degree it’s disappointing, at least it’s familiarly disappointing and we’re generally used to not expecting more.
If you wanted to address “the player knows it’s elsewhere”, then you’d need to track what the player has seen and where it last was for reasonable messages. But then what about things for which it’s the case that the player knows a thing exists in the game world but hasn’t encountered it yet? It’s a large pile of worms.
I’ve always thought this was a pretty neat way of communicating 'You can’t refer to that thing you just mentioned, but I’m not going to tell you whether that’s because such a thing doesn’t exist or because it’s something not available to you at the moment."
that player character/narrator is an extra dimensional being that openly mocks humanity’s (and therefore the player’s) fascination with objects and property. She wouldn’t say “I can’t see any such thing,” either. That isn’t her voice.
The Epistemology extension tracks “seen” and “known” (= seen or familiar) properties for all things, so it could handle this. Then you could, in theory, split the error message into three categories: “I don’t know that word”, “you’ve never seen such a thing”, and “that thing is somewhere else”.
However, Inform’s parser isn’t currently set up to do that. I can think of some ways to make it work (if NounDomain fails, run it a second time ignoring scope; before printing the error, check to see if the words at oops_word match any known thing…) but all of them are hacky.
Yeah, there’s an extension called Remembering (iirc) which goes through and duplicates every grammar line with [any known thing] in place of [any thing], pointing them all at the “remembering” action. The problem is you have to do all that duplication manually.
Expanded Understanding by Xavid offers working remembering functionality for 9.3/6M62, but it’s kind of an omnibus extension that includes a lot of other stuff too. It has a different strategy: when there would normally be a can’t see any such thing error, it rummages through the parser’s wastebasket to see if it can find a remembered thing corresponding to what the player had entered. So it doesn’t need to be explicitly associated with existing (or future) commands.
I guess it’s done enough for me to mention it, though I’m not willing to share yet. It has vexed me that we don’t have a current working Remembering, per se, extension. I asked, and Xavid gave me the go-ahead a few days ago, to rip out the remembering parts of Expanded Understanding and package them as a standalone extension, updated for v10.
And I haven’t tried to put it through the wringer yet, but it seems to work. It has some dependencies… I wrote my own follow-up to Snippetage by Dave Robinson, and had to update Object Matching by Xavid, and I added a dependency on Optimized Epistemology by Andrew Plotkin so the player’s memory-updating stuff could hook into it. (That means it inherits the limitation that Optimized Epistemology takes on in exchange for the speed: it updates on looking, examining, and opening closed opaque containers. It doesn’t automatically “notice” new things that may appear during an action – It becomes the author’s responsibility to include a line to explicitly update player knowledge as appropriate.)
With any luck, I’ll release it soon. I want to improve the output and come up with some sort of reasonable behavior and output for things the player may eat, destroy, or see eaten or destroyed.