Does this fix the mem leak correctly?

gaskell

Member
Reaction score
0
original trigger
Trigger:
  • spawner
    • Events
      • Time - Timer expires
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in Region 1 1 <gen> matching ((Unit-type of (Matching unit)) Equal to Zerg Spawner)) and do (Actions)
        • Loop - Actions
          • Unit - Create 1 Hydralisk Warrior for (Owner of (Picked unit)) at (Center of Region 1 1 <gen>) facing Default building facing degrees
          • Hero - Modify unspent skill points of (Last created unit): Set to 0 points


New trigger
Trigger:
  • spawner
    • Events
      • Time - Timer expires
    • Conditions
    • Actions
      • Set Tempgroup = (Units in Region 1 1 <gen> matching ((Unit-type of (Matching unit)) Equal to Zerg Spawner))
      • Unit Group - Pick every unit in Tempgroup and do (Actions)
        • Loop - Actions
          • Unit - Create 1 Hydralisk Warrior for (Owner of (Picked unit)) at (Center of Region 1 1 <gen>) facing Default building facing degrees
          • Hero - Modify unspent skill points of (Last created unit): Set to 0 points
      • Custom script: call DestroyGroup (udg_TempGroup)

Is that right?
If so I now know what I'm doing to fix my mem leaks (that i didn't know about until yesterday)
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
889
The idea is correct, but the compiler will probably yell at you a bit:

Set Tempgroup = (
call DestroyGroup (udg_TempGroup)

Notice how the case of the two variables is not the same. You'll need to use udg_Tempgroup if that is the name of the variable.
 

Exide

I am amazingly focused right now!
Reaction score
448
Also, don't forget the point-leaks when creating the unit.
 

gaskell

Member
Reaction score
0
so like this?
Trigger:
  • spawner
    • Events
      • Time - Timer expires
    • Conditions
    • Actions
      • Set SpawnPoint = (Center of Region 1 1 <gen>)
      • Set TempGroup = (Units in Region 1 1 <gen> matching ((Unit-type of (Matching unit)) Equal to Zerg Spawner))
      • Unit Group - Pick every unit in TempGroup and do (Actions)
        • Loop - Actions
          • Unit - Create 1 Hydralisk Warrior for (Owner of (Picked unit)) at (Center of Region 1 1 <gen>) facing Default building facing degrees
          • Hero - Modify unspent skill points of (Last created unit): Set to 0 points
      • Custom script: call DestroyGroup (udg_TempGroup)
      • Custom script: call RemoveLocation (udg_SpawnPoint)

and this repeats for all 25 regions
 

Bogrim

y hello thar
Reaction score
154
"at (Center of Region 1 1 <gen>)" needs to be changed to "at SpawnPoint", using the variable instead.

You need to understand the reason for memory leaks in order to fix them. When you choose a location or a group as reference for your action, you use something called a "handle". A handle is basically data tied to objects in the game that allow the game to put your triggers to work. Something like a location is just a coordinate ("35.432, 4564.325") stored in the game's memory. The problem here is if the game will generate the data if it's not already generated.

Let's take an example: Imagine you're creating two special effects at a target location. Each of your lines go, "Create effect at (target point of ability being cast)". The game generates the corresponding coordinate each time you use the line, creating the same coordinate twice. The coordinates remain in the game's memory, never to be used again and taking up unnecessary processing power. If enough data "leaks" this way, the game will start to lag from the amount of loose memory clustering up.

To avoid memory leaks we use variables. As I said in the bolded line, the game doesn't generate any data if it's already generated. Just using a handle once will generate the object data, and the variable serves as a link to that object ("spawnpoint = center of region"). Use the link when you need to refer to an object and remove the variable's attached data after use.

The tricky part is knowing when to use a variable, and the easiest way to avoid it is basically to always use a variable whenever you can choose to use a variable.
 

gaskell

Member
Reaction score
0
This is turning into a long and confusing trigger but I have to learn this. Theres no way I want to display the whole trigger as its HUGE.
But this first section should be leakproof.
Trigger:
  • spawner
    • Events
      • Time - Timer expires
    • Conditions
    • Actions
      • Set SpawnPoint = (Center of Region 1 1 &lt;gen&gt;)
      • Set TempGroup = (Units in Region 1 1 &lt;gen&gt; matching ((Unit-type of (Matching unit)) Equal to Zerg Spawner))
      • Unit Group - Pick every unit in TempGroup and do (Actions)
        • Loop - Actions
          • Unit - Create 1 Hydralisk Warrior for (Owner of (Picked unit)) at SpawnPoint facing Default building facing degrees
      • Set LastUnit = (Units in Region 1 1 &lt;gen&gt;)
      • Unit Group - Pick every unit in LastUnit and do (Actions)
        • Loop - Actions
          • Hero - Modify unspent skill points of (Picked unit): Set to 0 points
      • Custom script: call DestroyGroup (udg_LastUnit)
      • Custom script: call DestroyGroup (udg_TempGroup)
      • Custom script: call RemoveLocation (udg_SpawnPoint)

Is that correct?
Also instead of having this trigger repeat each region is there a way I can simplify this? At the moment directly under the last pictured action the next one starts for region "Region 1 2" then for the rest of my regions (1 3, 1 4, 1 5, 2 1, etc etc) the regions are named due to the postioning of each island which are set out in a 5x5 grid.
 

Bogrim

y hello thar
Reaction score
154
The "LastUnit" group is unnecessary - you can set the unit's skill points right after creation as you did before. However, the trigger is fine in its current form as well.

What you can do is create a Region Variable Array and save all your regions to that array in your map initialization, then run a loop using the array index to properly refer to every region saved. For example:
Trigger:
  • Actions
    • For each (Integer A) from 1 to 25, do (Actions)
      • Loop - Actions
        • Set TempPoint = (Center of Region_Array[(Integer A)])
        • Set TempGroup = (Units in Region_Array[(Integer A)] matching ((Unit-type of (Matching unit)) Equal to Zerg Spawner))
        • Unit Group - Pick every unit in TempGroup and do (Actions)
          • Loop - Actions
            • Unit - Create 1 Hydralisk Warrior for (Owner of (Picked unit)) at TempPoint facing Default building facing degrees
            • Hero - Modify unspent skill points of (Last created unit): Set to 0 points
        • Custom script: call RemoveLocation( udg_TempPoint )
        • Custom script: call DestroyGroup( udg_TempGroup )
 

gaskell

Member
Reaction score
0
nice ok so things like "last created unit", "Picked unit" and "triggering unit" are all good but an imaginary point or unit group, player group or something like that is when you need the integer system in place...
How do you do the array?
I guess you make an variable type "region", tick array and set size to 25? but how do i add my regions to that array?
This I could really use as using arrays would massively reduce the size of almost all my triggers (and make it easier and faster to edit and create)


EDIT:
I got it set variable then the number of the array location (0-25) so there is 25 set variable actions right at the bigining of the map where I create my timer windows and blah blah.
omg that little bit of advice shrunk a 2page trigger into a few lines.
Thankyou is not enough but will have to do :p
 

Bogrim

y hello thar
Reaction score
154
You could "destroy" units to save memory, but that would remove the unit from the game. Units are also automatically removed from the game when their corpse expires.

On the other hand you have something like a special effect. Even if the effect only plays its animation once (like Frost Nova or Thunder Clap), the effect is still there until destroyed. You could think of every object like a unit, you create it and you have to remove it when it no longer serves a purpose.
 

gaskell

Member
Reaction score
0
ok this is getting really heavy now :p
Ive created an array for abilities and assigned 8 aura abilities to it (0-7) and all the creation stuff and blah blah with the array is sweet (once again saves me mass editing to remove mem leaks)....
Now I want to remake my trigger for removing or decreasing the lvl of the ability on a specific unit depending on which ability the dieing unit has...
so if a unit (buff tower) dies and has ability (devotion aura) at lvl1, the the specific unit (buff tower trigger) loses the ability (devotion aura). BUT if the level of ability (devotion aura) is greater than 1, I want the ability on the specific unit (buff tower trigger) to be reduced by one.
now I currently have a huge trigger that does this:
Trigger:
  • buff tower death
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Buff Tower
    • Actions
      • Set TowerDeath = (Units owned by (Owner of (Triggering unit)) of type Buff Tower trigger)
      • Unit Group - Pick every unit in TowerDeath and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Devotion Aura for (Picked unit)) Equal to 1
            • Then - Actions
              • Unit - Remove Devotion Aura from (Picked unit)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Devotion Aura for (Picked unit)) Greater than 1
                • Then - Actions
                  • Unit - Decrease level of Devotion Aura for (Picked unit)
                • Else - Actions
      • Custom script: call DestroyGroup (udg_TowerDeath)

For each ability.
But I want to change the devotion aura to AbilityArray[X] (X being a number 0-7) but cant figure out exactly how to loop this so it will only remove the one ability from the "buff tower trigger" unit that matches the ability the dieing unit has.
My brain is feeling a bit fried now but the following should work (I hope) and not cause leaks:
Trigger:
  • buff tower death
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Buff Tower
    • Actions
      • Set TowerDeath = (Units owned by (Owner of (Triggering unit)) of type Buff Tower trigger)
      • For each (Integer A) from 0 to 7, do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in TowerDeath and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of AbilityArray[(Integer A)] for (Picked unit)) Equal to 1
                • Then - Actions
                  • Unit - Remove AbilityArray[(Integer A)] from (Picked unit)
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Level of AbilityArray[(Integer A)] for (Picked unit)) Greater than 1
                    • Then - Actions
                      • Unit - Decrease level of AbilityArray[(Integer A)] for (Picked unit)
                    • Else - Actions
                      • Trigger - Run (This trigger) (checking conditions)
      • Custom script: call DestroyGroup (udg_TowerDeath)
 

luorax

Invasion in Duskwood
Reaction score
67
Yeah, fixing memory leaks is a bit boring action with trigger, that's why i decided to learn JASS. I downloaded the JASS NewgenPack (some week ago i found a new, better pack, the JASS NewGenPack Experemental), read JASS tutorials, etc. Now, i work on my mortal kombat map, with a quite good hero selector, and Arena system, with a lot of ability etc. Everything was made in JASS (the systems in vJASS). It's more simply, more powerful, the things you need: the jassnewgen pack and practice.
Fixing memory leaks is more simply in JASS:
In GUI you have to select the action, the variable, it's new value, etc. In JASS, you can simply type" call RemoveLocation( tl )" and you're done. (tl is a local variable, so that doesn't need "udg_")

I'm sorry the offing, just wanted to tell me this :D
 

gaskell

Member
Reaction score
0
Yea I've been contemplating it but I know it will be a lot to learn. I'm only just learning about loops and arrays at the moment.
 

luorax

Invasion in Duskwood
Reaction score
67
know it will be a lot to learn.

No, I don't think so. For example: creating a loop in JASS is:

JASS:
loop
    exitwhen XYZ == ZYX
    call &lt;Some Function&gt;
endloop


If you have big trigger with loops, waits etc, what uses a variable to store things, you can't add the ability to more than 1 unit, because the next cast will modify the variables, and the old last cast will use it. An example:

If you cast the ability "A" with the unit "U" in the center of the map, what moves the unit from "A" to "B" and cast it again with the unit "U2" at the edge of th map, then "U" is going to move to the position of "U2". You can avoid this using arrays, etc, bit it's a bit harder work, and it's very very boring. In JASS with local variables there're not any problems: the variables are dynamic, you don't need arrays, or anything, every cast has its part.

Learning JASS... Learning the basics was not too hard, but there were 1-2 thing what was quite hard to understand for me (for example the returns) because I didn't learn any program language. I suggest you to try to move from Gui to JASS after learnt what you wanted about loops, etc. As I said: it's more easy, more powerful :D
 

gaskell

Member
Reaction score
0
yea currently when I see the Jass script like what you posted I kinda o_O ummmm. Like it kinda see that some commands are easy but most of it is, well, another language heh heh. But yea I reckon I could do a lot more if I learnt it. So many ideas I have that are limited by the GUI.
 

luorax

Invasion in Duskwood
Reaction score
67
Haha, I know what you said :D When I read the first JASS tutorials I thought exactly what you :D But by the god, the tutorials were simple, contained challanges, etc, so I could follow them in JASS with my editor. And I learnt it. (No, I didn't, I learnt much thing, but now everything... for example, I know nothing about structures [okay, i know a bit about them :D], but i will sit down, and learn it, when I will have enough time. But I think I can make everything what I want)

I don't want to make you to learn anything, what you don't want, I think JASS is much better, but it's my opinion. If you think that GUI is better, and you can remove leaks, etc, then use it, nobody cares how did you make it, the most player want to enjoy the map, not to analyze it :D (I'm not in the "most player" :D)
 
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