[adv3lite] Nil references, part two.

This may be a continuation of issues initially encountered with version 1.1 of adv3lite as detailed here - [adv3lite] Nil references with commands and NPCs and commas.

Note I’m now using version 1.2 of adv3lite.

The setup is thus: an initial event is triggered by asking an NPC something. Two turns later this event is triggered and sets in motion another event for ten turns later (and a sub-event for two turns before that).

When the second event is triggered, the NPC is removed from the location (sent to nil) via actionMoveInto, and an unthing representing said NPC moved in in its place. It’s not very easy to reproduce this bug but it does seem to be triggerable by attempting to give the NPC commands both just before and after the event triggers.

Boy, I wish QTads allowed selecting and copy-pasting, but anyway…

This is going to be pretty much impossible to diagnose without seeing the actual code that’s causing the problem together with the precise steps needed to reproduce the bug. Looking at the line numbers in the Runtime error listing it looks to me as if the problem may be something to do with trying to construct a scope list for an actor whose current location is nil, which from your description may arise from trying to give an order to an NPC who has just been moved into nil, but I don’t have enough information to see how this is coming about.

You can find the source code and an as-of-right-now build dl.dropboxusercontent.com/u/677 … Concept.7z here, Eric.

As for precise steps, from the start of the game:

ASK SHAMUS ABOUT LOST SPIRIT,Z,Z
Z,Z,Z,Z,Z,Z,Z
SHAMUS, GET ME
SHAMUS, GET TILES
SHAMUS, GET DOOR
SHAMUS, GET WINDOW
SHAMUS, GET BOARD

It should crash at the SHAMUS, GET DOOR mark.

If there’s anything else you need, ask and I’ll give it you.

I’ve downloaded your code and tried it, and I get the error at the command SHAMUS, GET WINDOW (looks like the same error, though). As I thought, the problem is that Shamus is in nil at that point, so the game falls over trying to build his scope list (which includes the list of things in nil). It would be easy enough to block the nil object reference error that causes, but first I want to investigate why the parser is accepting a command directed at Shamus when Shamus is in nil (and should therefore no longer be in scope to act as the target of the command), since this seems to me to be the more worrying error. I’ll get back to you when I’ve investigated further.

This may be related to another issue I had: you may have noticed the Unthing for Shamus that gets moved into the location after the event has triggered. Letting the game run without triggering the crash, and then typing a command like “SHAMUS, GET WINDOW” after the second event has triggered results in “There’s no point in trying to give orders to a shamus”. It seems odd, especially as an ask command (e.g. “ASK SHAMUS ABOUT SHAMUS”) gives the expected behaviour at this point (i.e. the response message for the unthing).

I also managed to get it to trigger the crash with an “ASK SHAMUS ABOUT” command, by having two "SHAMUS, GET " commands just before the event triggered, then “ASK SHAMUS ABOUT SHAMUS” just after the event triggered.

I think I’ve tracked down the problem, which is a subtle library bug that’s only getting triggered in this kind of sequence. Basically the problem is that the value of gActor is getting set after trying to find the actor’s scope, so if you’ve just issued a command, then on the following term the parser may be trying to find the scope of the actor you just gave a command to instead of the actor that just gave the command (normally the player character). The solution appears to be to reset gActor to gPlayerChar near the start of the Parser.parse() routine [in parser.t] thus:

parse(str)
    {
        /* tokenize the input */
        local toks;
        try
        {
            /* run the command tokenizer over the input string */
            toks = cmdTokenizer.tokenize(str);
            
            /* Dispose of any unwanted terminal punctuation */
            while(toks.length > 0 && getTokType(toks[toks.length]) == tokPunct)
                toks = toks.removeElementAt(toks.length);
            
        }
        catch (TokErrorNoMatch err)
        {
            /* 
             *   The tokenizer found a character (usually a punctuation
             *   mark) that doesn't fit any of the token rules.  
             */
            DMsg(token error, 'I don\'t understand the punctuation {1}',
                 err.curChar_);

           
            
            
            /* give up on the parse */
            return;
        }

        /* Assume initially that the actor is the player character */ //NEW LINES ADDED HERE
        gActor = gPlayerChar;        // AND HERE
        
        /* no spelling corrections have been attempted yet */
        local history = new transient SpellingHistory(self);

Yes, I’d just noticed this too, and had already just fixed it in my copy of the library before reading about it in your last post. The fix is to add the following method to the definition of the Unthing class:

    /* 
     *   Giving an order to an Unthing should give the same response as any
     *   other command involving an Unthing.
     */
    handleCommand(action)
    {
        say(notHereMsg);
    }

I’ve just uploaded these changes to GitHub.

Thanks for the help, Eric! So far, everything seems to be working as expected, so with any luck there won’t be any more threads on this error happening.