Travel Actors

TravelActor is a mix-in class that enables an ordinary actor to traverse the travel graph of the game world in an automated fashion. Travel is accomplished through a two-step process. First a logical path from the actor’s location to the desired destination is computed using Dijkstra’s shortest paths algorithm; then a daemon generates a series of actor commands that attempt the actor’s physical traversal along the path. Course corrections are made when necessary when the physical traversal fails.

 

TravelActor utilizes the actor’s knowledge of the game world, specifically the travel graph, in order to compute a path to the destination, and in choosing the appropriate direction to take to reach a given location. When physical traversal from one location to another is blocked, or the chosen direction does not lead to the location the actor thought it would, the corresponding vertex and edge are noted in the actor’s travelEdgeMemory along with the results of the attempted edge traversal.

 

At the end of each call to the actor’s travelDaemon(), a call is made to the actor’s travelScript() method, passing it a vector of the results of the calculations that occurred during that call.

 

In this way, TravelActor makes use of its knowledge both in where it has been previously and what happened to get where it currently is; as well as where it is going, and how to choose a route to get there.

 

Defining a TravelActor

It’s as simple as defining any other actor. Below is the definition for Joe, our brave little explorer.

 

joe: TravelActor, Person

{

    'joe' 'Joe' @livingRoom

 

    isProperName = true

    isHim = true

    obeyCommand(issuer) { return true; }

    wantsFollowInfo(obj) { return true; }

}

 

This isn’t any different from an ordinary actor’s definition might be, except that Joe inherits from the TravelActor mix-in.

Initiating a TravelActor

A TravelActor is driven by a daemon, which should be set at the beginning of the game. The initiateTravelActor() method let’s you do this, as well as setting up the initial travel destination list. The method also lets an author call the TravelActor’s runActor() method prior to the creation of the daemon, if desired. If the actor is initiated before runGame() is called this has the effect of starting the actor in motion when the actor’s commands are executed on the first turn, rather than waiting for the second turn.

 

       joe.initiateTravelActor(true, shed);

 

Now Joe will be setup with a daemon to execute his runActor() method each turn, and a travel destination list that contains the shed. In addition, the first argument, true, will cause the actor’s runActor() method to be executed at this time, and a dijkstra path from the actor’s location to the shed will be computed, a direction chosen, and the appropriate command placed in the actor’s command queue to be executed that will attempt to move him to the next location along his path.

 

By issuing the same command with a nil preTurn argument we postpone the computation, selection, and issuing of the command until the daemon triggers, which will mean our actor won’t attempt to move to the next location until his command queue is executed on the next turn.

 

It’s important to note this distinction of the travel process:

 

Actor travel occurs when its command queue is processed.  Actor travel commands are generated by the runActor() method, which is driven by a daemon.

 

 

Terminating a TravelActor

Although the daemon should normally run continuously throughout the duration of the game, the terminateTravelActor() method will stop the actor and remove its daemon from the eventManager.

 

                joe.terminateTravelActor();

 

To restart Joe after termination it will be necessary to call his initiateTravelActor(). Issuing multiple initiateTravelActor() and terminateTravelActor() commands can lead to stack overflow errors. To avoid this the TravelActor provides methods to temporarily pause it while its daemon is active.

Starting a TravelActor

Once a TravelActor has been initiated an author should use the startActor() and stopActor() methods to temporarily pause and restart the actor.

 

                Joe.startActor();

 

All this method will do is set Joe’s status to active, so that it’s daemon will proceed to process its travel destination list.

 

Stopping a TravelActor

To temporarily pause a TravelActor an author should call its stopActor() method. This will set the actor’s status to inactive, and all processing of its travel destination list will be halted. This will not stop the actor from attempting to process any travel commands pending in its command queue, but will simply stop it from issuing any further commands.

 

The Travel Script

The runActor() method calls doTravelScript() right before it exits, if the actor is active. This allows the actor a chance to perform special actions before its command queue gets executed on the next turn.

The Travel Log

A log of the runActor() decision-making process is created in the form of a Vector of TravelActionInfo objects. The log is built sequentially through runActor() processing and provided to the actor’s doTravelScript() method. This gives the actor a chance to know what the outcome of its previous travel command was, as well as information regarding the next travel command to be executed.

 

A typical log might look like this:

 

Travel Script Value : TravelEdgeSuccess

       travelDest:    Tunnel

       currTravelNode: Living Room

       nextTravelNode: Den

       travelEdge:    east

       location:     Den

—————————————————-

Travel Script Value : TravelCmdIssued

       travelDest:    Tunnel

       currTravelNode: Den

       nextTravelNode: Top of Stairs

       travelEdge:    north

       location:     Den

—————————————————-

 

What this indicates is that travel was successful when the actor moved east from living room to the den. Next a travel command was issued to the actor’s command queue to move north from the den to what the actor believes will be the top of the stairs.

 

Meanings of Travel Log Values

The following table gives the meanings for the travel log values:

 

Value

Meaning

StartOfList

The actor is at the start of a new path

EndOfList

The actor has reached the end of the travel destination list

TravelCmdIssued

A travel command has been appended to the actor’s command queue

TravelEdgeSuccess

The actor has succeeded in getting to its next location (without previous failure)

TravelLinkSuccess

The actor has succeeded in getting to its next location (after having previously failed)

TravelDestSuccess

The actor has reached its destination

TravelEdgeBlocked

The actor failed to reach the location by the direction it has taken

TravelLinkBlocked

The actor is prevented from going to its next location by any known direction

TravelNodeBlocked

The location the actor was attempting to travel to (along its way to its destination) was blocked along each avenue

TravelDestBlocked

The destination is blocked along each avenue

TravelEdgeFailure

The actor didn’t reach the location it thought it would when it traveled along this direction

 

 

This file is part of the TADS 3 Proteus Library Extension

Copyright © 2001-2004 Kevin Forchione. All rights reserved.