Broken Code (adv3Lite)

Your speculation or psychic powers may be useful here. I have an NPC AgendaItem that was working perfectly, but now it’s refusing to fire. I know it was working, because I can find the output in several tester transcripts from last week. The code for the AgendaItem hasn’t changed (though today I’ve tried tinkering with it, which hasn’t solved the problem). The code for the NPC’s Actor object hasn’t changed. The NPC is definitely present in the room, because he can be examined. Yet the AgendaItem (which provides the player a useful clue) is now dead silent. It doesn’t fire in a transcript I got from a tester this morning, and it doesn’t fire for me either.

For reference, here’s the code (not that that’s likely to tell you anything), with only one tiny spoiler replaced with Xxx:

+ frankXxxxClue: AgendaItem
    isReady = (gPlayerChar.getOutermostRoom() == securityOffice)
    initiallyActive = true
    invokeItem() {
        "As you enter the Security Office, the two guards are in the 
        midst of a discussion. <q>All I\'m saying,</q> one of them says,
        <q>is that we ought to be able to keep an eye on the leather
        goods shop.</q> He gestures at the big monitor screen. <q>We
        can see just about every other shop, the ones we need to see,
        anyhow.</q>
        <.p><q>Ah, it doesn\'t matter,</q> the other guard says. <q>It\'s
        not like anybody is going to come around here with their pants
        falling down and need to steal a belt.</q> ";
        isDone = true;
    }
;

This is embedded directly in the Actor object. I’ve tried moving it to the current ActorState (and adding a +, obviously). That doesn’t help.

I’ve run eval on the properties of the AgendaItem. They’re all what they should be. It’s initiallyActive, it’s isReady, and it’s not isDone. The gPlayerChar is definitely in the correct room. But the item doesn’t fire.

I tried stepping through the library to see what is or isn’t happening using breakpoints, but the process the library goes through at this point is so complex that I just plain don’t understand what’s going on, or where it could be going astray.

One remote possibility (which I would prefer not to contemplate) is that the overall size of the game has gotten too large for the interpreter software, which could lead to impossible-to-trace bugs. This morning a tester sent me a transcript that contained two absolutely impossible phenomena. He says he’s using the most recent version of QTads. In one moment in his transcript, QTads used the spelling corrector when he typed ‘dust’, correcting it to ‘dusty’ and thereby interpreting his command as referring to an object that was definitely not in scope. I couldn’t duplicate that error.

This is a very, very large game, so the possibility that I’m crashing up against the walls of the interpreter, though remote, is not beyond the realm of possibility. Comments would be appreciated!

1 Like

I’ve managed to really stress the limits of TADS interpreters before with some really crazy stuff, and had one game where you would have to wait a full two seconds after typing your command before the results arrived. While I don’t doubt that it’s possible to hit the limits of the interpreter, I still feel it’s unlikely, and I also doubt it would cause this bug to occur. If something is breaking a limit of any kind on a modern computer, it will usually throw an exception of some kind, or refuse to run the game at all.

However, I’m not going to take that off the table completely, but there’s probably other hidden likely reasons to hunt first.

The first thing, are there ANY differences in code between when this item was last working correctly, to when you first noticed it stopped working? You have looked in all the obvious places, but every program is a deeply-interconnected system, and the most unlikely thing can cause a bug.

adv3Lite has this interesting thing where it evaluates the entire turn as a stoppable sequence. This is convenient sometimes, but it also means that anything that get poked and evaluated after the player enters a command can end the turn early (like an action abort or exit) and something like this could (uncertain) also halt the firing of agenda items.

Disclaimer: I have used adv3Lite a LOT but I don’t have enough experience in the agenda item system to know what and how it’s invoked under the hood.

In my current project, a whole string of things weren’t running because the stuff that was supposed to invoke/call them was found in the after-action half of the turn handling loop, so when an action was cancelled for being illogical, it would also prevent all of these other things from firing.

I’m sorry I don’t have anything more specific right now, but you have absolutely nothing on the code you’ve provided that would cause a problem. That all seems correct.

EDIT: Did some poking at the guides and source code for adv3Lite. Some things to note: It says that an actor can only handle one agenda item per turn.

Also, I haven’t gain a full clarity yet, but my digging has not revealed a direct connection between action responses and agenda item handling. Unless there’s a way for a daemon or event handler to get denied if an action ends early.

Hopefully someone else can shed some light as well.

There are many, many differences. I’ve been processing bug reports.

I’ve checked all the AgendaItems and afterActions in my code. None of them is in items that are in scope when this failure is occurring, and none of them has any dodgy code, as far as I can see.

I’m aware of that, yes. This particular Actor has only the one AgendaItem. The other Actor in the room has none at all. And I’m not using ConvNodes, which I know can preventing an AgendaItem from firing.

Other Actors’ AgendaItems are still firing correctly – I just now checked a couple of them.

Anyway, thanks for the suggestions. I’ll keep trying to isolate it.

Further notes:

InvokeItemBase is simply not called when the PC enters the location. This implies that the AgendaItem is not being added to a list of this NPC’s AgendaItems. However, this turns out to be a bad guess. If I eval the NPC’s agendaList, the AgendaItem is indeed on the list! For the AgendaItem, isReady is true, initiallyActive is true, and isDone is nil.

So the question, to be specific, is this: Why would an Actor’s agendaList not be called when the actor is in scope?

Solved it. For some reason I had added the line

conversedThisTurn () { return true; }

to the NPC’s class declaration. That shuts off any AgendaItem checking.

1 Like