• 🏆 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!

What am I doing wrong (leaks)

Status
Not open for further replies.

Rei

Rei

Level 2
Joined
May 26, 2015
Messages
9
Hello.

A few months ago, I decided to learn the world editor. Ive used hive a lot, reading through tutorials and all.

I have checked the leaks tutorials, but the below trigger still leaks for a reason i cannot wrap my head around.

Killing around ~1500 units created with this trigger will gradually drop my framerate to around 2 FPS, but the trickiest part is it WILL actually go back to a decent 25 fps after some time, then drop BACK (without any actions taken during this time) to 2 FPS. Then it will just keep fluctuating. (explanation isn't very clear, but it's the best i could do to try to capture the symptoms).

(also, note that warcraft 3's memory only shows an increase of ~150 mb, from 150 to 300 during this whole procedure. Much less than it would usually take for an application to clog my computer's memory).

Anyways, here's the trigger:

  • ScuttlerSpawn1
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Set Temp_Group = (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to Scuttler))
      • Set tempPoint = (Random point in Scuttler Den 1 <gen>)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in Temp_Group) Greater than or equal to 15
        • Then - Actions
        • Else - Actions
          • Unit - Create 1 Scuttler for Neutral Hostile at tempPoint facing (Random angle) degrees
      • Custom script: call DestroyGroup (udg_Temp_Group)
      • Custom script: call RemoveLocation(udg_tempPoint)
Any help would be beyond appreciated ~
 
Level 9
Joined
Apr 23, 2011
Messages
527
try setting (Playable map area) to a point variable before setting the unit group.
optional, set (Number of units in Temp_Group) to an integer variable, i don't think it'd help though.
 

Rei

Rei

Level 2
Joined
May 26, 2015
Messages
9
Thanks for the reply.

I get the jist of the (units in playable map area) might be causing the leak, but how would i go about setting a region to a point? Or should I create a region variable and then force remove that? Thanks.

Edit: Point with size?
 

Rei

Rei

Level 2
Joined
May 26, 2015
Messages
9
  • ScuttlerSpawn1
    • Events
      • Time - Every 0.05 seconds of game time
    • Conditions
    • Actions
      • Set tempPoint2 = (Center of Scuttler Den 1 <gen>)
      • Set tempRegion = (Region centered at tempPoint2 with size (700.00, 700.00))
      • Set Temp_Group = (Units in tempRegion matching ((Unit-type of (Matching unit)) Equal to Scuttler))
      • Set tempPoint = (Random point in tempRegion)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in Temp_Group) Greater than or equal to 15
        • Then - Actions
        • Else - Actions
          • Unit - Create 1 Scuttler for Neutral Hostile at tempPoint facing (Random angle) degrees
      • Custom script: call DestroyGroup (udg_Temp_Group)
      • Custom script: call RemoveRect(udg_tempRegion)
      • Custom script: call RemoveLocation(udg_tempPoint)
      • Custom script: call RemoveLocation(udg_tempPoint2)
Noticed a slight improvement with this setup. Maybe I should scale down the amount of enemies but scale their strength up. Not certain if its possible with wc3 to mow down hordes upon hordes of foes without interruption *sigh*
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Two possible causes for bad performance.
1. Creating units on top of other units performs a displacement finding operation. If the area is crowded this can consume significant resources causing frames to be dropped.
2. You are testing every unit on the map 5 times a second. If there are 1,000 units that is 5,000 tests being done per second. This does not scale very well and can easily cause frames to be dropped.

To fix 1 try spawning them randomly in an area. Also make sure the area is mostly/entirely pathable for that unit type. This makes the displacement algorithm work less hard and use fewer resources.

To fix 2 try manually keeping track of how many of such unit exist at any given time. When you create them add them to a group. When they die remove them from the group. Counting efficiency could be improved (GUI uses O(n) complexity counter for unit groups) by keeping track of the number in a integer variable as you add or remove units from the group.

As far as I can see it should not be leaking.
 

Rei

Rei

Level 2
Joined
May 26, 2015
Messages
9
Ahhhhh. There's some insight. Yes, i might have been overcrowding areas during testing. The timer should not be anywhere near set to this frequency, however since i was certain this was the trigger causing leaks and I wanted to check the number of units it had to go through for the leak to become significant. However, If there really should be no leaks from this trigger, it might very well be another area that is causing problem over time. My map's mechanics are mostly finished but I only discovered the existence of leaks very late into the working process so.... *starts digging*

Thanks a bunch.

Edit: will try the solution for 2, see if that works.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Be aware that creating any unit might leak a small amount. Memory usage generally trends upwards as units are created and removed. Some report that the game eventually "garbage collects" and memory usage from the unit leak drops down however I have never experienced this.

There is no fix to this sort of leak. Instead it is recommended to keep the number of units created per session reasonable. A reasonable amount would be 5,000 odd.

Also be aware that units which die will only be removed after they "decay" which can take several minutes depending on settings. This can cause performance dips in the case of continuous unit creation and destruction.
 

Rei

Rei

Level 2
Joined
May 26, 2015
Messages
9
That taugh me quite a bit, appreciate it. My laptop isn't very powerful, which is probably why 1: the pileup of the garbage can become apparent to me very fast and 2: my poor initial knowledge when mapmaking isn't helping the case. Anyways, I thank you, and im already removing units on-death is that is any help.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
My laptop isn't very powerful
The performance could also be the result of overheating. This is why it gets better and worse rather randomly. Laptops generally have a processor more powerful than the cooling system can cope with to allow for burst performance when required. When you play games it continuously uses such performance resulting in the CPU reaching threshold temperatures. To prevent damage it reduces CPU clock speed to an extent the cooling can cope.

When operating at full clock speed the game will perform a lot better than when operating at reduced clock speed.

Additionally when you unplug the laptop from the power supply it will reduce clock speed to provide more energy efficiency. Hence why you should only play games when it is plugged in.
 
Level 12
Joined
May 22, 2015
Messages
1,051
You could also try not creating everything and deleting everything each time.

  • init
    • Events
      • Map Initialization
    • Conditions
    • Actions
      • Set scuttlerDenCenter = (Center of Scuttler Den 1 <gen>)
      • Set denRegion = (Region centered at scuttlerDenCenter with size (700.00, 700.00))
      • Set Permanent_Group = (Units in denRegion matching ((Unit-type of (Matching unit)) Equal to Scuttler))
  • ScuttlerSpawn1
    • Events
      • Time - Every 0.05 seconds of game time
    • Conditions
      • (Number of units in Permanent_Group) Less than 15
    • Actions
      • Set tempPoint = (Random point in denRegion)
      • Unit - Create 1 Scuttler for Neutral Hostile at tempPoint facing (Random angle) degrees
      • Unit Group - Add (Last Created Unit) to Permanent_Group
      • Custom script: call RemoveLocation(udg_tempPoint)
This would break if scuttlers are made by something else or if they are expected to leave the region you are spawning them, but I think you can use Enters Region and Leaves Region events to detect those. You'd probably also need to have a trigger to remove them when they die (not sure if completely decayed units get removed or not).

EDIT:
I just want to also ask on thing:
Did you mean to be doing it only when there are 15 or more scuttlers? I don't know exactly what you are trying to do, but basically, this trigger will just run over an over once there are 15 (unless you are killing them faster than 20 per second). It just seems like a lot. I wasn't sure if it was meant to be less than or equal to 15 so that it keeps always keeps a certain amount in play.

EDIT2:
Okay I realised I read your trigger a bit wrong haha - it's only making them in the else part. I updated my trigger to fix it.
 
Last edited:

Rei

Rei

Level 2
Joined
May 26, 2015
Messages
9
Oh, uhm... Well in in its real functional state, this trigger is supposed to spawn scuttlers in a region periodically provided there are not already enough scuttlers to fill the region. It's designed as sort of a farming area early on. Also I did tune it down to 6 scuttlers spawning at intervals of 8 seconds and made them a bit stronger to compensate, since there are quite a few more spawns in the game, and warcraft seems to have a bit of trouble handling large unit numbers. I've also smoothed out quite a bit of the leaks happening passively and it has, in general, already been a much better experience since then, thanks to the help i got in this thread.
 
Status
Not open for further replies.
Top