[adv3Lite] Doer never being executed?

I have a Doer that I want to apply when someone tries to unscrew an object in a certain room with a wrench:

Doer 'unscrew bolts with wrench; unlock grate with wrench; open grate with wrench'
    when = (wrench.isDirectlyHeldBy(gPlayerChar))
    where = megablockFloor1b
    execAction(cmd)
    {
        "With surprisingly little effort, you're able to screw the bolts out of the grate. Freed, the gate falls to the ground with a clattering sound that's loud enough to make you wince. You look around, wondering if anyone's watching, but of course no one is.";
        bolts.unscrewed = true;
        bolts.moveInto(megablockFloor1b);
        grate.moveInto(megablockFloor1b);
    }
;

Note: I’m putting this in a Doer because it I don’t know whether the iobjFor action on the wrench will take precedence over the dobjFor I already have on the bolts handling cases where the player doesn’t have a wrench yet. And also because it seems more natural to me.

Anyway, no matter how I formulate the command, all I seem to get is “You can’t unscrew anything with that.” Is there something I’m missing?

1 Like

WAIT. SO I’M NOT CRAZY???

Okay, so…

Bad News: I’m really sorry that I don’t have a solution. I have never ever gotten a Doer to ever work, no matter what I try. I have been surviving on hilarious dobjFor(ActionName) and modify ActionName magic this whole time.

Good News: Doers seem to hate me specifically, but everyone else swears by them. So if @jjmcc, @jbg, or @johnnywz00 know how to convince Doers to function at all, then all of us might have a collective learning experience here, lol.

2 Likes

Never used Doers yet(just did first reading on them a few nights ago) but don’t you need to still make sure the wrench clears verifyIobj(un)screw?

1 Like

Oh, that’s true. Didn’t think of that. There’s something else I realized though too.

2 Likes

@inventor200 I just realized something really important: while Doers match verbs based on literal matches or on built-in synonyms, the nouns in Doer syntax match based on class names or object names, not literal strings or synonyms thereof. In my case, I forgot that and had this Doer referring to the wrong bolts and grate, as well as the issue @johnnywz00 mentioned.

2 Likes

With those two fixes, it works.

2 Likes

Honestly, @inventor200, the confusion is understandable. Having nouns match on names of objects or classes (especially objects) without any sort of extra syntax to indicate that entities in your wider code, instead of literal strings, are being matched, so they look like literal strings but aren’t, is pretty confusing, because it just looks like a plaintext string, especially if you give your objects human-readable single word names. I think it would be way better if doers used syntax more similar to verb definitions. But ofc I’m hesitant to say I know better than Eric Eve.

1 Like

IS THAT WHAT’S HAPPENING???

Holy cow, this clarifies so many things!!! Thank you for your investigations! It never clicked in my head that this is what was going on. I thought it was matching literal player input strings this entire time! Most of the time, it wasn’t even compiling!

2 Likes

TADS-conventionally, instrumental iobjs almost never process any of the action. If it’s an iobjFor(VerbWith), all you’re likely to do is silently clear verify() and check(), with perhaps a touch or held precondition. So I’d say that dobjFor(Unlock/Unscrew) on the grate/bolts is a perfectly logical TADS-esque place to put that logic. On the other hand, iobjs might process all of the action for a Put or Throw verb, and Attachables might have a sort of reciprocal relationship between dobj and iobj…

1 Like

So glad I could help! And yeah, when the passage from the Library Manual suddenly bubbled up in my memory it hit me like a train that this was probably the same problem you were facing! It actually mentions this in the manual here:

The verb phrase syntax is generally the same as for regular player commands, but the noun syntax is different. Each noun is written as the source code name of a game object or class. That is, not a noun-and-adjective phrase as the player would type it, but the program symbol name as it appears in the source code. If you use a class name, the command matches any object of the class.

I knew that when I originally wrote the Doer, but in between writing it and testing it I changed some object names, and then when I was trying to fix it I skipped over the Doer command strings because they looked like literals.

1 Like

That all makes a lot of sense, thank you. Nevertheless I think I’ll stick with Doers, if for no other reason than that if I put it on a dobjFor instead of a Doer then I have to manually check what iobj is being used instead of matching it, which is more work.

1 Like

Edit: on further experimentation, since Doers only apply to one specific action, I’m running into an issue where if you try to unscrew the grate with something other than the wrench, or without the wrench in hand, it just says that you can’t unscrew the grate, which means I now have to define a dobjFor(UnscrewWith) on the grate anyway, which means I feel like I might as well just move from a Doer to a full on dobjFor

1 Like

Of course, let your code layout make you happy!
Academically speaking, this is an extremely common TADS paradigm:

bolts: Thing
        // elsewhere we may remap grate.dobjFor(Unlock(With)) to this action
   dobjFor(UnscrewWith) {
         verify() { /*we're logical*/ }
         check() { 
                     // we don't have to cater for every object in our game because only a couple of things are probably going to pass verifyIobjUnscrewWith
             if(gIobj==plausibleAlternative) "The reason why it doesn't work";
             else if(gIobj!=wrench) "The bolts need a special kind of wrench to be unscrewed. "; }
                    //we won't get here unless we're unscrewing us with the right tool
         action() { //desired code

Not that any of that is news to you, but I’m just saying that’s a perfectly normal and efficient way of handling things in the TADS world…
Personally I feel like Doers are there to stand in for the cases that really just make you scratch your head about how to handle them…

EDIT: And just now saw your post above this one

2 Likes

Or in this case, it would be knowing better than Mike Roberts, since the Doer mechanism is part of the (never finished) Mercury library I took over and incorporated into adv3Lite.

That said, I think Mike’s choice makes sense here (a) because it would be confusing if Doers matched on the programmatic name of classes but on the vocab of individual objects and (b) because a vocab match might be potentially ambiguous while using the programmatic object name makes it completely clear which object you have in mind.

As for the way the verbs are specified on Doers, I’d guess that Mike thought that something like ‘put Treasure in collectionCrate’ might read more naturally than ‘PutIn Treasure collectionCrate’.

5 Likes

I haven’t used Doers much, but this morning I found that adding a couple of Doers solved a really horrible problem as I try to clean up the remaining bug reports for “The Only Possible Prom Dress.” Anecdote follows.

The game has a little red wagon, which you can pull around. Eric provided some code (this was prior to the release of adv3Lite 1.6) that assisted in this, which IIRC was needed because there’s a room where the exits have no direction property; instead, you have to pull the wagon through a specific door. But there was a place where I was getting spurious messages in the game output: pulling the wagon up or down the ladder. I woke up this morning thinking, “This would be so much easier in Inform! I could just write an Instead rule.” And then I realized, adv3Lite has Instead rules! I can use a Doer. It works perfectly. Problem solved.

2 Likes

Yeah, Doers seem incredibly useful as a general rule, they just didn’t work out for me here because I had to give proper error messages if the wrong combination of objects was tried with the verb in order to make the puzzle sensible, so I had to handle a general case.

1 Like

For the record, Jim, I still look forward to finishing Prom dress, along with @jnelson 's Cain, after I get through the craziness of my own game (maybe by June???)

1 Like