A TADS3/adv3 module that modifies some stock actions to work for NPCs

Another day, another module: thirdPersonAction github repo.

This one’s designed to fix some stock actions that really only work when the player is the one doing them. For example, by default something like:

     newActorAction(alice, Smell, flower);

…will output something like…

     Alice smells nothing out of the ordinary.

…without any indication of why the game has decided to output that. With this module, the same action would produce something like:

     Alice smells the flower.

That’s the reasonably straightforward part. Under the hood most of the module code is devoted to running the base version of the action with no output, so that any side-effects of the actions will still occur. So for example if the flower has something like:

     smellDesc = "It smells like a flower.  <<someMethod()>>"

…then newActorAction(alice, Smell, flower); will still call flower.someMethod() even though no output is produced.

I have no idea how common the need for this sort of thing is, but for my WIP I’m using my updated memory model, which keeps track of gReveal tags on a per-actor basis. So having gReveal tags in descriptions working correctly for NPCs is a Big Deal.

7 Likes

I’ll look into it; if is portable to a3Lite I will consider doing the porting, because this can ease the NPC scripting & behavior, whose depends on the PC’s state (that is, calling methods whose output and variable settings depends on the value in pc.whatever)

Thanks, and best regards from Italy… and, please give more love to your WIP :wink:
Dott. Piergiorgio.

1 Like

Minor update:

Since the module works by basically running the actions in question twice (once in the default way but with output suppressed and then in the new way with output enabled) this was basically always pushing the NPC’s nextRunTime back by twice action’s actionTime.

The module has been updated to reset the actor’s nextRunTime to be whatever it was before the extra steps, meaning the actions will only be “counted” once.

Another update.

Added support for non-player Actors using >TALK TO. Under the hood this involves providing an alternative to adv3’s Actor.initiateConversation() (which assumes any NPC talking will be talking to the player), and then updating Actor.dobjFor(TalkTo) to use if if the player isn’t the one taking the action. There’s also modifications to TopicDatabase.findTopicResponse() to work for actors other than the player.

I’m simultaneously working on a completely new, graph-based multi-person conversation system so my checking with the stock adv3 conversation mechanics is a little perfunctory. But I think it’s all working.

As a usability tweak, there’s now a TopicGroup subclass for grouping topics by “target” actor. Usage:

+alice: Person 'Alice' 'Alice'
        "She looks like the first person you'd turn to in a problem. "
        isHer = true
        isProperName = true
;
++InConversationState
        specialDesc = "Alice is here, talking with
                <<alice.lastInterlocutor.theName>>. "
        stateDesc = "She's watching you as you talk. "
;
+++ConversationReadyState
        isInitState = true
        specialDesc = "Alice is here, in the ConversationReadyState. "
        stateDesc = "Alice is in ConversationReadyState. "
;
++++TopicGroupFor @gPlayerChar;
+++++aliceHelloTopicPlayer: ActorHelloTopic, StopEventList
        [ 'This is Alice\'s hello topic for the player.' ]
;
++++TopicGroupFor @bob;
+++++aliceHelloTopicBob: ActorHelloTopic, StopEventList
        [ 'This is Alice\'s hello topic for Bob.' ]
;

All of the topics under the TopicGroupFor declarations are available only when Alice is talking to the actor specified by the @.

2 Likes