A TADS3/adv3 module for providing per-actor action messages

Another itsy-bitsy module: actorActionMessages github repo.

This is intended to make it easier to define actor-specific action messages. Usage is straightforward:

alice: Person 'Alice' 'Alice'
        "She looks like the first person you'd turn to in a problem. "
        isProperName = true
        isHer = true
;
+NPCActionMessages
        okayTakeMsg = '{You/he} carefully take{s} {the dobj/him}. '
;

This defines the NPC Alice and then gives her her own action message object. In this case we just define a single custom message, for okayTakeMsg.

The module defines three classes for message objects:

  • ActorActionMessages which uses MessageHelper as its base. You probably don’t want to use it unless you’re planning on re-defining all the action messages for an actor
  • PlayerActionMessages which uses playerActionMessages as its base. This is for player characters
  • NPCActionMessages which uses npcActionMessages as its base. This is for, obviously, NPCs.

This is all really simple and is only a couple dozen lines of code, but I’ve been doing a lot of NPC scripting stuff and so wanted a modular way to do per-actor and per-“role” (that is, for characters that are doing a specific activity or are taking part in a specific event) action messages. So here it is.

4 Likes

You can elaborate somewhat more on your “per-role” ? (whose IS my main coding challenge, starting 2025)

Best regards from Italy,
dott. Piergiorgio.

1 Like

By “role” I just mean something that’s changing the character’s behavior in a global (that is, it applies to everything they’re doing, not just one specific task) but situational and temporary way.

To use a specific example, think of a gambler that’s playing a game of chance and is doing poorly. Maybe they start acting nervous, maybe, angry, or something else depending on the character of the specific gambler. This would influence not just the game-specific actions (like checking their cards or making a bet), but random other actions they might do in the course of a game (having a sip of their drink or whatever).

Instead of putting those situational inflections in conditional code in a single action message object, what I’m doing is using different action message objects.

1 Like

that is, the same NPC behaviour & reacting I’m designing but in the more limited scale of inflections like the manner of sipping, I’m correct ?

Best regards from Italy,
dott. Piergiorgio.

It’s for anything that’s handled as an action as opposed to being handled as a bespoke script. Say the action is Alice picking up a pebble. In terms of the underlying code, that can look like:

        "Alice looks left and right and then surreptitiously
             pockets the pebble. ";
        pebble.moveInto(alice);

…or it could look like…

        newActorAction(alice, Take, pebble);

In the first case you don’t need custom action message objects, because you can just output whatever you want. Even if you do use a message object in this case (to make it easier to localize, for example), you could still just use a one-off message:

        mainReport(&aliceTakesPebble);
        pebble.moveInto(alice);

…and elsewhere…

modify playerActionMessages
        aliceTakesPebble = 'Alice looks left and right and then surreptitiously
                pockets the pebble'
;

But on the other hand if you’re doing it the second way…just using TakeAction with an NPC…then it’ll be using the standard T3/adv3 mechanisms for figuring out what to output for the action. By default the only customization is based on whether the actor taking the action is the player character or an NPC (selecting playerActionMessages or npcActionMessages, respectively).

The module is just intended to make it easier to have more action message objects. One obvious use case is character-specific message objects, but the main idea is just to make it easier to group related messages together (so they can be toggled on and off together).

I also just pushed an update that:

  • Allows you to declare message objects on ActorState instances as well as Actor instances
  • Supports declaring travel messages (sayArriving, sayDeparting, and so on) on the message object

You can already define travel messages on actors and actor states in stock adv3, so the second bit is just intended to make it easier to put everything in one place.

2 Likes

Declaring travel messages when NPC is in AccompanyingState should be the very first thing to do under adv3… the ambiguity, to put it mildly, of adv3’s stock

NPC comes with you

should be, frankly, on the top of every TADS3/Adv3 coder’s modify list…

Kudos, and
Best regards from Italy.