Argax Project

Node Status: COMPLETE

Story Context: Triggers

After a scene plays, its getTriggers function is called. The scene can then add to the story context by returning one or more triggers from this function. A trigger simply watches for the later occurrence of a certain deed or event. Upon finding a match, the trigger can then modify the casting of a matching deed or the recasting of a matching event.

For instance, in an interactive Bluebeard fairy tale, a scene could have Bluebeard tell the player not to open a certain closet. The scene then ends, but it would also provide a single trigger to watch for the Open(closet) deed. Should this deed occur, the trigger can then recast the default MANIPULATE(closet) event to include a DEFY(Bluebeard) sub-event. Now both the MANIPULATE and the DEFY actions can provide material for future scenes. Certainly such a fairy tale would include a scene that provides a response to DEFY-ing Bluebeard.

A deed is cast to an action by the first trigger that matches that deed. Casting triggers are processed in the order they were added to the story context, starting with the most recently added trigger. Each action event is then recast by all the triggers that match it. This means a single deed can produce a fairly sizable tree of sub-events that represent all the story-level interpretations of that deed.

Because casting and scene selection actually happens before a deed is allowed to complete, it is also possible for a casting trigger to interrupt a deed. For example, a player may try to open a certain door. However, a casting trigger could cast this opening deed to an ATTEMPT action and thereby prompt a scene in which a nearby NPC leaps forward to prevent the player from actually opening the door.

Sometimes a scene may need to establish a more complex context than can be managed with only one or two separate triggers. Or a number of scenes might all require that the same fairly complex state of affairs exists before they can play. In these situations, a story state can be used. A story state is a trigger that also represents that an important story-level state currently exists.

As an example of a story state serving as a precondition, a Discussion_Starts scene might activate a "discussion" story state trigger. This discussion state trigger may then recast certain events--such as the player character leaving the room or attacking another character--as ending the discussion state. But, the discussion state itself can also be a precondition for other discussion-related scenes that further or naturally conclude the discussion. This helps to simplify the authoring of the preconditions for these discussion-related scenes, as they do not need to perform all the tests needed to determine whether a discussion recently started and is still ongoing. Instead, they can simply check if the discussion state is active.

The following is a pseudo-code definition of such a discussion story state trigger. It has the same code structure as any other trigger, but it may also be used as a precondition for other scenes because it is a state trigger.

StateTrigger Discussion {

  // Set by the scene that originally provides this trigger, this variable
  // tells Marlinspike that any event recast by this trigger reincorporates
  // the given source event.  
  super.source = null  //Will point to the most recent Discusion_Starts event
  
  // Whether this trigger should be removed from the TriggerManager as soon
  // as it successfully recasts an event. 
  super.expire = true

  function recast(event) {
    if event matches Event(PC, import > 4, any, any, any, source.location):
      // Any significant action by the PC in the presence of the discussion
      // interrupts that discussion
      return new Event(PC, END_STATE, null, this, null, PC.location)      

    else if event matches Event(PC, TRAVEL, any, any, any, source.location):
      // Any departure from the conversation by the PC interrupts it
      return new Event(PC, END_STATE, null, this, null, PC.location)
    
    else if event matches Event(any, Discussion_Concludes, any, any, any, any):
      // A discussion may reach its natural conclusion through the appropriate scene
      return new Event(event.actor, END_STATE, null, this, null, event.location)      
  }
}
Example pseudo-code definition of a recasting story state trigger.

Similarly, a story state can also be used to represent certain roles filled by NPC characters. As an example, a scene might assign an NPC to the role of a Friend to the player character. This Friend role may then serve as a precondition or a hook for certain scenes. However, this role story state is essentially self-managing in that it recasts any conditions that would end the role--such as if the player severely affronts the Friend character.