adv3lite: Automatically choosing the most-fitting Thing

So, I’ve been tinkering around with adv3lite, and converted most of what I was working on before into it, and so far I have to say I am liking most of the changes. However, so far I’ve had trouble getting it chose an object automatically if a sentence is incomplete.

For example, if you’re in a restaurant and there’s a Thing called ‘dinner’, I want it so if you just type “eat” you’ll eat the dinner.

In TADS3 it was easy, just setting the logicalRank in the verify step made it automatically go with whatever’s highest, but that doesn’t seem to work in adv3lite. I also want it to be able to work with requesting an object from an incomplete statement that has a dObj but still requires an iObj; so rather than asking “Put sweater where” it puts it in the wardrobe.

My other quick, unrelated question, is is there a way to tell if a noun is plural or not when you’re given it? That way I can do custom action handling rather than having it default to effecting all objects of that type (so “Take rock” takes a rock, but “Take rocks” says you can’t take all of them, only a couple, and then proceed to give the player two of them, or something).

Thanks.

This is one area where the Mercury parser that adv3Lite uses doesn’t always work as one might expect.

The quick and dirty solution is to define an additional action to take care of this, something like:

DefineTAction(PutInWhat)
;

VerbRule(PutInWhat)
    'put' multiDobj 'in'
    : VerbProduction
    verbPhrase = 'put/putting (what)'
    missingQ = 'what do you want to put'
;

modify Thing
    dobjFor(PutInWhat)
    {
          preCond = [objHeld]
          verify() { verifyDobjPutIn(); }
          action()  { askForIobj(PutIn); }
     }
;

Note, however, that this works for PUT SWEATER IN rather than just PUT SWEATER, since the parser can have no idea whether PUT SWEATER is an incomplete PutIn, PutOn, PutBehind or PutUnder command, and thus has no means of knowing which action’s verify() method to consult to find the iObj with the highest logical rank.

You could try testing for the value of gCommand.matchedMulti which should be true if and only if the player’s command matched multiple objects.

Sorry for the long gap before my reply. Using dummy actions to get whatever’s logical has been working pretty well, but I’ve hit a weird snag.

I’ve gotten it to work when it has something with a logical rank to choose from, but when everything’s equal I get a NounRoleQuestion crash.

For example, in the following code:

[code]startroom: Room ‘The Starting Location’
"Add your description here. "
;

  • me: Thing ‘you’
    isFixed = true
    person = 2 // change to 1 for a first-person game
    contType = Carrier
    ;

  • box: Container ‘box’
    ;

  • candyBar: Food ‘candy bar’
    ;

modify Thing
dobjFor(FuseWhat)
{
preCond = [objHeld]
action() { askForIobj(FuseObjs); }
}

dobjFor(AddWhere)
{
    preCond = [objHeld]
    //verify() { verifyDobjAddTo(); }
    action() { askForIobj(AddTo); }
}

dobjFor(FuseObjs)
{
    preCond = [objHeld]
}

iobjFor(FuseObjs)
{
    preCond = [objHeld]
    verify() { illogical('It just is, okay? '); }
    action() { "You fuse {the dobj} with {the iobj}. "; }
}

dobjFor(AddTo)
{ 
    preCond = [objHeld] 
}

iobjFor(AddTo)
{
    preCond = [touchObj]
    verify() { illogical('{I} can\'t add to {that subj dobj}. '); }
    action() { "Textttt. "; }
}

;

DefineTAction(FuseWhat)
;

VerbRule(FuseWhat)
[badness 500] ‘fuse’ multiDobj
: VerbProduction
action = FuseWhat
verbPrhase = ‘fuse/fusing (what)’
missingQ = ‘what do you want to fuse’
;

DefineTAction(AddWhere);

VerbRule(AddWhere)
[badness 500] ‘add’ multiDobj
: VerbProduction
action = AddWhere
verbPhrase = ‘add/adding (what)’
missingQ = ‘what do you want to add’
;

DefineTIAction(FuseObjs)
;

VerbRule(FuseObjs)
‘fuse’ multiDobj ‘with’ singleIobj
: VerbProduction
action = FuseObjs
verbPhrase = ‘fuse/fusing (what) (with what)’
missingQ = ‘what do you want to fuse; what do you want to fuse {the dobj} with’
iobjReply = withSingleNoun
;

DefineTIAction(AddTo);

VerbRule(AddTo)
‘add’ multiDobj (‘into’ | ‘in’ | ‘to’ | ‘in’ ‘to’) singleIobj
: VerbProduction
action = AddTo
verbPhrase = ‘add/adding (what) (to what)’
missinqQ = ‘what do you want to add; what do you want to add {him dobj} to’
iobjReply = toSingleNoun
;[/code]

“Fuse box” works perfectly fine, but “Add box” causes it to crash. I’ve played hunt the bug for awhile but as far as I can tell the code for each of them is only superficially different. Is there anything I’m missing?