VR-Forces 5.1 Lua Function Documentation

behaviorEngine

(For high level concepts about how to use Lua to write scripted tasks, please see VR-Forces User's Guide.)

This package implements a behavior engine aimed at supporting unit behaviors, or "commands." These commands are invoked and executed the same way all Lua task scripts are.

This file should be included in a behavior script with
require "behaviorEngine"
It provides several functions and implements the standard callbacks init(), tick(), saveState(), and loadState(), so they are not needed in the behavior script.


Usage

A task script that uses the behavior engine will generally be organized as follows:

  • Define global constants
  • Define utility functions
  • Define roles in a Role List.
  • Define a top level behavior node, with nested behavior nodes, that together define the command.
  • Call defineBehavior, passing the Role List and Top Node as arguments.
Note that there should be no init, tick, saveState, or loadState functions defined in the task script.

Role List

Roles are defined in tables and combined in a list (table). Each role has elements as follows:

name
The name of the role. This will be matched with a role string in a parallel action in the behavior.
types
A list (table) of strings that define object types. Subordinate entity types must match one of these strings to be assigned this role.
isCritical
(Optional, default false.) A Boolean which, if true, means that the behavior fails if no subordinate can be matched to this role; and the behavior fails if a parallel action for this role fails.
maxInstances
(Optional, default 1.) The maximum number of subordinates that can execute this role.
scoreFn
(Optional, default score is 0.) A function that takes three arguments: a subordinate object, the index of the subordinate in the _subordinates table, and a string containing the function of the subordinate. Returns a score: < 0 if the subordinate should not be assigned to the role; 0 if it should be assigned only when no + scoring subordinate is available; and a value > 0 otherwise that indicates the desirability of the subordinate for the role.

Behavior Node

A Behavior Node is either a primitive action or a module with "child" nodes. Different module types define different ways that children are selected and executed. A behavior is a tree of nodes with primitive actions at the leaves.

A node can be one of the following types:

  • sequence
  • parallel
  • selector
  • role
  • loop
  • task (leaf)
  • conditional (leaf)
  • job (leaf)
  • sync (leaf)
  • send (leaf)
  • receive (leaf)
  • query (leaf)

Behavior Node Definition

Each node is defined in a table with key value pair entries. Every behavior node can have the following entries:

nodeType
(Required) A string defining the type of the node. Must be one of the types listed above.
name
A string that is useful mostly in debugging output. Required for sync nodes; all sync nodes that are synchronized with each other must have the same name.
initFn
A function that takes a Node as an argument. No return value. Run after the node is created, but before any other function is called.
startWhen
A function that takes a Node as an argument. Returns a Boolean. When it returns true, node execution can begin.
endWhen
A function that takes a Node as an argument. Returns a Boolean. If this function is true, the node stops any running actions and ends (with success status).
failWhen
A function that takes a Node as an argument. Returns a Boolean. If this function is true, the node stops any running actions and ends with an fail status.
exitFn
A function that takes a Node as an argument. No return value. Run after the node finishes running, either with success or failure.

In addition, some nodes have special entries:

children
sequence, parallel, and selector nodes-- a table containing node definitions.
child
loop, role nodes -- a node definition.
doWhile
loop nodes-- a function that takes a Node as an argument. Returns a Boolean.
successPolicy
parallel nodes -- a string, either "one" or "all". How many children have to complete with success for the parallel node to finish with success. The default value is "one".
letAllFinish
parallel nodes -- boolean. True indicates that the parallel node will not be be finished until all children have finished. False indicates that the parallel node can finish as soon as its completion status has been determined. The default value is True.
role
role nodes -- a string that matches a role name in the role list.
task
task nodes -- A function that takes a Node as an argument. Returns an integer that is normally a VRF task handle, i.e. the return value of a vrf:sendTask() or similar function. A value of -1 indicates an immediate failure; a value of 0 indicates an immediate success; and any other value indicates that the VRF task is running.
condition
conditional nodes -- a function that takes a Node as an argument. Returns a Boolean.
job
job nodes -- a function that takes a Node as an argument. Returns a Lua Async Job object. (See Async Job documentation.)
mode
selector nodes -- a string, either "reactive" or "fallback". Indicates whether the selector attempts to tick all children every tick (to implement prioritized reactive behaviors) or whether it starts by ticking the currently running child node (to implement fallback behaviors).
messageType
send and receive nodes -- a string specifying the type of message to send or receive. Either an object message type, or "text" for plain text messages. Receive nodes can also use "all" to accept all message types. Defaults to "generic-table".
sendTo
send node -- can be one of three things:
  • simObject
  • string. A string must have the value "unit" or "subordinates".
  • function. Function takes a node for an argument and must return a table of simObjects.
messageFn
send node -- a function returning either a table (for object messages) or a string (for text messages). Takes a node as an argument.
sender
receive node -- Optional. can be one of three things:
  • simObject
  • string. A string must have the value "unit" or "subordinates".
  • function. Function takes a node for an argument and must return a table of simObjects.
If not specified, messages from all senders will be accepted.
acceptFn
receive node -- a function for processing messages returning true, false, or nil. Generally processes a message using the node.result() function. True makes the node return "success", false makes the node return "fail", and nil leaves the node "running".
query
query nodes -- A table that specifies the query. The table must have the following elements:
title
A string that will be the title of the query.
message
A string that will be the query itself.
options
A table whose items are strings. These are the answers from which the user may select.
displayStyle
An integer specifying how the options will be displayed. 0: as series of buttons; 1: radio buttons; 2: a combo box.
timeOut
query and receive nodes -- A time duration to wait for the user to respond to the query. If there is no response in this time, the query is canceled (and the node returns success).

A maximum time after the receive node is first ticked or has received a message before the next message must be received. If this time is exceeded, the node returns "fail".

Behavior Node Functions

Several entries in the behavior node definitions are functions that take a node as an argument. A node has several member functions that can be called to get context information. These functions are called with the node parameter as a reference, e.g. node.subordinate().
subordinate()
Returns a simObject -- the subordinate running this node; or nil if this node isn't under a role node.
instanceN()
Returns an integer -- the instance number in the role (above this node).
setRoleStateVar(varName, value)
varName is the name of a variable (string), and value is any Lua value. Sets the given state variable in the environment that is private to this role and this instance of that role. (See State Variables, below).
getRoleStateVar(varName)
Given the state variable name (a string), returns the value of that variable in the role-instance environment
status()
The current status of the node, which is "created", "waiting", "running", "success", or "fail". Generally, behavior code should not need to access the status.
result()
Job, query and receive nodes only. The result object returned by the async job or query. For jobs, the result will be nil until the job completes and the node goes to "success" status. For queries, the result is -1 until the user answers, and then it is an integer corresponding to the choice made. The first choice is 0. Fo receive nodes, this function returns the message received.

State Variables

There is a global table for state variables. These global state variables are accessible to any Activity Block or Action in the behavior. They are saved in a scenario save. To set and access them, use the functions setStateVar() and getStateVar() (see below).

Under each role node, there are additional tables set up that are private to that role, and to the instance of that role. Functions in nodes in these parallel actions can set and access variables using the functions setRoleStateVar() and getRoleStateVar() (above).

Graphical Status Output

The behavior engine generates a graphical view of the behavior tree that can be seen in the Tasks tab of the Information Panel for an object. For more information about the graph, see the VR-Forces User's Guide.

Function List

createObjectMap () Creates a table that can have simObjects as keys.
defineCommand (args) Define the behavior command.
getStateVar (variable) A convenience function to get the value of a state variable.
isRoleCritical (roleName) Indicates whether the given role has been defined as critical.
roleForSubordinate (subordinate) Returns the name of the role that the given subordinate has been assigned.
setStateVar (variable, value) Sets the entry "variable" in checkpointState.
subordinatesAssignedToRole (roleName) Provides a list of subordinates that have been assigned to the given role.

Table List

_subordinateFunctions A table with subordinates as keys and subordinate functions (strings) as values.
_subordinates A list of the subordinates of this entity.


Functions

createObjectMap ()
Creates a table that can have simObjects as keys. Since simObjects are USER_DATA, when used as keys, a normal table only works properly if a lookup is made using the same USER_DATA-- i.e., address in memory-- as the key. USER_DATA will change on every rewind or scenario load. However, if createObjectMap is used to create the table, then UUIDs will actually be used as the keys, and table lookups will work even after a scenario reload. The table will have a field __isObjectMap in it set to true to mark it for scenario saves.

Usage:

    checkpointState.objectLocations = createObjectMap()
    checkpointState.objectLocations[this] = this:getLocation3D()

Return value:

    A table that expects to have simObjects as keys.
defineCommand (args)
Define the behavior command.

Parameters:

  • args: is a table with two elements, args.subordinateRoles and args.topNode. The first argument is a Role List, i.e. a table containing role definitions. The second argument is the description of the top level activity block. Note that using Lua's "{}" notation, this function can be called with key value pairs. Returns true if successful, false otherwise.

Usage:

     defineCommand{subordinateRoles = myRoles, topNode = commandDefinition} 
getStateVar (variable)
A convenience function to get the value of a state variable.

Parameters:

  • variable: A string, the name of the variable.

Return value:

    checkpointState[variable]
isRoleCritical (roleName)
Indicates whether the given role has been defined as critical.

Parameters:

  • roleName: (string) A role name.

Return value:

    true if the role is critical.
roleForSubordinate (subordinate)
Returns the name of the role that the given subordinate has been assigned. If the behavior hasn't been assigned a role, or if the entity running this behavior doesn't have subordinates, then nil is returned.

Parameters:

  • subordinate: (simObject) The subordinate of interest.

Return value:

    role (string) The role assigned to the subordinate
setStateVar (variable, value)
Sets the entry "variable" in checkpointState. The calling code could do this directly; however, using this function causes an update to the output used for the html Inspector.

Parameters:

  • variable: A string, the name of the variable.
  • value: The value to set.
subordinatesAssignedToRole (roleName)
Provides a list of subordinates that have been assigned to the given role. The subordinates are listed in order; i.e. the first one will be assigned instance 1 of that role, the second to instance 2, etc.

Parameters:

  • roleName: (string) A role name.

Return value:

    List (table) of subordinates (simObjects) that have been assigned to the given role.

Tables

_subordinateFunctions
A table with subordinates as keys and subordinate functions (strings) as values. Computed using getSubordinateFunctions().

_subordinates
A list of the subordinates of this entity. Computed using getSubordinates(true).

Copyright© 2024 MAK Technologies, Inc. All rights reserved.