1. The mythological era has spawned some interesting characters around. Check them out and be sure to vote for them in the 30th Poll of the Texturing Contest.
    Dismiss Notice
  2. The 20th iteration of the Terraining Contest is upon us! Join and create exquisite Water Structures for it.
    Dismiss Notice
  3. Hivers united and created a bunch of 2v2 melee maps. Vote for the best in our Melee Mapping Contest #4 - Poll!
    Dismiss Notice
  4. Check out the Staff job openings thread.
    Dismiss Notice

Things That Leak

Discussion in 'Triggers & Scripts' started by Ralle, Jun 10, 2007.

  1. Ralle

    Ralle

    Owner

    Joined:
    Oct 6, 2004
    Messages:
    11,150
    Resources:
    22
    Tools:
    3
    Maps:
    5
    Tutorials:
    14
    Resources:
    22
    For a structured tutorial on the matter, read this.

    Hello guys!
    Credit to: Wolverabid, PurplePoot, Silvenon, Paskovich

    I want to make a list of things that leak and ways to fix them.

    Dynamic Unit Groups

    This trigger will instantly destroy dynamically generated unit groups.

    Unit Groups
    • Trigger
      • Events
        • Event
      • Conditions
        • Conditions
      • Actions
        • Custom script: set bj_wantDestroyGroup = true
        • Unit Group - Pick every unit in (Playable Map Area) and do (Unit - Hide (Picked unit))

    Another way to avoid a group leak is to store the group into a variable, and then destroy it manually.

    Unit Groups
    • Set GroupVar = Pick every unit in (Playable Map Area)
    • Unit Group - Pick every unit in GroupVar and do (Unit - Hide (Picked unit))
    • Custom script: call DestroyGroup(udg_GroupVar)

    This is useful if you want to use the group more than once in the trigger.​

    Dynamic Locations

    Locations
    • Unit - Create 1 unit at Somewhere

    If there is a function, like (Position of (Unit)) or (Center of (Region)), it will leak.

    Locations
    • Set loc = Somewhere
    • Unit - Create 1 unit at loc
    • Custom script: call RemoveLocation(udg_loc)

    Player Groups

    Player Groups leak also, but those are really rare. The fix:

    Player Groups
    • Player Group
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Some Spell
      • Actions
        • Set PlayerGroup = (All enemies of Player 1 (Red))
        • Player Group - Pick every player in PlayerGroup and do (Do nothing)
        • Custom script: call DestroyForce(udg_PlayerGroup)

    Note: (All Players) does not leak, and destroying it may cause problems.

    Special Effects

    Special Effects
    • Special Effect
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Some Spell
      • Actions
        • Set Point = (Position of (Triggering unit))
        • Special Effect - Create a special effect at Point using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
        • Special Effect - Destroy (Last created special effect)
        • Custom script: call RemoveLocation(udg_Point)

    Note: Creating a special effect and destroying it directly afterwards will still show the effect.

    Terrain Deformations

    These create a small but permanent leak, so having far too many of them may cause some performance issues.

    Spells like Shockwave and Hoof Stomp create terrain deformations, so do not over-use them.​

    Things That Always Leak

    Never use these functions:

    Black-Listed Functions
    • Unit Group - Pick all units of type Footman and do...
    • Camera - Pan Camera as needed...
     
    Last edited: May 5, 2015
  2. Diablo-dk

    Diablo-dk

    Joined:
    Nov 10, 2004
    Messages:
    369
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    • Leak
      • Events
      • Conditions
      • Actions
        • Unit - Move (Triggering unit) instantly to ((Position of (Triggering unit)) offset by 100.00 towards 180.00 degrees)
        • -------- Leaks Twice! --------
        • -------- --------
        • Set TempPoint = (Position of (Triggering unit))
        • Unit - Move (Triggering unit) instantly to (TempPoint offset by 100.00 towards 180.00 degrees)
        • Custom script: call RemoveLocation(udg_TempPoint)
        • -------- Still leaks a location --------
        • -------- --------
        • Set TempPoint = (Position of (Triggering unit))
        • Set TempPoint2 = (TempPoint offset by 100.00 towards 180.00 degrees)
        • Unit - Move (Triggering unit) instantly to TempPoint2
        • Custom script: call RemoveLocation(udg_TempPoint)
        • Custom script: call RemoveLocation(udg_TempPoint2)
        • -------- Finnaly no leaks! --------

    PolarProjection(Point with polar offset) also creates a location, meaning that it has to be set to a variable and removed.
     
  3. Ralle

    Ralle

    Owner

    Joined:
    Oct 6, 2004
    Messages:
    11,150
    Resources:
    22
    Tools:
    3
    Maps:
    5
    Tutorials:
    14
    Resources:
    22
    yeah, That makes sence!
    But aren't there other things that leaks except for locations?
     
  4. paskovich

    paskovich

    Joined:
    Jul 12, 2005
    Messages:
    794
    Resources:
    2
    Tutorials:
    2
    Resources:
    2
    Another way to avoid a group leak is to store the group instantly to a variable, and then destroy it manually. According to your example, Ralle:
    • Set GroupVar = Pick every unit in (Playable Map Area)
    • Unit Group - Pick every unit in GroupVar and do (Unit - Hide (Picked unit))
    • Custom script: call DestroyGroup(udg_GroupVar)
    This is useful is you want to use the group more than one time in the trigger.


    EDIT:
    In GUI, these two are the most common leaks. Creating any object will of course leak, but it is not that common for example a dummy unit is not killed/removed.
    Other leaks should be taken care of mainly in jass, when we create local triggers, timers, and such nasty things.
     
  5. Ralle

    Ralle

    Owner

    Joined:
    Oct 6, 2004
    Messages:
    11,150
    Resources:
    22
    Tools:
    3
    Maps:
    5
    Tutorials:
    14
    Resources:
    22
    yeah, that's more handy!
     
  6. FamousPker49

    FamousPker49

    Joined:
    May 27, 2007
    Messages:
    1,640
    Resources:
    1
    Skins:
    1
    Resources:
    1
    Intialization triggers also sort of leak, but by destroying them with "call DestroyTrigger(GetTriggeringTrigger())" after a trigger you do not need anymore this seems to help my maps a lot
     
  7. paskovich

    paskovich

    Joined:
    Jul 12, 2005
    Messages:
    794
    Resources:
    2
    Tutorials:
    2
    Resources:
    2
    Well, a good triggered map should have only ONE initialization trigger, and I don't think global triggers would reduce game efficiency.
     
  8. Silvenon

    Silvenon

    Joined:
    Nov 22, 2006
    Messages:
    1,233
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    Special effects leak, some people do like this:

    • Speical Effect
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Some Spell
      • Actions
        • Special Effect - Create a special effect at (Position of (Triggering unit)) using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl


    (this also covers a common location leak) When it should be like this:

    • Speical Effect
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Some Spell
      • Actions
        • Set Point = (Position of (Triggering unit))
        • Special Effect - Create a special effect at Point using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
        • Special Effect - Destroy (Last created special effect)


    Some people don't realize they had a leak, so it's useful to know.
    Also sounds leak, they should be destroyed like this:

    • Sound
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Some Spell
      • Actions
        • Sound - Play (Some Sound)
        • Sound - Destroy (Last played sound)


    Player Groups leak also, but those are really rare, I think they are called Forces in JASS, so the fix would be:

    • Player Group
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Some Spell
      • Actions
        • Set PlayerGroup = (All enemies of Player 1 (Red))
        • Player Group - Pick every player in PlayerGroup and do (Do nothing)
        • Custom script: call DestroyForce(udg_PlayerGroup)


    Correct me if I'm wrong here
     
    Last edited: Jun 10, 2007
  9. paskovich

    paskovich

    Joined:
    Jul 12, 2005
    Messages:
    794
    Resources:
    2
    Tutorials:
    2
    Resources:
    2
    Global timer should not ve destroyed!! When declaring the global variables, a new timer is created for each timer variable.
    .
    set udg_TimerVar = CreateTimer()
    .

    If you destroy the timer, you have to create it again, but why would you do that?
    So you're wrong with the timer, but right with the special effects. I don't know how forces leak. All i know is (All players) do NOT leak, and if you destroy it, sthg weird (crash or fatal error?) will happen, so that's not the best example, is it? :D
     
  10. Silvenon

    Silvenon

    Joined:
    Nov 22, 2006
    Messages:
    1,233
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    Sry, I wasn't positive about the timers, I was wondering why no one mentioned that........Yeah you're right with All Players, that's a constant so it doesn't leak, I edited it so maybe now it's a good example
     
  11. Razorbrain

    Razorbrain

    Joined:
    Aug 18, 2006
    Messages:
    1,165
    Resources:
    1
    Maps:
    1
    Resources:
    1
    why/how does this leak? i use (Position of (anotherUnit)) and it works fine for me
     
  12. FamousPker49

    FamousPker49

    Joined:
    May 27, 2007
    Messages:
    1,640
    Resources:
    1
    Skins:
    1
    Resources:
    1
    paskovich im saying that in intialization triggers in general not for one map you have more than one, and yes they do help
     
  13. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,202
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Floating text can also leak unless you destroy it but GUI comes easily with the ability to do so.
     
  14. GST_Nemisis

    GST_Nemisis

    Joined:
    Jan 5, 2005
    Messages:
    3,600
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    when the list is complete we should join it all together in one big list, then perhaps sticky?
     
  15. Silvenon

    Silvenon

    Joined:
    Nov 22, 2006
    Messages:
    1,233
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    Razorbrain, I know it works for you, it should. Leaks are not whether it's working or not, the full name is memory leaks. It's when (example) you create a special effect at the position of a unit. If that location (the position of unit) is not destroyed, it will stay there and take some memory, so when you create lots of these locations, your map will lag like hell. Imagine it like this, try putting 10000 units on a map and test it, it bet it'll lag because each unit takes some memory, and causes the game to leak. Same for Unit Groups, if you go pick every unit, then WE creates a group so he can do what you said, but if that group isn't destroyed, it will leak.

    These are what don't leak: integer, real, boolean, string (in JASS code doesn't leak also)

    Blizzard should have made a garbage collector for that, though I'm not sure how that works

    http://world-editor-tutorials.thehelper.net/cat_usersubmit.php?view=27242
     
  16. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,162
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    Those are what don't leak handles (null leaks). Otherwise, several handles don't leak.

    Also, strings technically leak.

    A few other things that leak (going into JASS junk) -

    -Triggers (duh)

    -Triggeractions (have to be removed before destroying the trigger in question)

    -Strings, but the reference is only created once. The same string won't leak twice, unlike most leaks.

    -Boolexprs generated with And() and/or Or().

    -All boolexprs, under the same conditions as Strings. However, boolexprs can be destroyed via DestroyBoolExpr(). If you reuse the boolexpr (as in a trigger that fires more than once, etc), you shouldn't destroy it.

    -Weather Effects

    -(All Players) is a player group that doesn't leak.

    -A whole ton of other things I can't think of right now.

    -By the way, the Triggering Unit thing I mentioned wasn't a leak, just an efficiency waste. Triggering Unit can replace any reference to a unit in a trigger where the unit referenced triggered the trigger in question.
    Eg. A Unit Casts an Ability -- Triggering Unit = caster
    A Unit Is Attacked -- Triggering Unit = unit that was attacked
    A Unit Dies -- Triggering Unit = unit that died
     
  17. Razorbrain

    Razorbrain

    Joined:
    Aug 18, 2006
    Messages:
    1,165
    Resources:
    1
    Maps:
    1
    Resources:
    1
    oh, ok :p
     
  18. Silvenon

    Silvenon

    Joined:
    Nov 22, 2006
    Messages:
    1,233
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    Just a question, does TriggerAddCondition(trig, Condition(function Trig_Blabla_Conditions)) leak? Did you know that you can do that only directly (like that)?? You can't do that with boolexpr local, It took me and HappyTauren about and hour and a half to figure that out.....
     
  19. paskovich

    paskovich

    Joined:
    Jul 12, 2005
    Messages:
    794
    Resources:
    2
    Tutorials:
    2
    Resources:
    2
    It leaks, but it can be cleaned!! I've learned this from Diablo and Purple:
    Code (vJASS):
    local trigger t = CreateTrigger()
    local boolexpr be = Condition(function Trig_Blabla_Conditions)
    call TriggerAddCondition(t, be)
    call DestroyBoolexpr(be)

    When destroying the local trigger, triggeractions and conditions should also be removed.
    TriggerRemoveAction
    TriggerRemoveCondition
    Code (vJASS):
    local trigger t = CreateTrigger()
    local boolexpr be = Condition(function Trig_Blabla_Conditions)
    local triggercondition tc = TriggerAddCondition(t, be)
    local triggeraction ta = TriggerAddAction(t, function Trig_Blabla_Actions)
    call DestroyBoolexpr(be)
    call TriggerRegister..Event(t, ..)
    //At the end when we want to destroy the local trigger:
    call TriggerRemoveCondition(t, tc)
    call TriggerRemoveAction(t, ta)
    call DestroyTrigger(t)
    //null all locals!
     
  20. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,162
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    Nope, pask, that's wrong on 2 ends ><

    A) if you destroy the boolexpr right away, you're killing the condition

    B) you CAN destroy the boolexpr when the trigger is to be discarded, but if there are any other instances of that trigger it can cause problems, as boolexprs are sort of stored like strings. In many cases, it's better to just not destroy them

    However, you got TriggerRemoveX right ><