Script Core Commands

This file documents the core commands and features available to various scripting subsystems (AI scripts, instance scripts, quest scripts).

The script system is extremely simple and executes instructions based on preprogrammed commands which perform a specific task. A few conditional features are provided, but complex control structures may be difficult to achieve.

Detailed Command Reference
Directives and Metadata
Brief Command Reference

Comments

The semicolon (;) is used as a comment character. For any line of text, the first presence of a semicolon indicates that any following text is to be ignored by the compiler.

Statements

Only one command is allowed per line. Each command is divided into tokens (words, symbols, numbers). Each token must be separated by at least one space. Tokens themselves may not contain spaces. In special cases, strings are enclosed in double quotation marks ("). Strings may contain spaces, and count as a single token.

Commands

All instructions are created by specific commands. Commands have a limited number of parameters which are required to be a specific type. Instructions take only a few rudimentary values: integer, string, variable, integer list, and label.

Strings, variables, integer lists, and labels are typically assigned when encountered by the compiler and can be used in further instructions.

Integer

Integer values must be explicitly written in the script as a number. Variables cannot be used here. They are compiled directly into the instruction.

Strings

Strings are a line of text enclosed by quotation marks ("). Once loaded, strings cannot be changed.

Variables

Scripts only support very basic integer variables for storing information.

Variable names should not contain punctuation.

It is good practice to initialize them at the beginning of a script using the set command.

Variables are case sensitive. If call one VAR and another var, they are not the same.

Example:
set var 0 set varb 4

Integer List

Normally these are not used, except by a few specific commands. These contain a list of integers as an array. They follow the same naming and usage convention as variables but they are not interchangeable. If a command parameter asks for a variable, you may not use an integer list, or vice versa.

Labels

Labels are used for the goto and call commands.

When defining labels in the script, prepend a colon (:). Leave out the colon when using the label in a command.

Example:
:begin ; ... other stuff here goto begin

History

The Script Core system was heavily revised around June 2014 with the intention of expanding operations further, and unifying behavior across all subsystems. Previously it was a fragmented implementation of copy/pasted duplicate code, where each subsystem had its own modifications. Since development of the server halted shortly after, the changes hadn't been updated to the live server and did not receive large-scale testing.

Some of the new features added may not be fully functional, so be sure to thoroughly test any scripts which use them.

This includes the following commands: else (if/else/endif), iarrappend, iarrdelete, iarrvalue, iarrclear, iarrsize, queue_event, exec_queue.
And includes the following directives: #symbol, #queue_jumps.

Integer Arrays aren't really useful on their own, but were implemented because some augmented script commands required them, like creature searches that needed to return multiple results.

Command Reference

end
Halts the script. This command takes no parameters.
goto [label]
Unconditional jump. See labels for information on how to create and use labels.
:begin goto begin
reset_goto [label]
Similar to goto, but erases the call stack and var stack. Be mindful of any subsequent return operations as these will no longer work.

This command can be useful to reset execution and jump out of deeply nested control statements and call operations.
:begin reset_goto begin

print [string:text]
Print a line of text to the server log. Can be useful for debugging scripts by providing a messages in the log. Useful to evaluate the chain of logic if the script is halting or not firing conditional statements properly.
print "Checkpoint!"
printvar [variable]
Prints the variable name and its current value in the server log.
set trigger 5 printvar trigger
printappvar [string]
Rarely used. Prints an application variable in the server log. These are special internal variables which are programmed directly into the server, specific to a scripting system.
printappvar "var"
printintarr [intarr]
Prints the contents of an integer array variable in the server log.
iarrappend array 1
printintarr array
wait [integer:milliseconds]
Delays execution of the script for a certain amount of time.
wait 1000
inc [variable]
Increments the value of a variable by 1.
inc VAR
dec [variable]
Decrements the value of a variable by 1.
dec VAR
set [variable] [integer]
Set a variable to hold a specific integer value. Also useful for variable initialization near the beginning of a script.
set VAR 0
copyvar [variable:src] [variable:dest]
Assign the value of the source variable to the destination variable.
set VARA 0
set VARB 5
copyvar VARA VARB
getappvar [string] [variable:dest]
Cannot be used unless the script system is preprogrammed to support it.

Retrieves the value of an internal server variable and place the result into the destination variable.
getappvar "somevar" var

call [label]
Unconditional jump to a label. The current instruction position is pushed into the stack. Use the return command to return to last call position, and that position is removed from the stack.

Call commands may be nested to facilitate implementation of more complex logic or pseudo-functions. The stack is limited to hold a maximum of 16 return positions.

Every block of code jumped to by call must encounter a return command. It is strongly recommended that you do not use goto to leave the block. It may cause a stack overflow if a call is never completed.

In the event of a stack overflow or corrupted stack, script execution may become erratic or halt entirely.

Example:
:begin call subroutine ; stack +1 ; safely returns to the beginning, since the call stack is empty. goto begin :subroutine ; do stuff return ;stack -1

return [label]
Return control to next command following the previous call command.

See the call command for an explanation and example.

if [value] [comparator] [value]
Compare two values for a conditional jump. You may only compare between integers or variable names.

The following mathematical comparators are allowed: {=,!=,<,<=,>,>=}

Use endif to close an if block.

Recent changes Script Core allow nested if statements. Each one must be closed by a corresponding endif.

Also new, optionally you may use the else keyword to separate blocks for true or false. Only use one else per if block.

Other parameter types and complex expressions are not supported.

Example:
inc var if var >= 5 print "blah!" else print "nope" endif

endif
Closes the most recent if block. Each if should have a matching endif or else the script may not compile and run properly.

See the example for the if command.

iarrappend [intarr] [intstk]
[intstk] is a special parameter type which can be either an integer or a variable.

Appends a value to an integer array.

Example:
set VAR 2 iarrappend iarr 1 iarrappend iarr VAR

Produces an array of [1,2]

iarrdelete [intarr] [intstk]
[intstk] is a special parameter type which can be either an integer or a variable.

Removes an index (not a specific value) from an integer array. Arrays are indexed beginning at zero, so [0] is the first item, [1] is the second, etc.

Example:
iarrappend iarr 10 iarrappend iarr 20 iarrappend iarr 30 iarrdelete iarr 0

Produces an array of [20,30].

iarrvalue [intarr] [intstk] [variable]
[intstk] is a special parameter type which can be either an integer or a variable.

Find the of an integer array, at a specific index (zero based) and place the result into a variable.

Example:
iarrappend iarr 10 iarrappend iarr 20 iarrvalue iarr 1 VAR

VAR will now hold the value of 20.

iarrclear [intarr]
Erase all values in an integer array. The array will now have zero entries.
iarrsize [intarr] [variable]
Retrieve the size (number of elements) in an integer array. Place the result in a variable.
queue_event [string] [integer]
Queue an event for firing. The string is the label name to perform a jump or call to. The integer is time delay, in milliseconds, to wait before processing the jump. Use a time of zero for no wait. Make sure to use exec_queue to perform the actual jumps.

The queue has a hardcoded maximum of 16 events.

Example:
queue_event "Something" 0

exec_queue
Step through the list of any queued events, calling the first one that is available. Execution will immediately shift to that location. If there are multiple events ready to fire, only one will be triggered. This function is best used in the main loop.

Example:
queue_event "event" 5000 :main exec_queue goto main :event queue_event "event" 5000 return

This example initially queues up an event to trigger in 5 seconds. When the event is called, it adds itself back to the queue, triggering it every 5 seconds indefinitely as long as the script is running.

pushvar [variable]
Push the value of a variable to the stack. Normally this command is used internally, but is available for specific use. You must use pop to remove the item from the stack, or else it will remain resident and possibly cause problems down the line.

The stack only holds 16 elements, and other functions like if use the stack as well.

pushint [integer]
Push an integer value to the stack. See notes for pushvar.
pop [variable]
Remove the last element from the stack and place its value into a variable.

Example:
pushint 5 pop VAR

VAR will now be 5.

Directives and Metadata Information

These are not instructions, but signal certain global features that are assigned during the compilation phase. They help control how the script compiles or executes, in the ways that the server program itself accesses and controls the scripts from outside the script itself.

#name [string]
Identifies the script by giving it a name. For easy organization, the name should match the file name. Use this name when assigning AI scripts to creatures via the CreatureDef ai_package property.

Example:
#name 4_druid_melee_30

#symbol [string:alias] [string:actual]
Creates a compile-time symbol alias. When the compiler reads a line, it will compare each token to the symbol table. If the match is found in the symbol table, it will replace that token with associated actual token.

Example:
#symbol BASH 288 use BASH

This example is used in the context of an AI script. When the compiler encounters BASH, it will automatically substitute 288 (the ability ID). So the lines
use BASH use 288 compile into the same instruction.

#speed [integer]
Sets the execution speed of a script, as instructions per frame.

Every cycle (or frame) of the server will process a certain number of instructions to avoid consuming too much CPU power, especially in the case of infinite loops.

This is most commonly used in more intricate scripts that contain heavy use of conditional branches, jumps and calls. The common if command compiles into three instructions which set up the data before the comparison is made. These conditionals can have a major impact on the total number of instructions, and thus increase the number of server frames which are required to run a full cycle of the script. Detailed AI scripts in particular will run noticeably slower, and will require a higher #speed allocation to help them run more smoothly, and react faster.

Example:
#speed 10

#idlespeed [integer]
Like #speed, but sets the idle execution speed. The default is set to zero (the script will not run when idle).

This field is of particular use to AI Scripts. Refer to the AI Script documentation for details.

Example:
#idlespeed 1

#queue_jumps [string]
This controls how external jumps are handled by the script. This is important when using the queue_event and exec_queue instructions.

The string can be one of two things "call" or "goto". Using call means that exec_queue will interpret the jump as a call instruction to the appropriate label, requiring a return to unwind. Using goto means that the jump will be interpreted as goto and will require another goto to jump back.

By default, queued jumps are set to false and the call style is set to "call". Using queue_jumps sets queued jumps to true. Queued jumps determine how the server handles explicit jumps to labels within the script.

For instance scripts, when mobs are killed it will generate a label name based from the mob type. If the label is found in the script, the script will jump to that label to perform any creature-specific processing, like tracking step-up spawns.

If queued jumps are false (the default state), then the jump will be abrupt, interrupting any prior execution chain, and clearing and the variable and call stacks.

If queued jumps are enabled, the script will resume execution as normal (finishing whatever operation it was currently doing). However, the script must have exec_queue in its main loop to process the jump, otherwise nothing will happen.

A maximum of 16 events may be queued at once.

Examples:
#queue_jumps goto
OR
#queue_jumps call

#flag [string] [integer]
Enabled debug flags for script execution. The string can be one of the following properties:

report_end report_label report_all

The value can be set to 1 to enable, or 0 to disable, although flags are disabled by default.

If report_end is activated, a debug message will be printed when the script ends.
If report_label is activated, a debug message will be printed if a requested jump label doesn't exist in the script.
report_all will activate both flags.

Example:
#flag report_end 1

Quick Command Reference

A brief overview of the commands. Here is an explanation of abbreviations here:
var = Variable Name
int = Integer
intarr = Integer Array Name
str = String ("enclosed in double quotation marks")
label = Label Name
intstk = Integer value, accepted either as a [var] name or plain [int] number.

end goto [label] reset_goto [label] print [str] printvar [var] printappvar [str] printintarr [intarr] wait [int:time in milliseconds] inc [var] dec [var] set [var] [int:value] copyvar [var:source] [var:destination] getappvar [string:name] [var:destination] call [label] return iarrappend [intarr] [intstk:value] iarrdelete [intarr] [intstk:index] iarrvalue [intarr] [intstk:index] [var:destination] iarrclear [intarr] iarrsize [intarr] [var:destination] queue_event [string:label name] [int:delay in milliseconds] exec_queue pushvar [var] pushint [int] pop [var:destination]