HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Learn me about local variables..

06-18-2004, 08:05 AM#1
Dalten
Here's my current understanding about Local variables.

Say you have a trigger called "Cash". It runs whenever a player casts a spell and here's what it might look like:

Event: a unit begins to cast an ability
Condition: unit is a hero equel to True
Actions:
if (owner of triggering unit) equel to Player 1 then set CashIndex = 1
if (owner of triggering unit) equel to Player 2 then set CashIndex = 2
Increase Current Gold of Player(CashIndex) 100 gold.

Now say two players were to trigger this at the same time, a collision might occur and player 1 or 2 would get twice as much gold and the other player none.

Obviously the stakes aren't high here, but i'm sure if you've understood me so far you know what i mean.

I understand that local variables somehow keep variables from being "overwritten" if two or more of the same triggers are being executed at the same time.

Can someone explain the mechanics behind this?

Thanks.
06-18-2004, 08:16 AM#2
Panto
Local variables work only within the instance of the trigger that they're made and used in. Unfortunately, you can't really use locals with the GUI. You'll pretty much have to change your trigger to jass and change the variable references to local instead of global.

But yes, there is a possibility of overlap occuring and messing up your count, so it's a good idea. Moving you to the Trigger Haven so you get a little more applicable help with this.
06-18-2004, 11:53 AM#3
Anitarf
According to my knowledge, it is psyhicaly impossible for triggers to overlap (unless you use wait commands). The warcraft engine is very accurate about this, I remember that in the times of starcraft trigger timing was a bit of a problem, but in warcraft, triggers run as they are. When your triggers run on different events, there's a gap between them anyway, but even if they run on the same event, one will always run first entirely, and then the other.

However, I am uncertain how event responses work. I have read that they can work like local variables, staying the same for one trigger even if, in the meantime, during a wait command, others run. However, in my developing map I did a simple trigger for debuging and the trigger that was supposed to display the (name of the (ability being cast)) upon the event the ability is cast and two seconds later, and first it did display the spell name, but two seconds later it displayed the text "default string"...
06-18-2004, 12:15 PM#4
Cubasis
Local variables are mostly useful in triggers with waits as mentioned. And just if you don't want to clutter your map with globals, and want to keep your code neater and avoid bugs.

There can be only 1 threads (instances of a trigger (errr, that is, each time a trigger runs a thread is created)) running at any one moment in WC3. So there is no clash unless you Wait somewhere.

Anitar, while "Last Created" stuff is (logically) not thread-based (local variables). Event responses are, for the most part. In fact, there was a "special" issue with some Ability Event response that did not work correctly after a wait, and that is then a special case. Normally all event responses should work anywhere in a thread.

~Cubasis
06-18-2004, 01:25 PM#5
Anitarf
Then I suppose i must have used an exceptional event response (ability being cast)... altrough i have had non-working issues with event responses such as casting unit (but I cannot be quite sure in that case that the event response wasn't working, because it was a more complex trigger; however, it did require only a litle change to get rid of the event response, so it is still quite possible that it was the event response that wasn't working, because I changed little else))

Perhaps, if enough triggers run in between, the war3 engine looses track of older event responses? I do have two periodic triggers that run twenty-five times per second, so that would mean that a 100 threads would run during those two seconds, and maybe that caused me to loose the "ability being cast" event response....



Edit: Well, I just did another test and in my case, event responses just don't act like local variables, but like global ones. I know it sounds wierd, but I just did the most simple test possible, and it gave me undoubtable results. I added a trigger to my map that, whenever an ability was cast, would display the name of the (ability being cast) and the name of the (casting unit), wait two seconds, and do the same again. If, during those two seconds, another ability was cast, then, when the two seconds were up, the first thread would display the info on the second ability.
06-18-2004, 01:30 PM#6
Vexorian
Quote:
Originally Posted by Cubasis
Local variables are mostly useful in triggers with waits as mentioned. And just if you don't want to clutter your map with globals, and want to keep your code neater and avoid bugs.

There can be only 1 threads (instances of a trigger (errr, that is, each time a trigger runs a thread is created)) running at any one moment in WC3. So there is no clash unless you Wait somewhere.

Anitar, while "Last Created" stuff is (logically) not thread-based (local variables). Event responses are, for the most part. In fact, there was a "special" issue with some Ability Event response that did not work correctly after a wait, and that is then a special case. Normally all event responses should work anywhere in a thread.

~Cubasis
that special issue only happens when you are using the wrong event, like begins casting an ability

If you use starts the effect of an ability, the event responses are Kept till the unit stops casting it.
06-18-2004, 03:14 PM#7
Dalten
How do you go about making a variable such as CashIndex a local variable then? I seem to recall awhile go someone adding in Custom Script into a gui based trigger to create this effect?

Good responses keep em coming!
06-18-2004, 03:26 PM#8
Vexorian
there is a way to make a trigger think that a global variable is local, but it only works with one variable.

Custom Script: local integer udg_IntVar

for example would make the integer global variable IntVar to be considered global
06-18-2004, 04:05 PM#9
Dalten
Quote:
Originally Posted by Lord Vexorian
there is a way to make a trigger think that a global variable is local, but it only works with one variable.

Custom Script: local integer udg_IntVar

for example would make the integer global variable IntVar to be considered global

That would be great. See, I have several triggers that use massive amounts of arrays that execute about 25 lines of code that each contain at least one array and sometimes a multidimentional array or two that references an Index that get defined depending on what player triggered it.

Having the index overwritten mid-execution by some other player's index could be catastrophic, depending on what part of the trigger the overlap occurred. But if what some of you guys are saying, this would never occur?

For example, in my map are "Weapon runes", you pick them up and it upgrades your weapon to make it stronger... ring a bell? yep, the Shadow Orb quest except my trigger is 5x as long and 5x as complex in order to take into account multiple players, heroes of the same type being possible, etc.

Now if player 1 picks up a rune and the Index is 1, i'm worried about player 2 picking up another rune and changing the Index to 2 before player 1's trigger is finished. I have several of these triggers that I want to prevent anything wrong from happening like I just mentioned.

So if I put "Custom SCript: Local integer udg_Weapon_Index", where Weapon_Index is my index for the arrays, it *should* prevent such a catastrophe?

Thanks again!
06-18-2004, 04:11 PM#10
Vexorian
I think that a whole array can be converted to local withouth problems:

Custom Script: local integer array udg_Ints

Would make Ints[] act as local.

Anyways this trick won't work inside Conditions nor Pick Every .... actions, because we converts them into other functions
06-18-2004, 04:12 PM#11
Anitarf
Yes, but as has been said before, unless you have a wait action in your trigger, there is no way another trigger can get in and mix things up. If that were the case, triggering anything whatsoever to work would be impossible.

But I am still interested about what I posted earlier: are event responses global or local? My testing suggests that they are global...
06-18-2004, 04:29 PM#12
Dalten
Well, I guess according to you Anitar(Cubasis rather) I don't have anything to worry about then since I'm not using any wait's.

Just for the sake of curiosity, do you have declare the variables as local In the trigger they're used in or can you do it at map startup?
06-18-2004, 05:56 PM#13
Oinkerwinkle
Quote:
Originally Posted by Dalten
Just for the sake of curiosity, do you have declare the variables as local In the trigger they're used in or can you do it at map startup?
You have to declare them as such in the specific trigger.
06-18-2004, 06:38 PM#14
Dalten
Quote:
Originally Posted by Oinkerwinkle
You have to declare them as such in the specific trigger.

I realize what you guys are saying but something still does not make sense to me in relation to two triggers not being able to execute at the same time... It seems to me that in fact they can execute at the same time... unless someone can shed light on why this happened awhile back:

In my map are upgrade stones, pick up a Knight stone and your given a subclass, a new hero and the trigger also adjusts a lot of stuff such as HeroName, what their class title is for the leaderboard etc...

I was playing around once and to test for collisions I picked up a bunch of these items with a lot heros as fast as I could... very soon one of the heroes turned into a hero he shouldn't have(I replace units). This never happens when i'm doing it one at a time and this is what has caused my whole concerns...

Something caused the game to give the wrong hero to one of the players, I can only imagine at this point that it was an overwritten Index.

I think i'll go ahead and put in the local variable declaration in the trigger for the index because I really believe there's a problem with my trigger that this might solve. Only problem I see with this so far is what Lord Vexorian said about Conditions, I do use several If loops for determining the class and player who triggered it so is this something i need to worry about?

Thanks again, by the way i've been giving all of you rep points that have replied.
06-20-2004, 03:16 PM#15
Cubasis
Ok, here are some statements that are true and have been proven.

1: Only 1 thread can run at a time. So only a single line of actions can be running at any time.
2: Event Responses ARE for the most part thread-defined. That is, they last throughout the complete thread, even in other functions (conditions, for-each) and they exist after Waits. There are though a couple of event responses that do not work correctly as Anitar prooved.
3: Dalten, i'm not sure if you understood local variables correctly, so i'll just say this anyways. Local variables do not exist between threads. That is, when you define a local variable in your trigger, it starts at 0 (well, garbage actually, but that's irrevelent), and you can use it whatever you want. But when the function/trigger ends, it disapear, and the next time the trigger runs, you get a new local variable, that starts again at...garbage/0.

If you run into a situation where you "need" a local variable in a condition or a for-each, you can put it into a another global variable, use the global variable in the condition/for-group, and then move it back into the local when you're done (if you changed it, that is. Oh, and you can't then have waits in the For-Group, as then other triggers might mess with this same global).

~Cubasis