The Phantom Nail (adv3Lite)

Today I ran into a really wacky problem in I7 … so I thought, “Let’s see how T3 handles that.” This led me to discover an entirely different class of problem, but one that’s just as baffling. I have created three nails and attached them to a plank – but initially the descContentsLister senses and reports on four nails, not three.

Here’s the code:

class Nail: AttachableComponent
    vocab = 'nail; iron sharp; spike'
    desc = "You've seen nails before. "
    dobjFor(Detach) {
        verify() {}
    }
    dobjFor(DetachFrom) {
        verify() {}
    }
    dobjFor(AttachTo) {
        verify() {}
        check() {
            if (gIobj != plank) "You can't attach a nail to that. ";
            else if (attachedTo == plank) "The nail is already attached to the plank. ";
        }
    }
;

lab: Room 'The Lab'
    "A not entirely sterile room filled with bubbling retorts, oscilloscopes, and discarded
    candy wrappers. "

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

++ plank: NearbyAttachable 'plank; hefty wooden wood; board'
    desc {"It's a hefty wood plank. "; }
    //attachments = [nail_1, nail_2, nail_3]
    iobjFor(DetachFrom) {
        verify() {}
    }
    iobjFor(AttachTo) {
        verify() {}
        check() {
            if (!gDobj.ofKind(Nail)) "You can't attach that to the plank. ";
            else if (gDobj.attachedTo == plank) "The nail is already attached to the plank. ";
        }
    }
;

+++nail_1: Nail
    attachedTo = plank
;
+++nail_2: Nail
    attachedTo = plank
;
+++nail_3: Nail
    attachedTo = plank
;

…and here’s the output:

>i
You are carrying a plank.

>x plank
It’s a hefty wood plank. You see four nails attached to the plank. 

>detach nail
You detach the nail. 

>x plank
It’s a hefty wood plank. You see three nails attached to the plank. 

>detach nail from plank
You detach the nail. 

>x plank
It’s a hefty wood plank. You see a nail attached to the plank.

You’ll notice that when the attachments list decrements from 2 items to 1 (1 remaining nail), the bug goes away. Looking at the Watch Expressions in Workbench using a breakpoint in descContentsLister, here’s what I’m seeing:

watch

nail_3 is being listed twice. Bug in library? Probably. Suggestions on how to nuke it?

Deleting the attachedTo property of each nail changes the output to

x plank

It’s a hefty wood plank. You see three nails attached to the plank.

Adding attachedTo = plank to nail_1 then shows the original buggy behavior, but now it’s nail_1 that’s listed twice.

I am just learning adv3lite, but to hazard a guess perhaps the AttachableComponent is inheriting some behavior from its parent SimpleAttachable in preInitThing?

Thanks! That solves the problem.

I’m sure you’re right. What’s going wrong is not in descContentsLister, which was my first guess, but in PreInit. Apparently PreInit will set up the attachments correctly if the classes are declared and the AttachableComponent is given the appropriate location. I was assuming I had to specify attachedTo.

The good news is, this is clearly user error on my part. The weirdness I ran into with I7, which is why I started looking at the T3 method, is more likely a library bug.

I looked into this some more, and I’m not so sure it’s not a bug, or at least something that could be clarified. If you look at the preInitThing of AttachableComponent,

    preinitThing()
    {
        /* Carry out the inherited handling. */
        inherited;
        
        /* 
         *   If we start out initiallyAttached, note that we're attached to our
         *   location and add us to our location's list of attachments.
         */
        if(initiallyAttached)

And then the preInitThing of SimpleAttachable


    /* Preinitialize a SimpleAttachable */
    preinitThing()
    {
        /* carry out the inherited handling */
        inherited();
        
        /* if I'm attached to anything, add me to its attachment list */
        if(attachedTo != nil)
            attachedTo.attachments = 
            attachedTo.attachments.appendUnique([self]);

It seems like it’s added twice, if initiallyAttached. You don’t see six nails in your example because of appendUnique – change that to append, and you will. You see 4 nails with appendUnique because, I think, of the order of the preInitThing calls.

Maybe one of these days I’ll get around to learning Lite, but I should probably finish my going-on-two-years adv3 game first :slight_smile:

I hope you finish your game! adv3 and adv3Lite are very similar, except where they’re different. The syntax for declaring vocabWords is different, and you don’t have to use the exit macro in a check() routine, stuff like that.

By now I don’t remember why I switched, but I like adv3Lite. I think Mike originally went for “robust,” while Eric went for “clean.” (Note that the parser in adv3Lite is in fact Mike’s work, which Eric built on.)

I have no doubt Lite is good. It’s just that I’ve invested so many hours with my nose buried in the adv3 Library Manual, I can’t see myself switching, when it does everything I can think of needing and I’ve grown quite fond of it :slight_smile: