Help with parser/resolving?

I have a situation that is admittedly not of extreme importance, but I feel it would add a little touch of refinement if I could get it to work. Plus, I am inclined to be academically interested in how this works even if the application is not urgent…

If any TADS veterans out there have wisdom to lend, here’s what I’m looking to do:

I don’t like the “spoiler effect” produced by the adv3 library, which will give a different error message based on whether the player types a word that is completely unknown to the game dictionary, or that is simply out of scope.
Currently, I have overridden askUnknownWord, noMatchCannotSee, and noMatchNotAware (all of the playerMessages object) to all give identical reports, hinting that either the reference isn’t in scope, or may not be part of the game at all.
I’m okay with this for objects that are in fact part of the game, but as yet unknown to the player. However, it gets a bit annoying to me to drop a well-known object, walk to a neighboring room, try to reference the object, and be told “that might not be a part of this game at all”.

What I envision (but don’t know where to intervene, being still mystified by grammarProds, Resolvers, and parsing in general) is to override some method in the parsing process to check the object with global scope sort of like a TopicResolver, and at least make a note of any matching simulation objects where gPlayerChar.knowsAbout(obj). Then, if the object ends up being out of scope for the actual action involved, noMatchCannotSee could at least display a message saying that the object isn’t in your location (instead of “may not be part of the game”).
I realize that with global scope disambiguation becomes a big issue, so it would either need to include the parenthesized announcement of its chosen object, or if necessary it could even list off all of the known objects to the PC, sort of like: “If you’re referring to the wooden spoon, the wooden horse, or the wooden mallet, none of those things are to be seen here.”
But of course it would disregard any simulation objects with matching vocabulary that are not known to the PC.

Sorry for the long wind! Anybody have suggestions?

(I thought about trying to do something elaborate with Unthings, at least for all portable objects, but I’ll probably only fiddle with that as a last resource…)

I think I may have come up with something. It seems to work, but not completely convinced it’s bug- free. I feel like it’s a hacky place to do this, so if anyone can suggest a better way, that’d be great. Or if you’re just looking to accomplish something similar, here it is:

tempObjs: object
	lst_ = nil
	;

modify NounPhraseWithVocab
	getWordMatches(tok, partOfSpeech, resolver, flags, truncFlags)
    		{ local lst;
        	lst = cmdDict.findWord(tok, partOfSpeech);
        	lst = filterDictMatches(lst);
		    tempObjs.lst_ = lst.subset(function(x) { 
               if(lst.indexOf(x)%2 != 0)	
			{ if(gpc.knowsAbout(x)) return true; } return nil; }).get.Unique());		        
        	lst = inScopeMatches(lst, flags, flags | truncFlags, resolver);
        	return lst; } ;

modify Action	afterActionMain() { inherited; tempObjs.lst_ = nil; }	;

modify playerMessages
    noMatchCannotSee(actor, txt) { if(sayNotHere()) ;
	   else "my generic msg "; }
    noMatchNotAware(actor, txt) { if(sayNotHere()) ;
	   else "my generic msg "; }
	;

sayNotHere() { local t = tempObjs.lst_; if(t && t.length()!=0) { if(t.length==1)
	{ "\ \^<<t[1].theName>> <<t[1].isPlural ? 'are' : 'is'>> not in view here. "; }
   else {
	"\ Whether you are referring to <<snhLister.showSimpleList(t)>>,
           <<t.length==2 ? 'neither of them is' : 'none of them are'>> to be seen here. "; } 
       return true; } return nil; }

snhLister: objectLister
	showListItem(obj, options, pov, infoTab) { "the <<obj.disambigName>>"; }
	listSepTwo = " or "
	listSepEnd = ", or "	;