A replacement for TADS3/adv3's seen/known/revealed mechanics

Here’s a TADS3/adv3 module for handling generic sense memories, intended to be a more-or-less drop-in replacement for the stock seen/knowsAbout()/gRevealed() system: memoryEngine github repo.


Instead of relying on flags on objects, the module by default creates a MemoryEngine instance on each Actor which uses a LookupTable to keep track of sense memories. This is intended to make it somewhat more straightforward to handle situations where you want to keep track of what a bunch of NPCs know about/have seen.


By default the module replaces the stock methods handling “seen”, “known”, “revealed” and “described” stuff: knowsAbout() and setKnowsAbout(), hasSeen() and setHasSeen(), gReveal() and gRevealed() and so on.

In addition, it provides (on Actor):

  • canSense(obj) returns boolean true if the actor can current detect the given object via any sense
  • hasSensed(obj) returns boolean true if the actor has previously detected the given object via any sense

There are also getters and setters for most of the memory properties. E.g. getDescribed(obj) returns boolean true if the actor has directly examined the given object and setDescribed(obj) sets the flag. Listing just the getters, theres:

  • getDescribed() has the actor directly examined the object
  • getKnown() does the actor know about the object. Automatically set when the object is sensed, can be set other ways as well
  • getRevealed() in stock adv3 this is only for conversational topics, but the module is agnostic about the object type revealed
  • getSeen() equivalent to hasSeen()

In addition, the module by default extends the tracked senses to include hearing, smelling, tasting, and touching. The compile-time flag -D MEMORY_ENGINE_NO_SENSES disable this behavior. With the extra sense logic enabled, Actor also gets:

  • getHeard()
  • getSmelled()
  • getTasted()
  • getTouched()

…as well as the corresponding setters. Also, the given object will be flagged as known if detected by any sense (instead of just sight in stock adv3).


In addition to replicating the stock seen/known/revealed behavior and extending it to other senses, the module by default tracks additional information about memories:

  • room the last-known location of the object
  • createTime the turn the memory was created on
  • writeTime the last turn the memory was updated on
  • writeCount the number of times the memory has been updated
  • readTime the last turn the memory was “remembered”
  • readCount the number of times the memory was read

Tracking of this additional stuff can be disabled by compiling with the -D MEMORY_ENGINE_SIMPLE flag.


The module also provides an Alert class as a mixin for Actors who should automagically sense their environments (in more or less the same way the player does).


Actors can also be assigned memories via declaration:

+alice: Person, Alert 'alice' 'Alice'
        "She looks like the first person you'd turn to in a problem. "
        isHer = true
        isProperName = true
++Memory ->pebble
        seen = true
        room = startRoom

…to have Alice have the memory of having seen the pebble in the location startRoom.


If compiled with the -D __DEBUG_MEMORY_ENGINE flag, the module provides some debugging commands:

  • >MA [actor] shows a summary of each of the actor’s memories
  • >MA [actor] actor|object|room shows a summary of each of the actor’s memories about other actors, objects, or rooms
  • >MA [actor] [object] shows a summary of the actor’s memories about the given object
  • >MO [object] shows a summary of the player’s memories about the given object
  • >ME displays information about the total number of memory engines and memories currently in the game

I’m also working on a module for handling more abstract/derived knowledge (instead of direct sense memories) and working on that will probably result in changes to this module. So there will probably be some churn.

But I’m basically trying to motivate myself to get more of this stuff done, so I’m publicly releasing it now.


I really love the holisitc idea behind this implementation. I regret that my WIP is waaay too far long for a retrofit. Bookmarked!


Just a little bump. I just updated the module to use the unique ID module I put up the other day.

Right now this mostly just means that in places where an argument indicates what a memory is of, either an object reference or an object ID will work.