• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Things That Leak

Level 12
Joined
Aug 20, 2007
Messages
866
Offtopic - Why do people prefer recycleing handles??? It doesn't seem to be beneficial at all... and it takes more function calls
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Well, sometimes people prefer using the same handle 1000 times rather than creating 1000 handles.

JASS:
local integer i = 0
local group g = CreateGroup()
local real x = ...
local real y = ...
loop
    exitwhen i == 1000
    call GroupEnumUnitsInRange(g, 500, x, y, null)
    call ForGroup(g, function ...)
    call ClearGroup(g)
    set i = i + 1
endloop

Instead of:

JASS:
local integer i = 0
local real x = ...
local real y = ...
loop
    exitwhen i == 1000
    local group g = CreateGroup()
    call GroupEnumUnitsInRange(g, 500, x, y, null)
    call ForGroup(g, function ...)
    call DestroyGroup(g)
    set i = i + 1
endloop
 
Level 12
Joined
Aug 20, 2007
Messages
866
Well, sometimes people prefer using the same handle 1000 times rather than creating 1000 handles.

JASS:
local integer i = 0
local group g = CreateGroup()
local real x = ...
local real y = ...
loop
    exitwhen i == 1000
    call GroupEnumUnitsInRange(g, 500, x, y, null)
    call ForGroup(g, function ...)
    call ClearGroup(g)
    set i = i + 1
endloop

Instead of:

JASS:
local integer i = 0
local real x = ...
local real y = ...
loop
    exitwhen i == 1000
    local group g = CreateGroup()
    call GroupEnumUnitsInRange(g, 500, x, y, null)
    call ForGroup(g, function ...)
    call DestroyGroup(g)
    set i = i + 1
endloop


Thats not handle recycling, thats just using the same handle

I'm talking about how in vJASS they recycle timers and things of the sort
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,199
Use a simlar JASS script to that of the timer recycler.

Basically when you get the contence of a group via the native for a trigger like an AoE of a spell it cleans out the contence of the group and replaces it with new contence.

This means that the same group object would not need to be destroyed as it could be reused infinatly. This removes any chance of leaks occuring and also makes the trigger more efficent as it constantly is not having to allocate a group and then deallocate it. This method can be extreemly useful in cases where you need to get units on the map via something like the get units in range etc for a spell a lot of times a second. Also if I am not mistaken, you can initialize globals with a handle value but only in JNGP as that enables one to have better controle over globals.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
JNGP is very useful(I like it a lot).
But even when you assign an initial value(like "Location(1000,1000)") the location may not be created(I have only tested it with regions(not rects), so I am not sure of all handles).
And the question was if initially created unit groups leak(the GUI ones).
 
Level 12
Joined
Aug 20, 2007
Messages
866
Use a simlar JASS script to that of the timer recycler.

Basically when you get the contence of a group via the native for a trigger like an AoE of a spell it cleans out the contence of the group and replaces it with new contence.

This means that the same group object would not need to be destroyed as it could be reused infinatly. This removes any chance of leaks occuring and also makes the trigger more efficent as it constantly is not having to allocate a group and then deallocate it. This method can be extreemly useful in cases where you need to get units on the map via something like the get units in range etc for a spell a lot of times a second. Also if I am not mistaken, you can initialize globals with a handle value but only in JNGP as that enables one to have better controle over globals.


Errr... that doesn't make sense

The contents of every group should be different, because each spell has a different target, so each group couldn't be recycled efficiently, because you'd need a group with your specified parameters for every single point of the map readily available

You cannot initialize globals with handle values, it causes some kind of thread crash (I had this problem with the GetZ library)

I am not asking for a timer recyle, or a group recycle

I am asking why they are used, and how they are possibly useful
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
I don't know. I never do.

But I've heard that nulling timers could be buggy and thus timer recycling would be better. I don't bother about those small issues though. I make sure I don't leak, that's all, I don't care if you gain a 0,00001 second performance by recycling a group variable. I really don't care at all.
 
Level 12
Joined
Aug 20, 2007
Messages
866
Ohh, ok, so the timer recycle (CSSafety) was only used to satisfy problems with an outdated gamecache

I suppose if you only use ABC, timer recycle would actually be useless and inefficient
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Contrary to popular belief, the best known current way uses neither.

JASS:
scope ASpell
private struct TheStruct
    //stuff in the struct
endstruct

globals
    private TheStruct array darr
    private integer max
    private timer T = CreateTimer()
endglobals

private function Loop takes nothing returns nothing
    local integer i = 0
    local TheStruct dat
    loop
        exitwhen i == max
        set dat = darr[i]
        //do stuff
        if <deallocate> then
            set max = max - 1
            set darr[i] = darr[max]
            if max == 0 then
                call PauseTimer(T)
            endif
        else
            set i = i + 1
        endif
    endloop
endfunction

private function Actions takes nothing returns nothing
    local TheStruct dat = TheStruct.create()
    //initialize the struct
    set darr[max] = dat
    if max == 0 then
        call TimerStart(T,<interval>,true,function Loop)
    endif
    set max = max + 1
endfunction
endscope

Voila, your spell now uses only one timer and no attachment system to speak of.
 
Last edited:
Level 12
Joined
Apr 27, 2008
Messages
1,228
To back up my statement.
I made these in the global variable window:

attachment.php


And this is what I got in the actual code:

attachment.php


JASS:
globals
    // User-defined
    abilcode                udg_ab
    attacktype              udg_at                     = null
    boolean                 udg_bo                     = false
    buffcode                udg_bu
    camerasetup             udg_ca                     = null
    gamespeed               udg_gam                    = null
    integer                 udg_in                     = 0
    item                    udg_it                     = null
    itemtype                udg_ite                    = null
    integer                 udg_item                   = 0
    leaderboard             udg_le                     = null
    lightning               udg_li                     = null
    lightningtype           udg_lig                    = null
    weapontype              udg_co                     = null
    damagetype              udg_da                     = null
    destructable            udg_de                     = null
    destructablecode        udg_des
    defeatcondition         udg_def                    = null
    dialog                  udg_di                     = null
    button                  udg_dia                    = null
    effecttype              udg_ef                     = null
    texttag                 udg_fl                     = null
    gamecache               udg_ga                     = null
    image                   udg_im                     = null
    imagetype               udg_ima                    = null
    multiboard              udg_Mu                     = null
    pathingtype             udg_pa                     = null
    quest                   udg_qu                     = null
    questitem               udg_que                    = null
    race                    udg_ra                     = null
    real                    udg_re                     = 0
    rect                    udg_rec                    = null
    sound                   udg_so                     = null
    effect                  udg_sou                    = null
    integer                 udg_or                     = 0
    player                  udg_pl                     = null
    playercolor             udg_pla                    = null
    force                   udg_play                   = null
    location                udg_po                     = null
    string                  udg_st
    integer                 udg_te                     = 0
    terraindeformation      udg_ter                    = null
    integer                 udg_terr                   = 0
    integer                 udg_terra                  = 0
    timer                   udg_ti                     = null
    timerdialog             udg_tim                    = null
    trigger                 udg_tr                     = null
    ubersplat               udg_ub                     = null
    string                  udg_ube
    unit                    udg_un                     = null
    group                   udg_uni                    = null
    fogmodifier             udg_vi                     = null
    weathereffect           udg_we                     = null

    // Generated
    trigger                 gg_trg_Melee_Initialization = null
    trigger                 gg_trg_Test                = null
a
endglobals

So although GUI says New *stuff* it doesn't create it.
I will do a test now, to test the other part of my statement.
Edit: Some handle types can be created as global variables :p
But regions can't.
Haven't tested all.
 

Attachments

  • Variables.w3x
    13.2 KB · Views: 65
  • Globals.JPG
    Globals.JPG
    97.6 KB · Views: 322
  • Variables.JPG
    Variables.JPG
    94.7 KB · Views: 305
Last edited:
Level 12
Joined
Aug 20, 2007
Messages
866
Contrary to popular belief, the best known current way uses neither.

JASS:
scope ASpell
private struct TheStruct
    //stuff in the struct
endstruct

globals
    private TheStruct array darr
    private integer max
    private timer T = CreateTimer()
endglobals

private function Loop takes nothing returns nothing
    local integer i = 0
    local TheStruct dat
    loop
        exitwhen i == max
        set dat = darr[i]
        //do stuff
            //WHEN YOU WANT TO DEALLOCATE
            set max = max - 1
            set darr[i] = darr[max]
            if max == 0 then
                call PauseTimer(T)
            endif
            //BACK TO MAIN SPELL
        set i = i + 1
    endloop
endfunction

private function Actions takes nothing returns nothing
    local TheStruct dat = TheStruct.create()
    //initialize the struct
    set darr[max] = dat
    if max == 0 then
        call TimerStart(T,<interval>,true,function Loop)
    endif
    set max = max + 1
endfunction
endscope

Voila, your spell now uses only one timer and no attachment system to speak of.


How is that the most efficient?? That just loops until you get your integer, every single time

ABC must be quicker, it uses a hash to get a random(I think) number from
0-8191, that is the index of an array for your stored integer

It uses the handles in a loop, just in case there are collisions

If there weren't any collisions(meaning the algorithm was perfect), the system wouldn't even need a function call

Sorry, but I refuse to believe looping constantly to get your integer is the fastest way (you probably already know, but you only need to use the struct name when declaring the variable to enable its syntax, for globals, you can just use integer)

EDIT - Err... I think there is something wrong

If your setting dat = darr, and i=0, then doing stuff with dat., that means your just using darr[0] everytime??


I R confuzzled :ugly:
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
You are confused, most certainly.
What PurplePoot posted indeed is the most efficient thing there could be.
Every attachment system is slower than that!
It uses only one timer, meaning that it is faster than creating a new timer each time and a lot safer.
Here is the logic:
Actions is called for the first time, max is 0, so the timer is started, max is increased. when the timeout is over, Loop is called, and will loop only once(i=0 and max=1).
If actions is called before the first timeout is over, the timer is not started again(max!=0), but one more hop is added to the loop(i=0 and max=2).
And so on and on.
It has just one flaw - at a later call of Actions, Loop will be called sooner than needed.
FOr example timeout is 10, you call actions once, than 9 seconds later you call actions again, and both things that must be done will be done after only 1 second. So the second thing will happen 9 seconds earlier.
So avoid doing it with timers with big timeouts.
 
Last edited:
Level 12
Joined
Aug 20, 2007
Messages
866
max is increased when the timeout is over

This is incredibly new to me, but correct me if I am wrong, max is increased when the if/then ends, not when the timeout ends

Ohhhh, just re-read your explanation

That is how it is done in GUI, run all of the actions on a single timer, and just loop through each one

I see how that could be more efficient, but I also see the problem with calling it more than once

That shouldn't be used for one-shot types of timers, it should be used for constant timers that are always running

Although, I would need to think a little bit about how one could stop a projectile using a system like that (lets say you wanted your timestop spell to stop projectiles too)

And you couldn't be able to have a choice in interval timing if you were gonna make movement functions

The only thing I have a small problem with is when you deallocate, you set your max down one, and set the stored struct that has been deallocated to the struct that was the max index struct, so the struct that had the index of the max is not eliminated, it is just moved to the place of the one you did eliminate, decreasing your total max whilst eliminating the appropriate struct

Thats genius

I see how that is far more efficient, but I didn't know timers were that large
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Herman said:
The only thing I have a small problem with is when you deallocate, you set your max down one, and set the stored struct that has been deallocated to the struct that was the max index struct, so the struct that had the index of the max is not eliminated, it is just moved to the place of the one you did eliminate, decreasing your total max whilst eliminating the appropriate struct

Yeap. Those are resemble the properties of stacks :p

Using it for something with small timeout would be best. The example with projectiles is an excellent one.
To stop them, in the //do stuff just add an if/than/else checking if time is stopped. You have to make this, to suit you. For instance in the projectile struct you can add a boolean to see if the projectile is stopped and in the timer callback see if it is. And/Or you can make a global boolean and check that as well.
P.s. Too addicted to pc games to create them, atm :p
About "max is increased when the timeout is over", I missed a fullstop. sew me :p
 
Last edited:
Level 12
Joined
Aug 20, 2007
Messages
866
Aye, it would be a little tricky to just set a boolean, because the boolean must be a part of the struct that the projectile is stored in, and somehow you would need to retrieve your specific structs index, and then add a boolean if/then

I suppose that is all ok, except maybe there are a large number of possible if/then situations, and not using a system like PUI, would be somewhat difficult, but if you were using PUI, properties could be set easily (simply index the struct index to the unit data)

EDIT - Yeah you really can't use this system for one-shot timers, for the reason you described. For one-shots just use QUICK_TIMER()

Oh, I just thought of another way to loop timers without an attachment system. In GUI I would create a unit, add and expiration timer, set its data to the index of the globals, and make a new trigger with a condition for when it dies

Well, this could be re-created with QUICK_TIMER() by just making the action restart the same timer with the same index, this way you can have MUI without attachment, periodic or one-shot\

*Sorry for getting offtopic, sort of brainstorming*
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Hm, I called doing this:
region abv

Initialization. Somehow it came to my mind before declaration.
And by creation I meant =CreateRegion()

So to paraphrase: You cannot create a global region when declaring it.
 
Level 12
Joined
Aug 20, 2007
Messages
866
[I guess efficiency posts would fit in this, because the leaks are bad because they destroy efficiency :confused:]

Putting alot of thought into stacking loops to remove attachment systems, and lower timer count

I think you could rig up the system into two generic TimedFunc() and PeriodicFunc(), which could both be done using one timer at .01 interval (obviously that creates a few restrictions, #1 being you can't call the function at lower than .01)

This would be helpful for those single-shot timers that spwin described, because all you'd need to do is make a counting integer array store a certain value * 100

Ex. You want to call two functions, one in 10 seconds, another in 7. The count value for the first would be 1000, the second 700, and each loop the count decreases, the loop will call a function via ExecuteFunc() and probably use an integer global to temporarily store a structs index

After the function is executed, the loop instance (type of thing) gets deallocated

I haven't quite figured out how to make a generic PeriodicFunc() to get the flag/boolean to deallocate from the ExecuteFunc()

Again, brainstorming, because I think it would be really cool to be able to run all of your timed functions off a single timer (2nd restriction would be that the timing could always be .01 of a second off)

I will create a little library when I figure out these problems, and then add it to the Code Snippets section

EDIT - Any variable that is started up with a handle value in GUI can be done without problems, anything that cannot have a starting value in GUI, cannot have a starting value in vJASS, although the processor will not note this to you
I have not yet found any exceptions to this (locations are included in this group, and I had f*cking hell learning that)
 
Level 18
Joined
Aug 3, 2008
Messages
1,935
okay id hate to sound stupid,
but what are the major side effects of leaked triggers?

because on an AOS map i usto have, i used that " create unit" trigger
5 times at one loaction at 5 locations. And it was every
4 seconds they would spawn.

Does that mean that my triggers leak 200 times a minute ?
 
Level 18
Joined
Aug 3, 2008
Messages
1,935
strange.
when i played my Aos Map
there was no lag at all.
but it was single player.
i guess on battle.net it would cause disconeections

correction : 5 for 1 location x 5 locations = 25.
25(2 leaks each time) = 50
50 leaks every 4 seconds for 1 minute =
50 x 15 =
750 leaks per minute

damn :D
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Actually it depends on how you create the units.
In the most typical GUI way you(in your case) would leak only one location per 5 units. So => 5 leaks per 4 seconds = 75 leaks per minute.
P.s. Those figures depend on how you specify the location, but one thing remains - Create # units at location facing # angle does not leak a unit.
 
Level 18
Joined
Aug 3, 2008
Messages
1,935
the trigger i used was :

Create 1 [Orc Archer] at [spawn region1] facing 270.00 degrees
Order [last created unit] to patrol to [ End Region Orc]

  • Event - Every 4 seconds of time[real]
  • Condition -
  • Action -
    • Create 1 [Beserker] at [spawn region1] facing 270.00 degrees
    • Order [last created unit] to patrol to [ End Region Orc]
    • Create 1 [Beserker] at [spawn region1] facing 270.00 degrees
    • Order [last created unit] to patrol to [ End Region Orc]
    • Create 1 [Orc Soilder] at [spawn region1] facing 270.00 degrees
    • Order [last created unit] to patrol to [ End Region Orc]
    • Create 1 [Orc Soilder] at [spawn region1] facing 270.00 degrees
    • Order [last created unit] to patrol to [ End Region Orc]
    • Create 1 [Orc Archer] at [spawn region1] facing 270.00 degrees
    • Order [last created unit] to patrol to [ End Region Orc]
Are you saying this doesn't it leak at the creation of the unit, then the ordering?

This trigger was basically copy and pasted 5 times for 5 different regions.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
It does not leak :)
Create # [Orc Archer] at [spawn region1] facing 270.00 degrees
Does not leak, because it saves the created unit in a global variable(gj_lastCreateUnit) every time. So to be precise it leaks every time, but the next time cleans up the leak.
And as you have used location variables, there are no location leaks.
 
Level 18
Joined
Aug 3, 2008
Messages
1,935
i see.

thats pretty cool, i didn't know that

correction : 5 leaks for every location ( 1 trigger)
there are 5 different locations ( 25 leaks ) for every 4 seconds.
25 x 15 = 375 leaks per minute according to eleandor

and 0 leacks according to SPiwn

im gonna have to agree with spiwn, because i didn't lag at all.
i had 25 FPS and everything ( except when the armies clashed )
thnx for the help
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Seems to me it does not leak. Because spawn region1 is a global variable. So it uses the same memory every time you call it. Does not allocate another memory, so it won't leak.

I know. Spawn Region 1 looks like a variable, but I assumed - since the trigger he gave was no a cnp but written without world edit - that it wasn't a variable and he was using "center of region".

thedeathunterxx, Will you right click your trigger and press "copy as text", then paste it here? Then we can see the real trigger :)
 
Level 11
Joined
May 31, 2008
Messages
698
Ok Ralle you wer talkin bout destroying special effects and u used "Special Effect - Destroy (Last created special effect)". Now i see that this would work for any special effect that did not last any time but what if you were to make an event where you wanted the special effect to last for something like 10 seconds. Then if the event happened twice within the 10 seconds it would destroy only the "last created special effect" meaning the first one would just stay there and never disapear. So shouldnt you use an array for that too??? Also say a unit has an ability that makes a special effect at a point and that ability can be cast 2 times within the abilities (and special effects) duration. Would it be possible to destroy both effects even tho they were created by the same unit and owned by the same player and in existence at the same time?
 
Level 18
Joined
Aug 3, 2008
Messages
1,935
Here is the exact trigger.

  • ORC Rally 1
    • Events
      • Time - Every 4.00 seconds of game time
    • Conditions
    • Actions
      • Unit - Create 1 Grunt for Player 12 (Brown) at (Center of ACR 1 <gen>) facing Default building facing degrees
      • Unit - Order (Last created unit) to Patrol To (Center of End Region 1 <gen>)
      • Unit - Create 1 Grunt for Player 12 (Brown) at (Center of ACR 1 <gen>) facing Default building facing degrees
      • Unit - Order (Last created unit) to Patrol To (Center of End Region 1 <gen>)
      • Unit - Create 1 Troll Headhunter for Player 12 (Brown) at (Center of ACR 1 <gen>) facing Default building facing degrees
      • Unit - Order (Last created unit) to Patrol To (Center of End Region 1 <gen>)
      • Unit - Create 1 Troll Headhunter for Player 12 (Brown) at (Center of ACR 1 <gen>) facing Default building facing degrees
      • Unit - Order (Last created unit) to Patrol To (Center of End Region 1 <gen>)
      • Unit - Create 1 Grunt for Player 12 (Brown) at (Center of ACR 1 <gen>) facing Default building facing degrees
      • Unit - Order (Last created unit) to Patrol To (Center of End Region 1 <gen>)
 
Level 11
Joined
Dec 31, 2007
Messages
780
Guys... ive found that my map starts lagging like hell when this hero is selected... it is a normal skill that is thrown a lot of times... so i need to know why this leaks... im looking at it... and i see no leaks :S

  • Sagitarius Arrow Movement
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • Set Location3[62] = (Position of Sagitarius_Arrow_Dummy)
      • Set Location3[63] = (Position of Sagitarius_Arrow_Targ)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between Location3[62] and Location3[63]) Greater than or equal to 40.00
        • Then - Actions
          • Set Location3[65] = (Location3[62] offset by 30.00 towards (Angle from Location3[62] to Location3[63]) degrees)
          • Unit - Move Sagitarius_Arrow_Dummy instantly to Location3[65]
          • If (((Current flying height of Sagitarius_Arrow_Dummy) Less than or equal to 300.00) and ((Distance between Location3[62] and Location3[63]) Greater than or equal to 2000.00)) then do (Animation - Change Sagitarius_Arrow_Dummy flying height to ((Current flying height of Sagitarius_Arrow_Dummy) + 100.00) at 200.00) else do (Do nothing)
          • If (((Current flying height of Sagitarius_Arrow_Dummy) Greater than or equal to 200.00) and ((Distance between Location3[62] and Location3[63]) Less than 2000.00)) then do (Animation - Change Sagitarius_Arrow_Dummy flying height to ((Current flying height of Sagitarius_Arrow_Dummy) - 100.00) at 200.00) else do (Do nothing)
          • Custom script: call RemoveLocation(udg_Location3[65])
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Sagitarius_Arrow_Targ is in Spell_Imunity_Group) Not equal to True) and (((Sagitarius_Arrow_Targ is Magic Immune) Not equal to True) and (((Sagitarius_Arrow_Targ is in SleepingGroup) Not equal to True) and (((Sagitarius_Arrow_Targ has buff Eternal Drowsiness ) Not equal to True) and (((Sagitarius_Arrow_Targ has buff Coffin of Ice
            • Then - Actions
              • Unit - Grant shared vision of Sagitarius_Arrow_Targ to (Owner of Sagitarius_Arrow_Dummy)
              • Unit - Order Sagitarius_Arrow_Dummy to Stop
              • Unit - Order Sagitarius_Arrow_Dummy to Human Mountain King - Storm Bolt Sagitarius_Arrow_Targ
              • Wait until (Sagitarius_Arrow_Casted Equal to True), checking every 0.10 seconds
              • Unit - Remove Sagitarius_Arrow_Dummy from the game
              • Unit - Deny shared vision of Sagitarius_Arrow_Targ to (Owner of Sagitarius_Arrow_Dummy)
              • Set Sagitarius_Arrow_Casted = False
              • Trigger - Turn off (This trigger)
              • Trigger - Turn off Sagitarius Arrow Target DIES <gen>
              • Trigger - Turn off Sagitarius Arrow Casted True <gen>
            • Else - Actions
              • Unit - Kill Sagitarius_Arrow_Dummy
              • Set Sagitarius_Arrow_Casted = False
              • Trigger - Turn off (This trigger)
              • Trigger - Turn off Sagitarius Arrow Target DIES <gen>
              • Trigger - Turn off Sagitarius Arrow Casted True <gen>
      • Custom script: call RemoveLocation(udg_Location3[62])
      • Custom script: call RemoveLocation(udg_Location3[63])

Could the problem be the "wait for condition" action?
 
Level 18
Joined
Aug 3, 2008
Messages
1,935
but razorbrain, i did that calculation earlier. And if it were 750
leaks a minute, my map would lag like hell 5 minutes into the game.

It was lagless. The whole game.
i cant explain this connundrum. ( I dont know how to spell that xD)

edit : by the way, he is getting the 5 from the fact that i copyed and pasted
that trigger 5 times. Since their was 5 different locations.
 
Level 11
Joined
Dec 31, 2007
Messages
780
any idea about my leak problem in page 26?


EDIT:

BTW

Ok Ralle you wer talkin bout destroying special effects and u used "Special Effect - Destroy (Last created special effect)". Now i see that this would work for any special effect that did not last any time but what if you were to make an event where you wanted the special effect to last for something like 10 seconds. Then if the event happened twice within the 10 seconds it would destroy only the "last created special effect" meaning the first one would just stay there and never disapear. So shouldnt you use an array for that too??? Also say a unit has an ability that makes a special effect at a point and that ability can be cast 2 times within the abilities (and special effects) duration. Would it be possible to destroy both effects even tho they were created by the same unit and owned by the same player and in existence at the same time?


Use a variable to store the first or the second (or both) special effects (a variable of type special effect)... then use the Special effect- Destroy <variable> Special effect

also can be done with an array... it is up to you
 
Last edited:
Level 12
Joined
Aug 18, 2006
Messages
1,193
darkrider, it could be the Kill Unit action. Its considered a leak by some people becouse the unit isnt correctly removed from the game. It just dies and is assumed to not be removed. Try chaning it to Remove Unit or Add Experation Timer if you need a death animation
 
Level 4
Joined
Aug 9, 2004
Messages
70
Also lagging does not come only from leaks as you may know. If you experiencing the lag problem suddenly after this trigger comes in action, then the problem itself is because the trigger is executing lots of functions and your computer's speed is just not enough. But if you experiencing lag after some time, (need at least 2 or 3 minute is my guess.), this is probably because of the leaks.

So my suggestion here is, Don't use every 0.04 seconds anytime in your game. Maybe it can be used only for systems like knockbacks, and they do stop after a short time too.
 
Level 11
Joined
Dec 31, 2007
Messages
780
the lag comes out after 10 to 20 minutes... increasing by little... first 1 second... then 2 and so on... until it is unplayable...

the only thing that comes to my mind is this skill coz it was a different way before... it use to be just an storm bolt... but i had some problem with blinking heroes that received no damage after blinking... so i did this... it is a unit that flyes (with a golden arrow model) that... when it reaches its target it casts the old ability based in storm bolt ... but i dont know why this leaks like hell... i dont know if it is the kill unit action coz its not casted so many times to create a considerable amount of not-removed units... but it might be... ill think how can i make it with an expiration timer... or maybe just removing it... ill have to test... coz i didnt find any leak in the trigger.... to have an idea... it is almost the same as the clockwerk goblin in dota with its misile (only that i did this trigger before that hero was created xD)

EDIT: I thought it could be the wait for condition action coz ive been told that it was a crappy action but dunno why :p
 
Level 4
Joined
Jul 9, 2008
Messages
36
I dont know if this is a leak but it doesnt work in-game
test it out
-----------
Leak
-/> Events
-Unit - A unit Dies
-Conditions
- Actions
-Unit - Replace [Triggering unit] with a Green Drake,or any other neutral hostile unit, using the old unit's relative life and mana


Start it in-game and kill a peasant and watch what happens
 

Attachments

  • This doesnt work.w3x
    16.2 KB · Views: 102
Top