Advanced verbRules, and Scope

New here, hello all.

I’ve been delving into T3 now for a few days, and still have a couple questions I haven’t been able to crack. The first involves verbRules, and isn’t so much a problem but more of a curiousity.

I created my own Tie to rules to give it the same general behavior as Attach To, but only for specific objects. Copying from the source, I came up with this:

VerbRule(TieTo)
    'tie' singleDobj 'to' singleIobj
    : TieToAction
    askIobjResponseProd = toSingleNoun
    verbPhrase = 'tie/tying (what) (to what)'
;

VerbRule(TieToWhat)
    [badness 500] 'tie' dobjList
    : TieToAction
    verbPhrase = 'tie/tying (what) (to what)'
    construct()
    {
        /* set up the empty indirect object phrase */
        iobjMatch = new EmptyNounPhraseProd();
        iobjMatch.responseProd = toSingleNoun;
    }
;

Seems to work fine, but I am curious what the following lines mean, or if they are important:

askIobjResponseProd = toSingleNoun...
[badness 500]...
iobjMatch...

Even reading through the ref, I still don’t get it, and I’m wondering I missed some documentation for this somewhere, or if the source is the best place to search for an answer and I should just suck it up and delve in :slight_smile:

The second (completely unrelated) question involves what I would call scope (although that may not be the technically correct term). I’ve noticed that after examining object(s), you can refer to them subsequently as “it” or “them”. I think it would be swell to allow the player to do the same after revealing hidden objects in certain cases - but I have no idea where to look for programmatically setting objects to be referred to in this way.

Thanks!

This defines your basic rule to support “>tie X to Y”. It will also allow the “>tie X to” syntax, and the askIobjResponseProd statement means that in this case, if the player omits the indirect object and the parser asks him to pick one, you want to treat the response as a noun, rather than a topic or a literal or whatever.

(toSingleNoun is the default value for askIobjResponseProd so this line can be omitted.)

However, this verb rule does not cover “>tie” or “>tie X”. The player will be told that the story doesn’t understand that command, which isn’t what we want at all. We just want him to be more specific. For that we need…

Here you’ve noticed the [badness 500] before the syntax. What this means is that we never want to use this rule in place of the “real” TieTo rule, even though “>tie X to Y” could theoretically be parsed as “>tie X [with some stuff the parser ignores]” and match this rule instead.

This is what covers the “>tie” input: if the player enters that, he’ll be asked what he wants to tie. If the player types “X”, or if he enters something like “>tie X”, he’s satisfied the parameters of this rule. All it wants is a verb and a direct object. So the rule is ready to create the action.

But wait! TieToAction requires both a direct and an indirect object. If we jump straight to it, TieToAction will try to access properties of an indirect object that doesn’t exist, and we’ll get a nil reference error.

That’s where the construct() function comes in. It’s saying, when you first set up this VerbRule, give it a placeholder for the indirect object. That placeholder is EmptyNounPhraseProd, because this particular rule can’t ever match input that includes an indirect object - otherwise it would have matched our first rule. EmptyNounPhraseProd is a cue to the parser to go back to the player and ask him to pick something.

The next line tells it to treat whatever the player types as a single noun. This covers the same ground as askIobjResponseProd = toSingleNoun did in our first rule, except it was optional there and it’s required here. By default, EmptyNounPhraseProd.responseProd is nil, so if we don’t supply a value we’ll get another nil reference error.

Thanks, that was an amazingly helpful post! Also, digging through the source has been somewhat revealing on my second question - I think I’ve narrowed it down to having to do with setPronoun(), but I still need to figure out to make it work. I’ll keep hunting, the source is actually very well documented and easy to follow (although pretty daunting at first!).

Thanks again

You’re on the right track. setPronoun takes a list of ResolveInfo objects, which are wrappers that the parser uses for in-game objects. If you drill into the code you see that it eventually calls setPronounObj with the actual object; we can skip straight there since we’re doing this outside the parsing sequence.

+ desk: Surface, Heavy 'desk' 'desk'
	"Just another desk. "

	dobjFor(Search) {
		action() {
			"You find a top secret report! ";
			report.discover;
			gActor.setPronounObj(report);
		}
	}
;

++ report: Hidden 'top secret report' 'report'
	"Just another report. "
;

Alternatively, if you want this behavior for all hidden objects that get discovered:

modify Hidden
	discover() {
		inherited;
		gPlayerChar.setPronounObj(self);
	}
;

Perfect, somehow I had missed setPronounObj. Thank you for such quick and detailed answers!