• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Leak Help

Status
Not open for further replies.
Level 8
Joined
Jun 16, 2008
Messages
333
I made a map and I think it leaks bad but I don't know how to fix leaks. I look at so many tutorials and tried to use a few programs that didn't want to open so I am asking if you can help me with cleaning my map up. If you can I will give you the map and + rep as well as thanks to"name here" in my map.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
Leaks are pretty simple.

Imagine eating from a new plate every time you are hungery. Instead of putting the plates to be washed (destroying them) you smash them on the floor (leaking them). As they are smashed they can no longer be used (leaked data is usless and surves no purpose) and additionally you can no longer wash them as they have been smashed (you can not clean up leaks in warcraft 3 after they have occured). Eventually you will run out of clean dishes (resources to play the game smoothly) as you have been smashing them (leaking them) and so no longer be able to eat (game is unplayable).

The process of smashing the plates transcribes to leaking, where you losing all references to a nolonger useful object you created via a trigger script. As such you can not remove the leak, can no longer use the object (make it useful againt) and can no longer free up the resources it used.

The process of fixing leaks is such.
When you eat off a plate (using an object), instead of smashing it you put it to be washed (to be destroyed to free up its resources). Eventually you do the washing up (destroy the objects thus freeing the resources) so the plates can be used again to eat off (the resources have been freed and can be reused by new objects). As you are always cleaning the plates you eat off (your map does not leak), you will never run out of clean plates (resources to run the game) and so you can continue eating happily (map plays smoothly with no lag).

Common leaks are force (player groups), group (unit groups), location (points) and effect (special effects). Only Special Effects have GUI destructors, all others must use custom script to axcess their destructors. These objects will always leak unless you store them in a variable and eventually destroy them before overweiting their reference with a new object of the same type.

The process goes like this in pesudo code.
1. Make and set up group.
2. Use group.
3. Destroy group.

The 2 most common ones to remember are.
call DestroyGroup(variablenamegoeshere)
call RemoveLocation(variablenamegoeshere)

When referencing GUI variables (globals) they will always have a udg_ prefix. Thus a variable called POINT in GUI will have its stored object removed with this line of code.
call RemoveLocation(udg_POINT)
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

Actually not. For example you have a variable "TempLoc" ( Point variable ).
If you use it and destroy it in the same trigger without any wait, you can use it always.

Else you can Jass - there you can locals but you will need some skill with Jass.

If you use a variable and destroy it after a "wait - time" you have to use different variables, because else it can be buggy.

Greetings
~ The Bomb King > Dr. Boom
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

Actually it's so simple, but lets make an example:

Ex 1: You can create unit and that unit should move to another point:
  • Trig1
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of Rect A <gen>) facing Default building facing (270.0) degrees
      • Unit - Order (Last created unit) to Move To (Center of Rect B <gen>)
This example leaks twice: "Center of Rect A" and "Center of Rect B".. to clear this we use 2 variables:

  • Trig1
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • Set TempLoc1 = (Center of Rect A <gen>)
      • Set TempLoc2 = (Center of Rect B <gen>)
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of Rect A <gen>) facing Default building facing (270.0) degrees
      • Unit - Order (Last created unit) to Move To (Center of Rect B <gen>)
      • Custom script: call RemoveLocation(udg_TempLoc1)
      • Custom script: call RemoveLocation(udg_TempLoc2)
Now: You can use the TempLoc1 and/or TempLoc2 in any other trigger like this. Because between the Set TempLoc ... and call RemoveLocation is no
  • Wait x.xx seconds

  • Trig1
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • Set TempLoc1 = (Center of Rect A <gen>)
      • Set TempLoc2 = (Center of Rect B <gen>)
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of Rect A <gen>) facing Default building facing (270.0) degrees
      • Unit - Order (Last created unit) to Move To (Center of Rect B <gen>)
      • Custom script: call RemoveLocation(udg_TempLoc1)
      • Custom script: call RemoveLocation(udg_TempLoc2)
  • Trig2
    • Events
      • Time - Elapsed game time is 5.01 seconds
    • Conditions
    • Actions
      • Set TempLoc1 = (Center of Rect C <gen>)
      • Set TempLoc2 = (Center of Rect D <gen>)
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of Rect A <gen>) facing Default building facing (270.0) degrees
      • Unit - Order (Last created unit) to Move To (Center of Rect B <gen>)
      • Custom script: call RemoveLocation(udg_TempLoc1)
      • Custom script: call RemoveLocation(udg_TempLoc2)

  • Trig1
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
    • Actions
      • Set TempLoc1 = (Center of Rect A <gen>)
      • Set TempLoc2 = (Center of Rect B <gen>)
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of Rect A <gen>) facing Default building facing (270.0) degrees
      • Unit - Order (Last created unit) to Move To (Center of Rect B <gen>)
      • Wait 1.00 seconds
      • Custom script: call RemoveLocation(udg_TempLoc1)
      • Custom script: call RemoveLocation(udg_TempLoc2)
  • Trig2
    • Events
      • Time - Elapsed game time is 5.01 seconds
    • Conditions
    • Actions
      • Set TempLoc1 = (Center of Rect C <gen>)
      • Set TempLoc2 = (Center of Rect D <gen>)
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of Rect A <gen>) facing Default building facing (270.0) degrees
      • Unit - Order (Last created unit) to Move To (Center of Rect B <gen>)
      • Custom script: call RemoveLocation(udg_TempLoc1)
      • Custom script: call RemoveLocation(udg_TempLoc2)


Actually it works, but the first trigger can't remove the TempLoc's because another trigger use the same variables, so there are "gone" from the first trigger.

Greetings
~ The Bomb King > Dr. Boom
 
Level 13
Joined
Mar 4, 2009
Messages
1,156
1.)
for any Points you must create a variable
for example:
Variable Type Point called "COOKIE"

set Cookie = (Your Point)
<now you can use this Cookie point as meny times you want but you must not set it to another point before removeing it with this>
Custom Script: call RemoveLocation(udg_Cookie)
3.)
so it means you can do this:

set Cookie = (position of Snake)
<use Cookie point for anything you want>
Custom Script: call RemoveLocation(udg_Cookie)
set Cookie = (position of Bear)
<use Cookie point for anything you want>
Custom Script: call RemoveLocation(udg_Cookie)

4.)
the same is for other leaks,here are the custom scripts

call DestroyForce(udg_NameofYourPlayerGroup)
call DestroyGroup(udg_NameofYourUnitGroup)
call DestroyLocation(udg_NameofYourUnitPoint)
5.)
effects do leak every time they are created,you have to destroy the created effect every time,or you can use dummy unit with model file of your effect
 
Level 8
Joined
Jun 16, 2008
Messages
333
Ok so I have these triggers... would work like this?
  • Trees 1
    • Events
      • Unit - A unit enters Region 000 <gen>
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Demon Hunter
    • Actions
      • Set TempLocA = (Center of Region 000 <gen>)
      • Set TempLocB = (Center of Region 004 <gen>)
      • Destructible - Remove Cityscape Fall Tree Wall 0000 <gen>
      • Environment - Change terrain type at (Center of Region 004 <gen>) to Cityscape - Brick using variation -1 in an area of size 1 and shape Square
      • Environment - Change terrain type at (Center of Region 000 <gen>) to Cityscape - Brick using variation -1 in an area of size 1 and shape Square
      • Environment - Create a 10.00 second Depression ripple deformation at (Center of Region 000 <gen>) with starting radius 500.00, ending radius 500.00, and depth 64.00, using 1.00 second ripples spaced 512.00 apart
      • Custom script: call RemoveLocation(udg_TempLocA)
      • Custom script: call RemoveLocation(udg_TempLocB)
      • Trigger - Turn off (This trigger)
  • Trees 1 Copy
    • Events
      • Unit - A unit enters Region 001 <gen>
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Demon Hunter
    • Actions
      • Set TempLocA = (Center of Region 007 <gen>)
      • Set TempLocB = (Center of Region 001 <gen>)
      • Destructible - Remove Cityscape Fall Tree Wall 0001 <gen>
      • Environment - Change terrain type at (Center of Region 007 <gen>) to Cityscape - Brick using variation -1 in an area of size 1 and shape Square
      • Environment - Change terrain type at (Center of Region 001 <gen>) to Cityscape - Brick using variation -1 in an area of size 1 and shape Square
      • Environment - Create a 10.00 second Depression ripple deformation at (Center of Region 001 <gen>) with starting radius 500.00, ending radius 500.00, and depth 64.00, using 1.00 second ripples spaced 512.00 apart
      • Custom script: call RemoveLocation(udg_TempLocA)
      • Custom script: call RemoveLocation(udg_TempLocB)
      • Trigger - Turn off (This trigger)
and
  • Move 1
    • Events
      • Unit - A unit enters Region 022 <gen>
    • Conditions
      • (Triggering unit) Equal to Crypt Fiend 0016 <gen>
    • Actions
      • Set TempLocA = (Center of Region 020 <gen>)
      • Unit - Order (Triggering unit) to Move To (Center of Region 020 <gen>)
      • Custom script: call RemoveLocation(udg_TempLocA)

Would all this work with the same variable... plus with dodads do i have to do it?
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

You did a mistake: In the actions like "Environment - Change terrain type at (Center of Region 004 <gen>) to Cityscape - Brick using variation -1 in an area of size 1 and shape Square" don't use "Center of Region 004" use the variable you set for this!
So look like this:
  • Environment - Change terrain type at (TempLocA) to Cityscape - Brick using variation -1 in an area of size 1 and shape Square
Else it will work with the same variable, because ( as I said ) if there are no wait time between the variable creation and the removing, you can use the same variables.

Greetings
~ The Bomb King > Dr. Boom
 
Level 8
Joined
Jun 16, 2008
Messages
333
Moin=)

Then does that mean I have to do it with the
  • Move 1
    • Events
      • Unit - A unit enters Region 022 <gen>
    • Conditions
      • (Triggering unit) Equal to Crypt Fiend 0016 <gen>
    • Actions
      • Set TempLocA = (Center of Region 020 <gen>)
      • Unit - Order (Triggering unit) to Move To (Center of Region 020 <gen>)
      • Custom script: call RemoveLocation(udg_TempLocA)
?? and how would I do it for
  • Check Point 1 Copy
    • Events
      • Unit - A unit enters Region 064 <gen>
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Demon Hunter
    • Actions
      • Game - Display to (All players) the text: (|cff995500You guys better thank|r + (|cffFFFFFF + ((Name of (Owner of (Triggering unit))) + |r)))
      • Unit Group - Pick every unit in (Units of type Demon Hunter) and do (Unit - Kill (Picked unit))
      • Player Group - Pick every player in (All players) and do (Camera - Pan camera for (Picked player) to (Center of Region 064 <gen>) over 0.00 seconds)
      • Wait 2.00 seconds
      • Unit Group - Pick every unit in (Units of type Demon Hunter) and do (Hero - Instantly revive (Picked unit) at (Center of Region 064 <gen>), Show revival graphics)
      • Hero - Set (Triggering unit) Hero-level to 5, Hide level-up graphics
      • Environment - Change terrain type at (Center of Region 064 <gen>) to Cityscape - Grass using variation -3 in an area of size 3 and shape Square
      • Trigger - Turn off Slide 1 <gen>
      • Trigger - Turn off (This trigger)
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

Sorry, but if I see this, I see that you didn't understand it well ...

Look at your trigger:
  • Events
    • Unit - A unit enters Region 022 <gen>
  • Conditions
    • (Triggering unit) Equal to Crypt Fiend 0016 <gen>
  • Actions
    • Set TempLocA = (Center of Region 020 <gen>)
    • Unit - Order (Triggering unit) to Move To (Center of Region 020 <gen>)
    • Custom script: call RemoveLocation(udg_TempLocA)
You set the TempLocA variable but you don't use it and this is fail. This trigger should look like this:

  • Events
    • Unit - A unit enters Region 022 <gen>
  • Conditions
    • (Triggering unit) Equal to Crypt Fiend 0016 <gen>
  • Actions
    • Set TempLocA = (Center of Region 020 <gen>)
    • Unit - Order (Triggering unit) to Move To (TempLocA)
    • Custom script: call RemoveLocation(udg_TempLocA)
And about your second trigger you just use you can use this:
  • Trigger2104
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to (==) Demon Hunter
    • Actions
      • Set TempLocB = (Center of MyTestRect <gen>)
      • Game - Display to (All players) the text: xxx
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units of type Demon Hunter) and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Camera - Pan camera for (Picked player) to TempLocB over 0.00 seconds
      • Wait 2.00 seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units of type Demon Hunter) and do (Actions)
        • Loop - Actions
          • Hero - Instantly revive (Picked unit) at TempLocB, Show revival graphics
      • Environment - Change terrain type at TempLocB to Lordaeron Summer - Dirt using variation -1 in an area of size 1 and shape Circle
      • Custom script: call RemoveLocation(udg_TempLocB)
In this trigger you have to use a variable, that you ONLY USED IN THIS TRIGGER, because between the creation and the Removing is a wait time.

Edit: Before you do an action with "Unit Group - Pick every unit ....." do another action BEFORE it
"Custom script: set bj_wantDestroyGroup = true", to clear the unit group leak. [Unit group gets destroy AFTER! it's used.]

Greetings
~ The Bomb King > Dr. Boom
 
Level 14
Joined
Aug 30, 2004
Messages
909
As long as we're on the topic, i wonder if you could tell me if this leaks:

Set tempPoint = position of triggering unit
Set tempPoint = tempPoint offset by 30 toward facing angle of triggering unit
custom script: destroy tempPoint
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
Cause he obviously has no idea about programming at all. I guess we all have to start from somewhere so keep in mind below is a prety universal concept.

A variable is like a box that can hold exactly 1 item or value in it at a time.

Set tempPoint = position of triggering unit
This makes tempPoint the position of triggering unit.
Set tempPoint = tempPoint offset by 30 toward facing angle of triggering unit
This makes tempPoint hold an offset position but as tempPoint has a value the old value is discarded causing a location leak. Basically as a box can only hold 1 value, it must discard the old value inorder for a new one to be put in and since the discarded value is a pointer to a location it causes a leak as the location can no longer be referenced and is nolonger useful
custom script: destroy tempPoint
This removed causes a syntax error on map save. It should be...
custom script: call RemoveLocation(udg_tempPoint)
 
Level 8
Joined
Jun 16, 2008
Messages
333
Edit: Before you do an action with "Unit Group - Pick every unit ....." do another action BEFORE it
"Custom script: set bj_wantDestroyGroup = true", to clear the unit group leak. [Unit group gets destroy AFTER! it's used.]


Ok with that do I have to make a variable with it or I can just leave it? I took of the wait so what is now possible?
 
Level 14
Joined
Aug 30, 2004
Messages
909
Um... Why use of only one variable for two different stuff?

I want to get the Point variable to point to next to a unit. So I need the unit's location, and then another point which is that location offset by 30 in some direction. It saves variable space if I just have 1 variable. I first set the variable to the unit's location, then I set it to itself offset by 30 in some direction.
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)


In this following trigger I create unit group leak for you.
  • UnitGrp Leak
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units of type Footman) and do (Unit - Remove (Picked unit) from the game)
Ok now we have two ways to fix the unit group leak
1) You can use a custom script before you Pick every unit and this custom script will destroy the unit group after all actions in the group are done:
  • UnitGrp Leak
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units of type Footman) and do (Unit - Remove (Picked unit) from the game)
2) You can fix this leak with a variable and a custom script like this:
  • UnitGrp Leak
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Set TempGrp = (Units of type Footman)
      • Unit Group - Pick every unit in TempGrp and do (Unit - Remove (Picked unit) from the game)
      • Custom script: call DestroyGroup(udg_TempGrp)
You can choose yourself! what way you want, some people say the first is better, other the second is better, so whatever, take what you want ^^




Yes the leak to and you can fix like that:
  • !!!Sound without wait!!!
    • Events
    • Conditions
    • Actions
      • Sound - Play (Your Sound)
      • Sound - Destroy (Last played sound)
  • !!!Effect without wait!!!
    • Events
    • Conditions
    • Actions
      • Set TempLoc = (Center of (Playable map area))
      • Special Effect - Create a special effect at TempLoc using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_TempLoc)
You have to put the "Destroy part" directly after you create the sound/effect. The sound is destroyed after it's played and the effect is destroyed after 5 seconds.


Again I have to say as a notice [ all good things are 3^^]: If there is a waittime between the creation of the variable and the destroying of the variable, use UNIQUE variables only for this trigger, else it's buggy!!


Points: call RemoveLocation(udg_variable)
Units: set variable = null
Real: set variable = 0.00
Integer: set variable = 0
Unitgroup 1: set bj_wantDestroyGroup
Unitgroup 2: call DestroyGroup(udg_variable)
Sound and effects: See above


Greetings
~ The Bomb King > Dr. Boom
 
Level 8
Joined
Jun 16, 2008
Messages
333
With Player Groups how do you pick all of them so they get all chosen? I have this trigger right here.
  • Alliance Start
    • Events
      • Time - Elapsed game time is 8.00 seconds
    • Conditions
    • Actions
      • Set Alliance_grp = (All allies of Player 2 (Blue))
      • Player Group - Pick every player in Alliance_grp and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Random player from Alliance_grp) controller) Equal to User
              • ((Random player from Alliance_grp) slot status) Equal to Is playing
            • Then - Actions
              • Set Alliance_Loc = (Center of Alliance Start <gen>)
              • Unit - Create 1 Unit Selector for (Random player from Alliance_grp) at Alliance_Loc facing Default building facing degrees
              • Custom script: call RemoveLocation(udg_Alliance_Loc)
            • Else - Actions
      • Custom script: call DestroyForce(udg_Alliance_grp)
 
Level 13
Joined
Mar 4, 2009
Messages
1,156
With Player Groups how do you pick all of them so they get all chosen? I have this trigger right here.
  • Alliance Start
    • Events
      • Time - Elapsed game time is 8.00 seconds
    • Conditions
    • Actions
      • Set Alliance_grp = (All allies of Player 2 (Blue))
      • Player Group - Pick every player in Alliance_grp and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Random player from Alliance_grp) controller) Equal to User
              • ((Random player from Alliance_grp) slot status) Equal to Is playing
            • Then - Actions
              • Set Alliance_Loc = (Center of Alliance Start <gen>)
              • Unit - Create 1 Unit Selector for (Random player from Alliance_grp) at Alliance_Loc facing Default building facing degrees
              • Custom script: call RemoveLocation(udg_Alliance_Loc)
            • Else - Actions
      • Custom script: call DestroyForce(udg_Alliance_grp)

use (Picked Player) instead (Random player from Alliance_grp) -.-
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

First of all agree to: ALiEN95 - use (picked unit)

Second: you talk about a leak ... wondering there's no leak in this trigger.

You create a PlayerGroup Variable and clear it after using. I think you mean the location? In this case everything is fine.

The way how your trigger works: ( Maybe for better understanding)

1) First of all you set the group.

2) After you pick the players in the group and filter them with your conditions.

3) Now a TempLoc is created for ONE filtered player, the unit is created for THIS player and the location is removed for THIS player.

4) Only then the trigger starts to do the same process for the other players who are left.

5) And after this is done for every player inside the filtered Group, the group is destroyed.

Greetings
~ The Bomb King > Dr. Boom
 
Status
Not open for further replies.
Top