Variables
From WarCraft3
Variables are one of the key features in any programming language, and Jass is no exception. Jass includes global and local variables, and also arrays are available. There are 6 primitive types and a multitude of in Jass.
Contents |
Local Variables
Local variables are specific to both to the function they are declared in, and the instance of the function. This means they cannot be directly accessed from outside the function, and if there are several instances of the same function running, their local variables will not collide.
Declaration
The syntax to declare a local variable is the following:
local <type> <name> [= <value>]
local <type> array <name>
where the parts inside square brackets are optional. <type> is the type of the variable and <name> is the name it will be referred as. The name can contain numbers, alphabetic characters, and underscores with the restriction of not being allowed to start or end with an underscore nor start with a number. The <value> is optional and can only be used for non-array decelerations.
Examples
local integer myInt
local unit caster = GetTriggerUnit()
local real array reals
Discarding
The agent types in Jass are reference-counted. This means that whenever a variable is set to point to an agent, this agent's reference counter is increased by one, and when a variable pointing to an agent is set to point to something else, the agent's reference counter is decreased. If an agent's reference count is not 0, its handle id and memory cannot be freed.
The reference counter of an agent should also decrease when a local variable pointing to it disappears (i.e. when the function instance it was created in ends), but due to a mistake by Blizzard, this doesn't happen. As a result of this, most agent types1 need to be nulled2 before the function ends, as not doing so would lead to the agent's reference counter never reaching 0, thus its memory and handle id staying reserved even when the agent itself is destroyed, creating a memory leak. If the value of a local handle variable is returned, it is not and cannot be nulled. To prevent a leak, a global variable should be set to the local variable, the local variable nulled, and the global variable returned instead.
Explanations
1: Agents that cannot be destroyed, for example playerstate and player, do not need to be nulled. This is because their memory and handle ids will never be freed anyway, as they will not be destroyed. However, nulling variables of these types will not harm in any case, so when unsure of whether an agent should be nulled or not, null it.
2: "Nulling" means simply setting the variable's value to null;
set u = null
Global Variables
Global variables are somewhat different to local variables in the sense that they can be used everywhere and anywhere. However, they are not function specific, and can be easily overwritten (which can be an issue when trying to achieve MUI).
Declaration
Globals are declarated in a globals block at the top of the map's script (and also at the top of common.j, Blizzard.j, and AI files). However, this block is not reachable by a regular mapper, so there are two different ways for the mapper to declare them, one requiring a third-party tool.
Variable Editor
The regular way of declaring globals is the same as in GUI; using the variable editor. These variables will be prefixed with the letters udg_, so for example naming a variable MyInteger will result in it being usable with the name udg_MyInteger in the Jass code.
The advantages of using the variable editor to create global variables are that it can be used without third-party tools and that these variables can be used in GUI without custom script lines. The disadvantages are that not all types are available, they are harder to organize, and are slower to create (clicking is generally slower than typing).
Setting the 'Size' field in the Variable Editor when creating arrays will not actually change the array's size, but rather generate a script that'll automatically initialize the slots from 0 to <size> with the value in the 'Initial value' field. This script will be placed in the function InitGlobals, which is called by main.
Freeform Globals Declaration
vJass makes the coder able to declare globals blocks anywhere in the code except inside other globals blocks. These blocks' contents will be moved inside the map's globals block by JassHelper. The syntax for declaring globals using the globals block is the following:
globals
<type> <name> [= <value>]]
constant <type> <name> = <value>
<type> array <name>
endglobals
where the parts inside the square brackets are optional, <type> is the type of the variable, <name> is the name it will be referred as, and the optional <value> the value it will be initialized with. The name can contain numbers, alphabetic characters, and underscores with the restriction of not being allowed to start or end with an underscore nor start with a number.
The keywords constant and array cannot be used for the same global (see arrays for further information). The keyword constant makes the variable's value not able to be changed, i.e. the variable becomes constant. Constant variables have to be initialized with a value in their declaration.
Examples
globals
real MyReal = 13.37
constant MY_INTEGER = 1337
unit array Units
endglobals
Though locals and globals have their differences, they also have their similarities in usage, functionality, and syntax.
Setting Values
The syntax for setting values to locals and globals is the exact same,
set <name> = <value>
where <name> is the name of the variable whose value will be changed, and <value> is the new value.
Examples:
set myInt = 7
set u = GetTriggerUnit()
set u = null
Arrays
Arrays are sort of two dimensional variables (like a list). The variable name is followed by [<index>], where <index> is an integer between 0 and 8191 (inclusive). That array can hold different values in different indices.
Unlike all other variables, arrays are automatically initialized with a default value. The default value is 0 for reals and integers, false for booleans, and null for everything else.
Arrays have some special restrictions in their declaration syntax. First of all, they cannot be initialized with a value, as arrays consist of several values. If one wants to initialize them with some other value than their default value, they will have to do so in some function, looping through the array's slots. And leading from the second, as arrays cannot be initialized with a value in their declaration, they cannot be constant, as constant variables have to be initialized in declaration. Additionally, the primitive type code cannot be used with arrays.