SWAT TUTORIAL
HistoryBook Operators
The HistoryBook is an especially useful feature; it's a record of every Event that has taken place in the play of your storyworld. Think of it as "the history of the storyworld so far." You can look up Events in the HistoryBook to recall exactly what happened. Here are the Operators you can use:


EventHappened

This is a boolean Operator; it returns a simple yes-or-no answer to the question "Did the
Event fitting this description ever take place?" It takes a single argument, another boolean, that provides the description in proper form. Here's an example:

EventHappened
        AND
                AreSameActor
                        
ReactingActor
                        PastSubject of:
                                CandidateEvent
                AreSameVerb
                        
punch
                        PastVerb of:
                                CandidateEvent

This means, Has any Event ever happened in which the Subject was the ReactingActor and the Verb was "punch?" You may be a little confused by the use of "CandidateEvent." Remember, when we ask the Engine to look for "any Event," we are telling it to look at each and every Event to make a decision; that decision has to consider each Event individually. "CandidateEvent" is that "each Event individually." So we could expand the terse description above into the following more specific version:

Engine, I want you to examine each and every
Event in the whole HistoryBook. When you look at each Event, we'll call that Event you're looking at "CandidateEvent." Now, I want you to get the Subject and Verb of that CandidateEvent. If the Subject of that CandidateEvent is the ReactingActor, and the Verb is "punch," then return "true."

We also provide a handy little helper Operator: MainClauseIs. We learned in practice that many of our EventHappened Operators ended up looking like this:

EventHappened
        AND3
                AreSameActor
                        
ReactingActor
                        PastSubject of:
                                CandidateEvent
                AreSameVerb
                        
punch
                        PastVerb of:
                                CandidateEvent
                AreSameActor
                        
ThisDirObject
                        PastDirObject of:
                                CandidateEvent

Over and over again, we found ourselves specifying the Subject, Verb, and DirObject of the PastEvent. This became rather tiresome, so we came up with this handy-dandy little shortcut:

EventHappened
        MainClauseIs
                
ReactingActor
                punch
                ThisDirObject

This means exactly the same thing as the previous version, but it's a lot easier to use.

Why would you use
EventHappened? Normally you use it to check whether some Event has taken place that would be required for a later choice to be made. For example, suppose that you don't want the Prince to be able to rescue the Princess until after the Dragon has been slain? Then you might have an Inclination Script for the Option rescue looking something like this:


PickUpperIf
     EventHappened
          MainClauseIs
              
Prince
               slay
               Dragon
     Maxi
     Mini



LookupEvent

This is what you use to answer questions such as "Is this the same
Prop that the Subject used to hit the ReactingActor previously?"  Here is how it is typically used:

AreSameProp
   
This4Prop
    Past4Prop of:

        LookupEvent of:
            AND
   
            MainClauseIs
       
            ThisSubject
                    hit with
                    ReactingActor
                AreSameProp
                    This4Prop
                    Past4Prop of:

                        CandidateEvent

LookupEvent is found under the History Operators menu. 

Here's a fine point about
LookupEvent: it searches backwards from the present and stops at the first Event it finds that meets the specifications. This means that it will find the most recent Event that meets the specs.


CountEvents

This Operator answers the question "How many times has this happened before?" For example, you might want to have
Charlie Brown ask himself, "How many times has Lucy yanked the football away when I ran to kick it?" Presumably this would be used in a Script like this:

Offer to hold football: CharlieBrown: refuse to kick football: Inclination

Number2BNumber of:
        quotient of:
                CountEvents of:

                        MainClauseIs
                                
Lucy
                                yank football
                                Charlie Brown
                100

There are several important things to notice about this script.

First, note that the entire clause starts off with the Operator Number2BNumber. You might ask why we need this. If you'll recall from our tutorial on Attributes, all traits are BNumbers, and range from -1.0 to +1.0. Again, we do this to be sure we are always comparing apples to apples, and making it easier to keep our scripts contained within a similar range of values. But a storyworld's Events don't range between -1 and +1. They range from 0 on up to 100, 1,000 or more. To use CountEvents (or any regular number) in a script, we must first convert it to a BNumber.

Second, note that we divide CountEvents by 100, using the Operator quotient. This is basically saying that Charlie Brown is in fact capable of learning from his mistakes, albeit rather slowly. If we wanted to make him a quicker learner, we'd do this by making the 100 a smaller number—say, 10—or even eliminate the quotient altogether, and just have Number2BNumber of: CountEvents. Charlie Brown's inclination to refuse to kick the football would increase a good deal more rapidly in that case.


"Causal" tests

There is also a corresponding set of Operators that use a slightly different way of searching the HistoryBook. All the Operators above start at the current
Event and work backwards in time. "Causal" tests (CausalEventHappened, LookupCausalEvent, CountCausalEvents) only follow the chain of causality backwards. These tests ignore unrelated Events and look only at those Events that are directly in the chain of causality leading to the Event being reacted to. This is a more precisely targeted test that is necessary when you want to make sure that you're not fooled by an Event that meets your specs but is, by some strange chance, unrelated to the current Event.


ElapsedTimeSince

This is another rarely-used Operator; you use it to find out how much time has passed since an
Event took place. Example:

Offer donut: DirObject: accept donut: Inclination

Number2BNumber of:
        ElapsedTimeSince
                AND
                        AreSameActor
                                
ReactingActor
                                PastSubject of:
                                        CandidateEvent
                        AreSameVerb
                                
eat donut
                                PastVerb of:
                                        CandidateEvent
                        
The
ReactingActor's Inclination to accept the donut is proportional to how much time has passed since he last ate a donut(Notice that when counting time, as with counting Events, we have to convert the regular number to a BNumber in order to use it in the script.)


IHaventDoneThisBefore

This is a particularly useful Operator that is meant to obviate repetitious behavior. What's neat about it is that it's so smart. You can bury it inside a
WordSocket and it will look for matches right up to and including that WordSocket, but it will ignore anything beyond it. In other words, you don't have to specify the contents of the WordSockets; it automatically fills them in for you. That's probably confusing, so here's an example. Suppose that you are having a conversation with another Actor about a third party. You've been comparing notes about the various Attributes of that third party. You don't want to ask about an Attribute that you've previously asked about. You could do this with LookUpCausalEvent, but there's an easier way:

agree to talk: DirObject: gossip about: ActorAttribute: Acceptable

IHaventDoneThisBefore

That's all it takes! 
This Operator can only be used within an Option, so you will notice that it does not appear in the History menu under, for instance, AssumeRoleIf or Emotional Reaction scripts.


IHaventDoneThisSince

This is a variation on IHaventDoneThisBefore, but it adds a backwards time limit. It means "I haven't done this in the last X moments." 
As with IHaventDoneThisBefore, this Operator can only be used within an Option.



Previous tutorial:  Special Operators                                                                  Next tutorial:  More Special Operators