• 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.

Are these amounts of MB in the Task manager suspicious?

Level 15
Joined
Jun 9, 2008
Messages
309
So one thing I started doing, because I notice frustrating lag in my maps, is I run Warcraft in window mode and look at the task manager.
I get crashes somewhat frequently (but VERY inconsistently), but they do not seem to be linked to jumps in memory usage, certainly nothing close to GB.

I BELIEVE I am doing my best fixing leaks, using custom delete scripts rather excessively (actually, I seem to use them more than anyone else, I put them after AND before the variables (to make sure I catch anything left over from previous triggers I somehow missed); my philosophy so far is, use custom delete scripts as much as possible even if redundant).

I checked my imported custom files, they do not seem to be corrupt.

So from reading around, another hyposthesis is that it's not so much leaks as inefficient triggers. How much of a difference do "inefficent triggers" make, even if they don't leak or don't leak much?

The MAIN thing though is, what would you conclude from the following:

  • Warcraft version 1.29
  • Map dimensions are 480x480
  • 24 players
  • Lots of imports
  • Custom Triggers
  • In Task manager, you get
590 MB at start,
690 MB at 10 minutes,
726 MB at 20 minutes,
760 MB at 30 minutes,
785 MB at 40 minutes
750 MB at 50 minutes
775 MB at 1 hour
(If there is no crash, I usually end it after 1 h because I have other things to do)

How does that compare with your warcraft experiences?
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Well, I would never do something like call a function just hoping that it'll work. You're banking on the fact that the developers put in safety nets for when a function is used incorrectly, IE: Destroy an object that doesn't even exist. That being said, Warcraft 3 is pretty good about that kind of thing, but it's still not a recommended habit. Do things deliberately, don't assume things, and don't hope that it'll just magically work out.

Anyway, I've heard of weird problems associated with maps of that size, perhaps you could import everything into a smaller map size like 256x256 and see if the crash still occurs. Unfortunately, it's tough to test for a crash that rarely happens since it's difficult to tell if it's fixed or not, you might just get lucky and not experience it for a while.

Also, I'm not sure what your "inefficient triggers" are doing, but perhaps you have some kind of infinite loop that causes the crash. I find I often run into this issue with events related to Acquiring/Losing items, Damage taken, Issuing orders, and Dying units.

Another thing, if you experience noticeable spikes where the game freezes for a second and then resumes, it's probably because you're:
1) Creating too many units/special effects in the same game frame.
2) Using Unit Groups inefficiently. Manually add/remove individual units in constant Unit Groups whenever possible, don't constantly recreate them.
3) Loading something for the first time, like a unit, ability, etc. (Preloading will help with this, although the problem will basically sort itself on it's own)
 
Last edited:
Level 15
Joined
Jun 9, 2008
Messages
309
Anyway, I've heard of weird problems associated with maps of that size, perhaps you could import everything into a smaller map size like 256x256 and see if the crash still occurs.
I tried simply reducing the map size of the original map to 256x256, to avoid making a new map, though I doubt that was helpful since it messed with the regions I set. I tried quickly adapting the triggers accordingly, but I am not too surprised the crash moved from "sometimes, at random" to "almost always, right at map initialization or shortly after". (In the big map, I had that problem when I used regions that were apparently too large for the triggers to handle, and once I reduced the size of the regions, the map became playable).

2) Using Unit Groups inefficiently. Manually add/remove individual units in constant Unit Groups whenever possible, don't constantly recreate them.
That might be a really big factor. I create and delete plenty of unit groups.
If you say this helps, I will start by changing my triggers accordingly.

But in that spirit - I looked around a bit, but I'm not sure I have quite pieced it together - how would you handle using unit groups:

My usual approach is this
  • Set the Unit Group variable (often complex, like "all units in Queensland (Australia) called Bob or Sarah with political opinions different from my own")
  • Use it
  • Destroy the Unit Group with custom script

Very often, I will also "refine" unit groups by creating new unit groups with various characteristics, and remove them from the first unit group.

Example:
  • Example trigger
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Level of A Flag for (Attacked unit)) Equal to 1
    • Actions
      • Set Replazzo = (Attacking unit)
      • Set Standpoint = (Position of (Attacked unit))
      • Set Gewerbegebiet = (Region centered at Standpoint with size (400.00, 400.00))
      • Custom script: call RemoveLocation(udg_Standpoint)
      • Set TempGroup1 = (Units in Gewerbegebiet matching (((Matching unit) is A structure) Equal to False))
      • Set Extractos = (Units owned by Neutral Passive)
      • Unit Group - Pick every unit in Extractos and do (Actions)
        • Loop - Actions
          • Unit Group - Remove (Picked unit) from TempGroup1
      • Custom script: call DestroyGroup(udg_Extractos)
      • Set Extractos = (Units in Gewerbegebiet matching ((Owner of (Matching unit)) Equal to (Owner of (Attacking unit))))
      • Custom script: call RemoveRect(udg_Gewerbegebiet)
      • Unit Group - Pick every unit in Extractos and do (Actions)
        • Loop - Actions
          • Unit Group - Remove (Picked unit) from TempGroup1
      • Custom script: call DestroyGroup(udg_Extractos)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TempGroup1) Equal to 0
        • Then - Actions
          • Unit - Change ownership of (Attacked unit) to (Owner of Replazzo) and Change color
        • Else - Actions
      • Custom script: call DestroyGroup(udg_TempGroup1)
(simple one for demonstration purposes, "TempGroup1" and "Extractos" are often much more complex than that)
EDIT: In newer triggers, I use the "remove unit group from unit group" action rather than what I posted here.

So instead of destroying unit groups, maybe I should just empty and fill them as needed? But how would you do that - "Pick every unit from unit group and remove from unit group"? Or that custom script "set null" option?
But then, how would I add fresh units to it? If I redefine the variable, that just recreates it as a new unit group?
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
The idea with the Unit Groups is to find patterns of repetition and organize things where possible.

For example, here I will keep track of "soldiers" that belong to each Player and "heroes" that belong to each Player:
  • Events
    • Unit - A unit Enters playable map area
  • Conditions
  • Actions
    • Set UnitToAdd = (Triggering unit)
    • Set PN = (Player number of (Owner of UnitToAdd))
    • Unit Group - Add UnitToAdd to Player_Units[PN]
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (UnitToAdd is a Hero) Equal to True
      • Then - Actions
        • Unit Group - Add UnitToAdd to Player_Heroes[PN]
      • Else - Actions
        • Unit Group - Add UnitToAdd to Player_Soldiers[PN]
Now for instance whenever I want to get all non-Hero units owned by Player 4 I already have a group of them narrowed down so there's no need to "search" for these units. I have a direct reference which is a massive improvement in performance:
  • Unit Group - Pick every unit in Player_Soldiers[4] and do (Actions)
    • Loop - Actions
I don't know how your map works exactly but I imagine you'll be able to do something like this. Also, don't forget to Remove dead units from the groups as well since they aren't removed automatically:
  • Events
    • Unit - A unit Dies
  • Conditions
  • Actions
    • Set UnitToRemove = (Triggering unit)
    • Set PN = (Player number of (Owner of UnitToRemove))
    • Unit Group - Remove UnitToRemove from Player_Units[PN]
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (UnitToRemove is a Hero) Equal to True
      • Then - Actions
        • Unit Group - Remove UnitToRemove from Player_Heroes[PN]
      • Else - Actions
        • Unit Group - Remove UnitToRemove from Player_Soldiers[PN]
This Event based approach where you do smaller processes spread out over time rather than one big process all at once will help prevent those dips in framerate. Think about it this way:

1) You do everything all at once in one big expensive process:
The result, the game runs at 200 frames per second but every few seconds it has a massive performance hit which drops the fps down to 10 fps for a moment before jumping back up to 200 fps.

2) You spread out your calculations over time in smaller but more processes:
The result, the game runs at 170 fps but without any spikes in performance. The 170 fps is going to be far more enjoyable because it's a smooth experience throughout, it doesn't disrupt the player.

I can't promise you that what I'm suggesting will actually fix your problems. A map of your size is probably going to struggle regardless of what you try, however, it should be a step in the right direction.
 
Last edited:
Level 15
Joined
Jun 9, 2008
Messages
309
590 MB at start,
690 MB at 10 minutes,
726 MB at 20 minutes,
760 MB at 30 minutes,
785 MB at 40 minutes
750 MB at 50 minutes
775 MB at 1 hour
(If there is no crash, I usually end it after 1 h because I have other things to do)

How does that compare with your warcraft experiences?
Circling back to the original question, are those numbers something you'd consider "suspicious", right off the bat?

It's certainly a lot more than in a standard melee game.
 
Top