Triggers - Variables and Arrays

L

Laika.

Guest
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.

Variables

Overview:
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:
Code:
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:

Constants
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:
Types
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.

Natives
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.

Scope
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.

Code:
globals
[I]...
type name = expression
type name = expression
...[/I]
endglobals

Local variables are defined when a function is called and can only be used from that function.
Code:
function...
local [I]type name = expression[/I]
...
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.






Arrays

Overview:
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:
Code:
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
[center][U]INDEX  |  VALUE[/U]
1     |     ?
2     |     ?
3     |     ?
..     |     ..
[/center]

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:

Maps
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:
Code:
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:
Creating
Arrays in JASS cannot be initialized, you must fill in the value for every index with a seperate Set statment.
Code:
[I]type[/I] array [I]Name
set Name[/I][[I]index[/I]][I] = expression
set Name[/I][[I]index[/I]][I] = expression
...[/I]
Size
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. =]
 

phyrex1an

Staff Member and irregular helper
Reaction score
446
Nice. That is the only thing I have to say.

Or I have some feedback:

Mention what the size section does in global arrays.
(No it does not limit the size)

Is Code a Handle derived type?

Setting a local to null is a good idea in most case but do it after you have removed or destroyed the handle if dont have anyother way to acces the handle. Otherwise you will have a realy leak. Another thing to know is that blizzard themself doesn not 'nulling' locals. I dont know why.

We also have a variable tutorial here . I dont say wichone is best I have never needed any of them but if someone doesnt understand this one they may understand by reading the oter one. Who knows?

*Applaudes* (spelling?)
 
L

Laika.

Guest
To my knowledge, the 'size' field in Global Arrays does absolutely nothing. Try making an array of size 1 in the editor and assigning a value to index >1, it will let you.

Code is also another native type, that I ommited... for no reason really. I'll add it in.

Good point about destroying what the handle points to. I'll mention that as well. Why can't JASS just have the nice end of function trash collecting of other languages ; ;

Edit: I removed the memory leaks section, as it would be out of the scope of the tutorial to do it justice.

Also, Thanks for taking the time to comment.
 

xPheRe

New Member
Reaction score
43
Wow, this rocks!
From now, when someone ask me about vars, arrays or something, I will redirect him/her to this thread.

Great tutorial threads has been added to TH in quite a few days. That's good for all of us!

Nice job, Laika!!
 
L

Laika.

Guest
Thanks xPheRe!
Also, I fixed some formatting and added some things I meant to but forgot. =]
 

phyrex1an

Staff Member and irregular helper
Reaction score
446
Laika. said:
To my knowledge, the 'size' field in Global Arrays does absolutely nothing. Try making an array of size 1 in the editor and assigning a value to index >1, it will let you.

well I have noticed ONE thing. When the array is a group or force you cant use GroupAddUnit() or ForceAddPlayer() and functions that using that before making a operator that returns a group/force. Well I havnt realy tested but it sound locical since there index of the array are pointing to null if the index is out of the "size".
 
L

Laika.

Guest
You can't use those functions on the array directly.

GroupAddUnit() requires the input GroupAddUnit(group, unit).

If your array is an array of unit-groups then

GroupAddUnit(My_Unitgroup_Array[1], GetLastCreatedUnit()) would work.
 

phyrex1an

Staff Member and irregular helper
Reaction score
446
when did I say that I didnt send the paramaters?

it is much easir to write just funtion() then function(group, unit) ^^

the thing is that the "size" "initilize" the array ie asigning it a vaule, things that cant be asigned is scipped (units, triggers)

All vaules is pointing to null, 0 or "" at the begining after a of the array the still point to null, 0 or "" with the exeption of groups and forces.

The point to a group or force that is empty

check this:
Code:
globals
    // User-defined
    group array             udg_g
    force array             udg_f
    unit array              udg_u
    integer array           udg_i
    real array              udg_r
endglobals

function InitGlobals takes nothing returns nothing
    local integer i = 0
    set i = 0
    loop
        exitwhen (i > 4)
        set udg_g[i] = CreateGroup()
        set i = i + 1
    endloop

    set i = 0
    loop
        exitwhen (i > 4)
        set udg_f[i] = CreateForce()
        set i = i + 1
    endloop

    set i = 0
    loop
        exitwhen (i > 4)
        set udg_i[i] = 0
        set i = i + 1
    endloop

    set i = 0
    loop
        exitwhen (i > 4)
        set udg_r[i] = 0
        set i = i + 1
    endloop

endfunction

and as i said, not tested so i cant be sure ^^
 

PB_and_J

level 85 anti-spammer
Reaction score
41
nice tutorial gj liaka
 
L

Laika.

Guest
Oh, alright I see what you're getting at. That very well may be the case phyrex1an, but theres nothing stopping you from manually creating another force at approriate index. =] I don't use force or unit-group often, so I haven't ran into this problem.
However, that drawback is different from the 'size' of arrays in other typed programming languages (Java, C++) where the intial size of the array is directly linked to how much memory is allocated to that array and that if you pass an invalid index you will simply break the program. =] JASS allocates every array to 8192 indexes no matter what, wether that index is initialized properly for that type or not.
That is good to note however, I think some testing may be in order. (Before I add it to the tutorial).
 

phyrex1an

Staff Member and irregular helper
Reaction score
446
Another thing that needs testing is the nulling of handle arrays.

All test i know of has showed leaks with nonulled handles but I have hear/read that handle arrays doesnt need to be nulled. I have no prof or anything, I wasnt I who said this from the begining.



Laika. said:
but theres nothing stopping you from manually creating another force at approriate index. =].

that is what the "before making a operator that returns a group/force" stands for I think ^^. Glad that we agre with each other.


BTW this tutorial ownz the officila th variable tutorial (no offence Ryoko) on the advanced section. Dont know wich basic section that is best.
 

SD_Ryoko

Ultra Cool Member
Reaction score
85
phyrex1an said:
BTW this tutorial ownz the officila th variable tutorial (no offence Ryoko) on the advanced section. Dont know wich basic section that is best.

Perhaps. But notice he did not colaborate with the tutorial, and include all the elements inside that one as well.

So now we have two 'mostly compelte' tutorials.
 

DM Cross

You want to see a magic trick?
Reaction score
566
*Takes this tutorial, and the tutorial site tutorial, stuffs them into a teenie tiny little box and rattles it around for awhile*

:rolleyes:

Anyway, can't you just sort of take the best parts of both and create the "ultimate variable tutorial"? :p
 

The Helper

Necromancy Power over 9000
Staff member
Reaction score
1,688
5 Star Bump

5 Star Bump!

This tutorial has only been rated two times. Please consider reviewing this Tutorial and giving a rating. Thanks!
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top