A TADS3/adv3 module for implementing NPC daily schedules

This builds on the calendar and targetEngine modules. It’s intended to make it easier to implement scripts for repetitive NPC behaviors, like Majora’s Mask-ish daily schedules. The code: dailySchedule github repo.

I’ll just dive in with an example:

alice: Person 'Alice' 'Alice'
        "She looks like the first person you'd turn to in a problem. "
        isHer = true
        isProperName = true
+DailyActivity 'work' [ 'morning', 'afternoon', 'evening' ] @aliceShop
        startActivity() { mainReport('Alice starts work for the day. '); }
        endActivity() { mainReport('Alice finishes work for the day. '); }
        activityAction() { mainReport('Alice does some work. '); }
+DailyActivity 'home' [ 'night', 'early' ] @aliceHouse;

Going through the bits, this is:

  • A standard adv3 NPC declaration
  • A DailyActivity declaration for the “work” activity. It occurs during the “morning”, “afternoon”, and “evening” time periods every day. These are IDs from the standard daily cycle defined in the calendar module.
    At the start of the “work” activity, if Alice isn’t in the aliceShop location she will attempt to path there.
    The first turn after arriving in the target location, the message “Alice starts work for the day.” will be displayed in Alice’s scope.
    Every turn thereafter during the relevant periods, “Alice does some work.” will be displayed.
    When the period is no longer “morning”, “afternoon”, or “evening”, the message “Alice finishes work for the day.” will be displayed.
  • A DailyActivity declaration for the “home” activity. It occurs during the “night” and “early” periods.
    If Alice is not in the aliceHouse location during these periods, she will attempt to move there.
    Once there, Alice will do nothing in particular.

In this case all of the activities are declared directly on the NPC. When you do that, the module will automagically create a default DailySchedule instance, make it active, and add all activities to it. You can also declare multiple DailySchedule instances on the NPC (using the canonical +[declaration] syntax) and juggle them by hand.

Under the hood every DailySchedule is also an AgendaItem, so you can play with which one is active on a turn by adjusting the agendaOrder or by manually adding and removing them from the actor’s agendaList. There will probably eventually be logic for doing this supplied by the module, but I’m not sure what that’s going to look like yet.

This is all pretty simple; it’s basically just duct-taping together the very simple behavioral agendas provided by the targetEngine module, but it does about 90% of the non-unqiue scripting stuff I want for most “background” NPCs (where I don’t want them to be completely static, but I’m not going full-on behavioral scripting with them either).