It really helps to learn the ins and outs of trigger functionality. This means understanding the order of how things are executed and how multiple instances of triggers are created and run at the same time.
For the most part triggers are quite simple, a trigger executes from top to bottom, one line at a time. When the same trigger runs multiple times at once, multiple instances of the trigger are created and ordered to execute automatically. Remember, two things can't happen once, everything is ALWAYS placed in an order. Imagine a line of triggers, or a trigger queue, that are all lined up waiting for their turn to execute.
This concept can be easily seen if you Display text messages throughout your triggers. This is a great exercise for not only debugging but for understanding how things happen. Understanding the order of things will help you understand why something is or isn't working.
For example, if you have a trigger that uses the "A unit dies" Event, and 3 units in your game die at the same time (maybe Thunderclap killed them), understand that technically those units didn't actually all die at the same time. The game has ordered their deaths and the "A unit dies" trigger will follow this order. So one unit is chosen to die first, which runs the first instance of the "A unit dies" trigger, then the second unit dies and runs the 2nd instance of "A unit dies" trigger, and finally the 3rd unit dies and runs the third and last instance of "A unit dies" trigger.
From the player's perspective in-game, all of these units died at the same time, which is true in a sense, but technically behind the scenes the code has ordered these things to happen sequentially. This is why Event Responses like (Dying unit) even work. If all of the units died at the same time, who would be the (Dying unit)? They can't ALL be the (Dying unit) at the same time, which is where this instancing comes into play. They're all considered the (Dying unit) in their own respective trigger instances.
Global variables are no different from Event Responses (for the most part) and are subject to this same treatment. That's why a lot of the time they can be shared in multiple triggers without a problem. Unfortunately, there are cases where they aren't safe to reuse.
In certain cases, separate instances of triggers aren't created, and instead the Actions of one trigger are inserted directly into the Actions of another trigger, creating a trigger combining effect.
Here's an example of this, which also shows how reusing Temp variables can be unsafe:
-
Events
-
Unit - A unit starts the effect of an ability
-
Conditions
-
Actions
-
Set Variable TempPoint = (Center of map)
-
Unit - Create 1 Footman for (Triggering player) at TempPoint
-
Unit - Kill (Last created unit)
-
Custom script: call RemoveLocation(udg_TempPoint)
-
Events
-
Unit - A unit dies
-
Conditions
-
Actions
-
Set Variable TempPoint = (Position of (Dying unit))
-
// do something with TempPoint
-
Custom script: call RemoveLocation(udg_TempPoint)
The first trigger above will cause the second trigger to run. You may think that these two triggers will play nice together since there's no Waits or delays and TempPoint is being Removed in both of them. Unfortunately, that's not the case. The Actions from the "A unit dies" trigger are inserted directly into the Actions of the "starts effect" trigger, right after the unit is killed.
This is the result, a combined trigger which now leaks a Point (location):
-
Events
-
Unit - A unit starts the effect of an ability
-
Conditions
-
Actions
-
Set Variable TempPoint = (Center of map)
-
Unit - Create 1 Footman for (Triggering player) at TempPoint
-
Unit - Kill (Last created unit)
-
Set Variable TempPoint = (Position of (Dying unit))
-
// do something with TempPoint
-
Custom script: call RemoveLocation(udg_TempPoint)
-
Custom script: call RemoveLocation(udg_TempPoint)
So in these cases you'll want to use a different TempPoint variable in order to avoid the issue. You can also order your Actions in a way that will avoid the issue, for example, if we removed TempPoint before Killing the (Last created unit) in the first trigger then the leak would not happen. This solution doesn't always work though.
Whenever I work in GUI I create specific variables that I use exclusively for problematic Events like "A unit dies". I still use Temp variables throughout most of my triggers since I can differentiate between when they're safe or not. If you're ever unsure of whether something is safe or not, use Text messages to visualize how these things are executed.