Custom grammar token doesn't work

i’m trying to install an in-game help system where the player can HELP WITH …

the help with $Obj may not be in scope but it should have been encountered at some point. i have a separate process running that marks everything in the room as (now) (known *) after it’s entered.

so i’ve set this up:

@(grammar transformer [[known] | $Tail] $SoFar $Verb $Action $Rev)
	(grammar transformer $Tail [90 | $SoFar] $Verb $Action $Rev)

(match grammar token 90 against $Words $ into $Obj)
    *(understand $Words as known $Obj) 

(understand $Words as known $Obj) 
    (known $Obj)

(grammar [help with [known]] for [help with $])

but $Obj in (understand words as…) isn’t bound to anything and defaults to the #player object. i’ve triple-checked using @dynamic and the “known” objects are definitely “known”, so that’s not the problem.

i can get around this problem i think by mucking around with the [any] token instead but i’m just wondering why this doesn’t work.

Right now, your (understand $ as known $) isn’t really doing anything. I think what you’d want is something like this:

(understand $Words as known $Output)
    (collect $Obj)
        (determine object $Obj)
            *(known $Obj)
        (from words)
            *(dict $Obj)
        (matching all of $Words)
    (into $List)
    *($Output is one of $List)

In other words, iterate over all (known $) objects, make a list of all the ones that match the provided words, and iterate over that list. (The list may not be necessary if you structure your multi-queries right, but (determine object $) is finnicky enough that I find this easier.)

2 Likes

that works, thx!

it’s kind of a relief that i was nowhere close…

Yeah, this used to be a whole lot more transparent (the way of defining grammar lines), but it was changed for efficiency. So now it’s about as opaque as Inform is.

The key is, (match grammar token 90 against $Words $ into $Obj) is supposed to return all appropriate $Objs that could match $Words, for this specific token. So you need to write a routine that does that: that iterates over known objects and checks which ones match $Words.

1 Like

and in my defense, this is only oh-so-lightly touched on in the manual.

1 Like

Oh yeah, the manual page on this really needs some more clarification now that the library’s become so opaque about it. It used to be so straightforward—you would write an (understand $Words as $Action) predicate that did all the parsing yourself. But eventually this got slow enough that a huge cascade of barely-documented access predicates was added to optimize the common cases, and now…