AI scripts are written in C-like language. Comments are specified using two slashes (//
). The purpose of a script is to specify decisions for a state machine on a group. Each group can have different variables and functions, which can only be affected via code.
Variables do not need to be defined before they are used, as they are automatically created with a value of 0 or "". Variables can be floating point numbers (no prefix), character strings ($
prefix), or script contexts (@
prefix).
There are two special objects that can be used to call a function:
parent
: represents the parent group of the current groupcaller
: represents the group that called a function on the current groupAdditionally, one can reference any static group defined in the same AI instance by its name. The usage is similar to that of parent
and caller
. In fact, parent
, caller
, and group names are a kind of pseudo-contexts and can be used as such (without the @
prefix).
There are two special functions for debugging and logging:
print()
: used for debugging purposes, removed in release modelog()
: used to display any information that should be read in release modeThe syntax for these functions is:
print("foo");
log("bar");
You can put any number of const strings (e.g. "toto") and variables (floating point numbers or strings) separated by a comma. All the string representations are concatenated to form the final string.
For example:
print("My position is ", x, ":", y);
You can dynamically define functions on the group. These functions are called script functions or user functions (as opposed to the hard-coded "native functions").
User functions do not have parameters.
Functions can be defined like this:
my_function()
{
print("message"); // print a message
myvar = 5 * myvar; // the variable myvar is now equal to myvar * 5
caller.myvar = myvar; // the variable myvar of the caller is now equal to myvar (see below for more explanation)
}
You can call a function like this (note that if a function is not defined for a group, nothing is called):
my_function(); // call my_function from this group
group1_tryker.my_function(); // call my_function for group1_tryker (inside this function the current group is accessible via the `caller` keyword)
Some simple mathematical operators can be used: +, -, /, * with or without parenthesis.
For example:
myvar = (5 * myvar + 1) / 3;
Note that the negative operator should be used with caution. You MUST add a space after the "-" symbol.
You can do comparisons with variables and/or numbers (can be used for if and while statements). Note that you cannot do mathematical computation inside the if parameter (you cannot write if (x+10 < 20)
).
For example:
myvar = 10;
if(myvar < 10)
{
...
}
In the above code, we could replace caller
with parent
, which is another keyword that indicates the parent of a machine state. The parent/children relation is defined for dynamically spawned groups (see below native functions).
while
, if
, else
can be used as in C.
onchildren
ConstructThe onchildren
special construct allows you to execute a script block on all the children of the current group.
onchildren()
{
...
}
random
ConstructThe random
special construct allows you to execute a block of code randomly among several blocks. One instruction in the block following the rand
keyword is chosen and executed. This instruction can be a block, in which case the whole block is executed.
random()
{
block1();
{ // Block2 begin
print("foo");
} // Block2 end
(bar)block3(baf);
}
Native calls provide hardcoded services to the scripter and have input and output parameters, also known as arguments and return values. The syntax for calling a native function is as follows:
(destVar1,destVar2)nativeMethod(paramVar1);
This example calls the nativeMethod
function for the current group. The left parentheses define the output arguments, and the right parentheses define the input arguments.
If a function call does not have return variables, the return parentheses can be omitted entirely:
anotherNativeMethod(paramVar1);
For more information on the available native built-in AI script functions, see the AI Script Function Reference document.
Here's an example of a simple code block written in AI script:
(aggroSize)getAggroListSize(0);
// If too many players are attacking the boss
if (aggroSize > 10)
{
($player1)getAggroListElement(0);
($player2)getAggroListElement(1);
($player3)getAggroListElement(2);
// The boss teleports 3 players from its aggro list to the end of the world
teleportPlayer($player1, 14233, 123123, 0, 0);
teleportPlayer($player2, 14233, 123123, 0, 0);
teleportPlayer($player2, 14233, 123123, 0, 0);
clearAggroList();
}
When adding an event action handler, choose the code
type, then write the code to be run.
In the World Editor, you can create AI script templates using the script_rep and script nodes. This allows you to define reusable code segments that can be used in AI actions. Here's an example of the script node and properties: