nil obj ref after changing gPlayerChar (adv3Lite)

In my game, gPlayerChar is candidate until a test period is over at which time gPlayerChar morphs into saturnExplorer. Both are actor objects.

This is achieved by these lines of code…

setPlayer(saturnExplorer);
candidate.moveInto(nil);
saturnExplorer.moveInto(hibernationChamber);

All is well. The game works, I can play the entire game to a successful conclusion.

However, a tester has encountered a nil obj ref during game play when he enters the command close eyes immediately after the player char switch. Actually, any command that takes a direct object—whether it’s a valid command or not (take drink even though there is no drink in scope), will achieve the same results, as will a non-implemented action whether it takes an object or not, such, as awaken for which there is no implementation in my game.

If I enter a valid command without an object (look or wait, I can then enter the close eyes—as well as the take drink and awaken commands—without encountering the nil obj ref.

I’ve found where the problem occurs, just not how to avoid or correct it.

The nil obj ref error is produced by line 960 in query.t…

    addSelfIlluminatingWithin(obj)
    {
        addAll(obj.intContents.subset({x: x.visibleInDark}));
    }

…which is fed by line 183…

            local c = actor.outermostVisibleParent();

The local c is used in a subsequent call to addSelfIlluminatingWithin, where it becomes the the obj of line 960.

When I run my game and set a breakpoint at 183, actor is candidate, not saturnExplorer as expected (since it’s after the player char switch). Since candidate is by now located in nil, c is nil, and line 960 generates a nil obj ref.

I’ve been able to reproduce the error in a test bed environment. Initially, the player char is me.
When you push the magic button, me is moved into nil and otherPerson becomes the player char.

If you then enter any command that takes an object—take drink for example—the nil obj ref error occurs.

If you enter the command wait first, then take drink, it does not.

Here’s the test bed code…

#charset "us-ascii"

#include <tads.h>
#include "advlite.h"

versionInfo: GameID
    IFID = '445C38A3-AD1B-4729-957A-F584600DE5C1'
    name = 'test'
    byline = 'by Jerry Ford'
    htmlByline = 'by <a href="mailto:jerry.o.ford@gmail.com">
                  Jerry Ford</a>'
    version = '1'
    authorEmail = 'Jerry Ford <jerry.o.ford@gmail.com>'
    desc = 'Testing scene.'
    htmlDesc = 'Testing scene.'

;

gameMain: GameMainDef
    initialPlayerChar = me
    paraBrksBtwnSubcontents = nil
   
;

me: Actor 'me' @room
    "The main man.<.p>"
    isHim = true
    
    person = 2
;
+ eyes: Thing, Fixture 'eyes'
    "Eyes."
    
    isOpenable = true
;

otherPerson: Actor 'other person'
    "The other person. <.p>"
    isHim = true
;

room: Room 'room'
    "In the room. \b
    A magic button mounted on the wall is currently in the <i><<magicButton.status>></i> position. <.p>"
;
+ magicButton: Button 'magic button'
    "The magic button. <.p>"
    
    status = 'off'
    
    dobjFor(Push)
    {
        action()
        {
            status = (status == 'on' ? 'off' : 'on');
            "The button's status changes to <<status>>. <.p>";
        }
    }
;

otherRoom: Room 'other room'
    "The other room. <.p>"
;


showTime: Scene
    startsWhen = magicButton.status == 'on'
    whenStarting()
    {
        otherPerson.moveInto(otherRoom);
        setPlayer(otherPerson, 2);
        me.moveInto(nil);
        otherRoom.desc;
    }
;

This looks similar to the nil object reference bug in the immediately preceding thread. So I guess the next question is, have you downloaded the most recent library from github?

I believe Eric fixed the condition in the previous thread (sslaxx’s problem with shamus), and those fixes are in the adv3Lite 1.2 release, which I have downloaded and installed.

The error occurs with the 1.2 library (though my game, which has been in the works for some time, is compiled with 1.0—I hope I don’t have to change libraries, the game has been through extensive testing and I’d hate to spring a new library on it at this late stage. I’m hoping to find a patch, or at least a workaround kludge.)

Jerry

Okay, I do have a kludgy workaround.

Since the nil obj ref only occurs if the command that triggers it is the first command out of the box with no look or wait command as a buffer, I can force a wait in a StringPreParser…,

StringPreParser
    doParsing(str, which)
    {
        if(saturnArrivalScene.isHappening && gActor == candidate)
        {
            say('You feel somewhat dazed, a bit groggy. You shake your head
                once, which clears your mind. <.p>');
           str = 'wait';
        }
        return str;
    }
;

…which, when you wake up after hibernating to Saturn orbit, produces…

So instead of a nil obj ref error, I get a …you are groggy… message which allows the library to reset itself and handle the close eyes command correctly.

Not ideal, but at least it’s not a crash.

Jerry

No, sslaxx’s thread and my fix post-date the 1.2 release, so the fix isn’t in that. As Jim says, you need to download the latest version from GitHub (which is post 1.2) for the fix (or else manually apply the patches I described in the other thread). Your description of the problem certainly makes it look like it’s the same bug, and when I run your sample code with my version of the library I don’t get the error, so Jim is almost certainly right in everything he says; it’s the same bug and it’s fixed in the latest version on GitHub.

On the other hand, if you issue your game with the version 1 library it will have all the library bugs that were fixed in the 1.1 and 1.2 releases, and not just this particular bug you’re trying to deal with.