• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Is there a way to fix Memory Leaks caused by "Pick every unit in Playable map area" in one swoop?

Level 2
Joined
May 26, 2024
Messages
6
I'm pretty much done with my map, but I noticed that its been stuttering a bit most likely because of the "Pick every unit in Playable map area" triggers that i've made. is there a way to for example, maybe clear out the Memory Leaks in one trigger, or am I forced to rewrite all the spaghetti triggers i've made from scratch?

Attached is my map, maybe someone can look if its still possible? or will I need to rewrite almost everything?

Thanks in advance, If i don't reply quickly its probably just busy at work or something.
 

Attachments

  • Winter Assault 2.2 - Hero Siege.w3x
    1.6 MB · Views: 7
Level 45
Joined
Feb 27, 2007
Messages
5,578
Network latency lag, game engine hangs from many costly operations being done inefficiently, pathfinding/movement interruption due to too many units owned by one player, and escalating memory usage caused by memory leaks are all entirely separate phenomena. It is important to understand what is actually happening to address it correctly. I did not look at your map; are you certain this is not a pathfinding issue?

The impact/cost of using Units in Region scales with: the size of the region, the number of units in the region, what exactly you are doing with each unit, and the frequency of the check. For example, periodically looking at every unit in the map just to find 1-5 specific units is likely a terrible idea. In some cases you may truly need to scan the entire map for something, but most of the time you can significantly reduce your overhead by planning ahead with a group variable and then looping over the group. You can add units to these groups as they are created or make some triggers to do it automatically for you. Some logic will also allow you to clear the group of 'useless' units automatically:
  • Events
    • Unit - A unit enters (Playable map area)
  • Conditions
    • (Unit-type of (Triggering Unit)) equal to Wisp
  • Actions
    • Unit Group - Add (Triggering Unit) to WISP_GROUP
  • Unit Group - Pick every unit in WISP_GROUP and do (Actions)
    • Loop - Actions
      • If (All conditions are true) then do (Then actions) else do (Else actions)
        • If - Conditions
          • ((Picked unit) is Dead) equal to False
        • Then - Actions
          • -------- Do whatever here --------
        • Else - Actions
          • Unit Group - Remove (Picked unit) from WISP_GROUP
 
Level 2
Joined
May 26, 2024
Messages
6
I think it might actually be the pathfinding in my map since I have a lot of "When unit enters <REGION> Order them to move to <REGION>. Is there another way to do creep pathing without using a lot of when unit "Enters Region"?

Also, i've tried replacing my existing triggers of selecting all units in the map, here is an example, is it working as expected or is there something i'm missing?
 

Attachments

  • Leak.jpg
    Leak.jpg
    121.7 KB · Views: 7
Level 2
Joined
May 26, 2024
Messages
6
I think it might actually be the pathfinding in my map since I have a lot of "When unit enters <REGION> Order them to move to <REGION>. Is there another way to do creep pathing without using a lot of when unit "Enters Region"?

Also, i've tried replacing my existing triggers of selecting all units in the map, here is an example, is it working as expected or is there something i'm missing?
Also in addition to this, i've also noticed that the lagspikes occured when the WC3 patch dropped because a few days before my map wasn't lagging/stuttering this hard. Not sure if the patch had any effect in the overall performance of the game.
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Running a Playable Map Area pick once every 50 seconds should have no impact on your gameplay unless there are literally thousands of units for it to look at an the map is 480x480. What you have done there is not any different than just picking everything directly, so perhaps you haven't understood the method.

Saving "units in playable map area" into a group variable doesn't help you. Populating the group yourself with the correct units so that you do not have to do the "units in playable map area" search is the thing that saves computation time. You make the group so the game doesn't have to search the whole map for every unit you want. In your case it would look like this:
  • Events
    • Unit - A unit enters (Playable map area)
  • Conditions
    • (Unit-type of (Triggering Unit)) equal to Temple of the Damned
  • Actions
    • Unit Group - Add (Triggering Unit) to T1TempleOfDamned
  • Events
    • Map initialization
  • Conditions
  • Actions
    • Set T1TempleOfDamned = (Units of type Temple of the Damned)
  • Events
    • Time - Every 50.00 seconds of game time
  • Conditions
  • Actions
    • Unit Group - Pick every unit in T1TempleOfDamned and do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (Then actions) else do (Else actions)
          • If - Conditions
            • ((Picked unit) is Dead) equal to False
          • Then - Actions
            • Unit - Create (1 + (PlayerCount / 2)) Necromancer for Player 10 (Light Blue) at T1TempleOfDamnedPoint facing (Default building facing) degrees
          • Else - Actions
            • Unit Group - Remove (Picked unit) from T1TempleOfDamned
Also in addition to this, i've also noticed that the lagspikes occured when the WC3 patch dropped because a few days before my map wasn't lagging/stuttering this hard. Not sure if the patch had any effect in the overall performance of the game.
The patch should have had no impact. It was melee balance adjustments as far as I am aware.
  • Do Nothing is useless and it literally is just a blank function that you are calling for no reason. Don't use it.
  • How to post your trigger

Now, about pathfinding. Such enters region triggers should not be an issue; what usually makes pathfinding bog down is when there are too many units owned by a single player. I think I saw someone in a recent thread suggest limiting each CPU to no more than 60 units at a time (but can't vouch for that number myself), and I would never go above 100. You should instead distribute the CPU units across as many players as is necessary; there are 24 player slots available now in modern WC3 (updating is free; you do not need to own Reforged) and you can forcibly rename and recolor all the CPU players so it looks like just one unified CPU force.

This will mess with overall AI strategic behavior if you are trying to keep an AI in control of the units. It sounds like you're ordering mobs to run a particular path so this likely won't really matter to you?

Since it sounds like you have a bunch of different triggers that spawn variable numbers of units at any given time, I think the best solution for you is going to be just to create a list of 'viable' cpu players that can manage their share of the units and then cycle through them to distribute units as they spawn. Instead of trying to count up to 60 and then swap to the next player, just assign each new unit to the next player in the cycle and keep going through it. Something like this would work:
  • Events
    • Map Initialization
  • Conditions
  • Actions
    • Set AI_Owner = (Player 10 (Light Blue))
    • Set AI_Owner_Name = (Name of AI_Owner)
    • Set AI_Owner_Color = (Color of AI_Owner)
    • Set AI_Players[1] = Player 2 (Blue)
    • Set AI_Players[2] = Player 3 (Teal)
    • Set AI_Players[3] = Player 7 (Green)
    • //...
    • Set AI_Players[10] = Player 17 (Wheat)
    • Set AI_Players_Count = 10
    • Set AI_Current = AI_Players_Count
    • For each (Integer A) from 1 to AI_Players_Count do (Actions)
      • Loop - Actions
        • Player - Set name of AI_Players[(Integer A)] to AI_Owner_Name
        • Player - Change color of AI_Players[(Integer A)] to AI_Owner_Color, Changing color of existing units
        • Player Group - Add AI_Players[(Integer A)] to AI_Group //you would need this if you need to check "is a unit owned by the hostile AI?" since just checking its owning player wouldn't always return AI_Owner
  • Events
    • Unit - A unit enters (Playable map area)
  • Conditions
    • (Owner of (Triggering Unit)) equal to AI_Owner //ALL AI units should be initially spawned for this player
  • Actions
    • Set AI_Current = (AI_Current + 1)
      • If (All conditions are true) then do (Then actions) else do (Else actions)
        • If - Conditions
          • AI_Current greater than AI_Players_Count
        • Then - Actions
          • Set AI_Current = 1
        • Else - Actions
    • Unit - Change owner of (Triggering Unit) to AI_Players[AI_Current] and Change color //technically the change color shouldn't matter
If you need to check that a unit is owned by the AI you would then do this:
  • Conditions
    • ((Owner of THE UNIT) is in AI_Players) equal to True
 
Top