[adv3lite] possible bug with gVerifyIObj and implicit actions

Hi Eric and friends,

Is the appropriate place to discuss issues here or should I open an Issue on GitHub?

  • tads version: Release HT-24 (Build Win121; TADS 3.1.3)
  • adv3lite version: 16.1
  • severity: high (crash)

I was trying to understand some of the code around implicit actions and questions. I took the vanilla Cloak of Darkness from Cloak of Darkness · EricEve/adv3lite Wiki · GitHub, created a new adv3Lite project and did the following.

w
put cloak

This caused a fault which stopped the process.

Debugging shows that gVerifyIObj is defined as

#define gVerifyIobj (gIobj ?? gTentativeIobj[1])

In this case gIObj is nil because I haven’t specified one. gTentativeIobj is also nil. Attempting to reference the first index is what is causing the crash.

Thanks for any suggestions you can offer!

3 Likes

I can confirm this. The definition of gVerifyIobj is brittle, always requiring an object reference to be returned. At first I thought maybe it should return a dummy object if gTentativeIobj failed, but then the use of gVerifyIobj would be inconsistent if a player tried

if(!gVerifyIobj.ofKind(Fruit)) logical;

where, especially if it is possible that this situation can happen at any time other than right after game launch, the dummy object could potentially pass verify for an action that clearly expects a sim object…

Should a dummy gCommand be in place at the beginning of the game so gTentativeIobj is never nil or length 0?

Note that if you launch a (skeletal) game and begin with

>put hat in me
You can't.
>put hat
What do you want to put it in?

there is no error. It’s like it takes the first mention of an iobj to get it set.

@Eric_Eve

2 Likes

I don’t think the problem is with gVerifyIobj. Although it’s the attempt to evaluate it that causes the run-time error, in a way this could be seen as a good thing, since it’s calling attention to problems that lie elsewhere.

One problem is that that the parser is interpreting PUT CLOAK as an incomplete PUT IN command, which I don’t think it should do (why PUT IN rather than PUT ON or PUT UNDER or PUT BEHIND?). So one response here would be to tell the player they need to specify where they want to put the hat. This is relatively easy to do (define a PutVague Verbule with a corresponding Put Action which is ruled out accordingly at the verify stage).

But this doesn’t address the problem of why the parser is calling the verify routine that triggers the runtime error in the one case (the initial PUT HAT) and not the other (PUT HAT following PUT HAT IN ME), so I need to dig a bit deeper to figure out what’s happening here.

Part of what’s happening is that following PUT HAT IN ME gIobj is still set to me when the command PUT HAT is parsed, so that gVerifyIobj evaluates to me and the runtime error triggered by trying to evaluate gTentatativeIobj[1] is never triggered, but that all raises further questions I need to delve into.

EDIT: A tentative set of fixes fix is to change a line in the selectObjects(cmd) method in parser.t (so that verify methods that cause the error have less reason to be called, to change the definition of the gVerifyDobj/gVerifyIobj macros so that they evaluate to nil in cases where the runtime error would otherwise occur, and adding protective code to statements where this might cause a nil object reference error (by using if(gVerifyIobj && …)). I’ll mull over it a bit more before uploading these changes to GitHub.

@johnnywz00

3 Likes

A couple of notes: I mistyped when I said the response was

What do you want to put it in?

In fact, it said

Where do you want to put it?

as it should.
Furthermore, it seems to be the case that once an iobj is referenced, it doesn’t matter how many intervening commands there are, the next time you try ‘put cloak’, there will be no error.
Could this not possibly be fixed by giving gTentativeIobj some kind of starting value? It seems then that the behavior would be from the start as it is after I typed ‘put hat in me’.
It seems that it would be a shame to change gVerifyIobj (if indeed this is the only instance where gTentativeIobj comes up empty), because of how much verb code relies on the definition as it is. Also there may be users who are used to using gVerifyIobj without having to do the && check and might get confused.
Just submitting some thoughts… I know you’ll do what you think best with it.

1 Like

I checked, and the problem does not occur after a restore (presuming that an iobj was mentioned before the save). It seems to be only directly after game load or restart.

1 Like

I’ve now got back and taken another look at this and pushed my tweaks up to GitHub. gVerifyIobj and gVerifyDobj now return a dummy failVerifyObj object in cases that would otherwise result in a nil object reference runtime error. There’s also a minor tweak to the Parser object that makes it a little less likely to call verify routines in the problem case. In my test case an initial PUT KEY now results in a correct ‘Where do you want to put it?’ response.

As this is the only change I’ve made since version 1.6.1 it doesn’t seem worth releasing another version yet at this stage.

3 Likes

Github still shows 1.6.1 as a March 15 release. Is that the download with the new tweaks?

1 Like

No, that’s the 1.6.1 release. The tweaks are in the files in the main repo. If you look down the list you’ll see some labelled “fixed gVerifyObj problem”.

1 Like

yes, I confirm.

more detailed is the commit page:

From which appears that only five files are changed, I suspect that all is needed is DL these four files, and copy them in their places on the working adv3lite directory (in my case, if/wrk/tads3/a3lite)

Best regards from Italy,
dott. Piergiorgio.

ps. for Eric: you have thinked about porting ProxyActor as extension to vanilla adv3 ? :wink:

1 Like

I confess I hadn’t, since it’s quite a while since I’ve given any thought to adv3, but if anyone wants to make an adv3 version of ProxyActor they’re welcome to do so.

2 Likes

no more needed. Last week I have surprisingly successfully ported my 230+ Kb WIP from adv3 to adv3lite in 4-5 sessions, so a3Lite’s ProxyActor is ready to strenghten Azuj & Miyai…

now, I’m hunting for a thread where I posted an assertion that was too difficult porting a WIP from adv3 and adv3Lite, for duly retracting said wrong assertion (coming from the very same country of Galileo, i must apply to the hilt the scientific method…)

Best regards from Italy,
dott. Piergiorgio.

1 Like