Triggers - Variables and Arrays

Tutorial By Laika.

Variables & Arrays

Variables & arrays are a necessary part of programming and knowledge of them is very helpful. Many people on this forum have had conciderable trouble understanding and using variables & arrays, so I have to decided to write this in-depth guide to alleviate this confusion.

All variables can be created in the World Editor from the Variable Editor, which is found in the Trigger Editor window.


What is a variable?
In the loosest sense a variable is something that can change. However in programming a variable is something slightly more specific than that. A variable allows you to save information for use later. Like a labeled filing cabinet, you give the variable a name (label) and then put something (data) inside it to be looked at again later.

All variables have the same parts:

Type Name = Value

Type: This is the type of your variable, all variables can only hold one type of information. Only certain types of things can fit in our cabinet and this is what kind of stuff will fit.
Name: This is the name of your variable. By using this name in your program it is the same using the information inside. This is the label of the cabnet, instead of telling the program "get the scissors" you can tell it "get what is inside the cabinet labeled Name"
• Value: This is the information that is stored by the variable. This can also be an expression, variable or function that gives a result of the correct type.

Here's a quick example:
Let's make a variable! We will make its type "Integer" (whole numbers) Its name will be "Fish" And its value will be "7.4"... Wait a second we can't do that! Its value (7.4) isn't the right type, it's not a whole number. So that won't work. Instead we will make its value "13". Now, in a trigger we could say: 13+7 OR Fish+7 and we will get the same answer: 20!

Basic Uses:
What good does a variable do us?
Variables allow us to include things in our triggers when we don't necessarily know what they are. Does that sound a little weird? It may, but we do it all the time.

There are so many uses for variables there is no way to list even a fraction of those here, instead here is a simple guideline for when to make something a variable:

If you use something in your triggers that you expect to change over the course of the game, or if you want to store a value for use later: Make it a variable!

To tell the variable what information to hold you can either enter a value in the 'Variable Editor' or use the Action: Set Variable.

Advanced Uses:
Here are some more uses for variables:

If you use a value over and over again in your triggers, consider making it a variable so that if you ever decide to change it, you only have to change it in one place.

[More to be added]

Additional Info:
Here are the common type of variables found in the WC3 engine and tips for choosing the correct type:

• Integer: Whole number.
• Real: Number with decimal point.
Note:Some values (HP, MP, etc) must be a "Real" while others must be an "Integer".
• String: A sentence like this, also it can be 'null' (0 letters long).
• Boolean: Either TRUE, or FALSE.
• Item: A single unique item on the map.
Note: An example of this is, even though there are many apples around, an Item variable refers to only one unique apple.
• Item-Type: This refers to a type of item.
Note: This is a generic item of a type, like apple. Use this type of variable for creating items.
• Item-Class: This refers to a set of items of a certain level (1-8) and category (permanent, charged, etc).
• Unit: This refers to a single unique unit on the map.
Note: This type is like Item. Example, even though there are many footmen an Unit variable only refers to one of them.
• Unit-Type: This refers to a type of unit, like footmen or Archmage.
Note: Use this type of variable for spawning units.
• All the rest of the types of variables are either self explanitory or seldom used.

[More to be added]

Techical Information & JASS:
This is information for those who desire a more technical understanding.

The types: Integer, Real, String, Boolean, Code, and "Handle" are considered 'native' types in JASS. All other types of variables are derived from "Handle" and are defined in WC3 itself. Handle is basically a pointer to the internal data structure. Code is a type that references another function and is seen mostly in functions dealing with triggers.

Variable scope is where we can use a variable from. There are two main scopes: Global and Local. Global variables are defined in the begining of a JASS script (see below) and can
used in any function (trigger) in the code.

globals ... type name = expression type name = expression ... endglobals

Local variables are defined when a function is called and can only be used from that function.
function... local type name = expression ... endfunction

Local variables are useful in writing a function that may be called many times quickly, because gobal variables would be overwritten each time the function in run, while a local variable is indepent of how many other triggers (even the same one) are running.


What is an array?
Arrays are a powerful programming tool that allow the creation of more dynamic and simplified code. Once you understand their structure and usage, creating 'complicated' triggers will be well within reach. Just like a variable, arrays store data within them. Except that while a variable is like a cabinet, an array is more like a book with many pages. Each page has a number and that number is called an index.

An array is a simple thing, and all arrays have the same format:

Type Name[Index] = Value

Type: This is the type of the array, just like the type of a variable this deterimines what can be stored in the array.
Name: The name of your array, much like the name of a variable.
• [Index]: The index is always contained within brackets "[ ]" and is always a positive integer (1, 2, 3, 4...). Also it may be any expression, variable, or function that returns a positive integer.
• Value: Is the value of the array at the specified index (more on this later), and its type is always of the same type as the array.

Basic Concept and Use:
An array is very much like a list of variables, and each one has its own number (index). But why would you want to use an array over a group of variables?

One common use for arrays is organizing information by player number. Here a common example to illustrate this point:
Let's say we want to keep track of the number of kills for each player. We could make an integer variable for each one: Player1_Kills, Player2_Kills, Player3_Kills,... Or we could make an integer array: Player_Kills[] We can think of this array like a table INDEX | VALUE 1 | ? 2 | ? 3 | ? .. | .. Now, by choosing what index to change the value at, it would be like choosing what variable to change if we weren't using an array. i.e: Player_Kills[1] = Player1_Kills Player_Kills[2] = Player2_Kills Player_Kills[3] = Player3_Kills ... This doesn't seem to much easier, except now we can have a function choose the index for us, allowing us to simplify what could be many triggers into one. #Kill Counter #Events: A Unit Dies. #Condition: ((Dying Unit) is a Hero) equal to TRUE #Actions: #//Find out the Player Number of the Killing Player #Set Player_Killer_Num = (Player Number of (Owner of (Killing Unit))) #Set Player_Kills[Player_Killer_Num] = Player_Kills[Player_Killer_Num] + 1

To tell an array to hold information you may only use the Action: Set Variable, remember to put in something for the index!

Advanced Uses:

A map is simply a way of linking two things together, typically something that doesn't follow a patern. Other programming languages offer a more flexible way of doing this, however in the limited environment of Warcraft 3, this will have to suffice. As long as there is a way to recude one of the elements to an integer (for use as the index) you can link them together.

Here's a simple example using only integers:
Let's say we're making an ability with 4 levels and we want to have it deal more damage based on level. However this damage does not follow a pattern, is there a way other than if/then statements to solve this problem? Yes, Arrays! Integer array CoolAbility_Damage[], will be our array. Then simply intialize it so that the index is [level of the ability] And the value is the damage at that level. i.e: Set CoolAbility_Damage[1] = 31 Set CoolAbility_Damage[2] = 100 Set CoolAbility_Damage[3] = 777 In your ability trigger add this in the place where you had the damage CoolAbility_Damage[(Level of Ability (CoolAbility) for (Casting Unit)] Viola, your damage will come out as the right amount, without the hassle of a ton of if/then statments.

Technical Info & JASS:
Arrays in JASS cannot be initialized, you must fill in the value for every index with a seperate Set statment.
type array Name set Name[index] = expression set Name[index] = expression ...
Arrays in JASS all have the same max index of 8192. This means that the 'size' field for arrays in the WE is useless (to my knowledge). In this sense arrays are more like hash-tables, as you will not recieve an 'index out of bounds' error. But it also means that every array you make will occupy a certain amount of space no matter how much or little data is put into it.

Final Words
Thanks for reading this, and I hope it was helpfull. As always comments, suggestions and questions are welcome. Also, most of the JASS related information I learned from this very helpful JASS Manual.

Happy Mapping. =]

Click here to comment on this tutorial.
Blizzard Entertainment, Inc.
Silkroad Online Forums
Team Griffonrawl Trains Muay Thai and MMA fighters in Ohio.
Apex Steel Pipe - Buys and sells Steel Pipe.