General - Reducing Lag

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Reducing Lag
Do you often have players complaining about a laggy map or have sudden pauses while your map is running?

This tutorial will tell you a bit about the causes of lag, and teach you how to avoid lag.

1. Map Initialization Lag

Map Initialization lag can be anything from long loading times to players lagging just after the map starts.

There are a few causes:

A. Unit & Hero Creation

Every time you create a new unit that the game has not loaded yet, it takes time. Putting these at map initialization will get rid of annoying in-game pauses, but it will increase the time it takes to load the map. If you don't want either of these, you could try making a short cinematic just after the game starts, so the player won't notice a long load time or any sudden pauses.

B. Massive Amounts of Code

If you have a lot of code being run at Map Initialization, it can create a long loading time. Sometimes, spreading this out just after game start, while playing a cinematic can help to make it a little more bearable.

C. Loading the Map

The other players lag may also be because of how large your map is. If your map is Epic, or Large sized, you may want to add a loading time at the beginning of the map, just so players can handle the heavy strain on their computer.

2. Game Lag

As the game progresses, does lag seem to get worse and worse? It could be from any of the following causes:

A. Memory Leaks

a. Removing GUI Leaks

Did you know that every time you use a "Pick every Unit in..." or a "Create Units at Location" that you create a memory leak? These are the biggest cause for in-game lag. There are many variables that leak:
Points, Unit Groups, Player Groups, Special Effects, Lightning Effects, Floating Text, Countdown Timers, and a number of others.

To remove these memory leaks, every time that you use any of these variable types in a line of GUI, you must set a variable to it, and then use custom script/JASS to remove them.

EX:
Trigger:
  • Untitled Trigger 001
    • Events
      • Unit - A unit enters Region 0001 <gen>
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Position of (Entering unit)) facing Default building facing degrees


Your first step is to identify all the values that you can change, and their variable type.

In this trigger I used 1 (An Integer), Footman (A Unit-Type), Player 1 (Red) (A player), Position of (Entering unit) (A Point), Entering unit (A Unit), and Default building facing degrees (A Real).

Your next step is to check to see which of these variables leaks.
1 (Integer) = Integers do not leak.
Footman (Unit-Type) = Unit-Types do not leak.
Player 1 (Red) (Player) = Players do not leak.
Position of (Entering unit) (Point)= Points do leak.
Entering unit (Unit)= Units do not leak.
Default buliding facing degrees (Real) = Reals do not leak

As you can see, I have found that one of my variables leaks; my point variable, Position of (Entering unit).

So what you must do, is you set a temporary variable to that point, BEFORE the line of text that has the memory leak, and use the variable as the point in the leaking line:

EX:
Trigger:
  • Untitled Trigger 001
    • Events
      • Unit - A unit enters Region 0001 <gen>
    • Conditions
    • Actions
      • Set TEMP_Point = (Position of (Entering unit))
      • Unit - Create 1 Footman for Player 1 (Red) at TEMP_Point facing Default building facing degrees


Now you have the leak stored in a variable, so you can remove it. Each leaking variable has its own custom script to destroy it however, so you must memorize these lines:

Points, Unit Groups, Player Groups, Special Effects, Lightning Effects, Floating Text, and Countdown Timers::
JASS:
Custom script:    call RemoveLocation (udg_*Temp variable name here*)
Custom script:    call DestroyGroup (udg_*Temp variable name here*)
Custom script:    call DestroyForce (udg_*Temp variable name here*)
Custom script:    call DestroyEffect (udg_*Temp variable name here*)
Custom script:    call DestroyLightning (udg_*Temp variable name here*)
Custom script:    call DestroyTextTag (udg_*Temp variable name here*)
Custom script:    call DestroyTimer (udg_*Temp variable name here*)


For the Special Effect, Blizzard already created a Line that destroys it:

Special Effect - Destroy (Last created special effect)

You may want to watch out for the tricky leaks, such as this double point location leak:
Trigger:
  • Untitled Trigger 001
    • Events
      • Unit - A unit enters Region 0001 <gen>
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at ((Position of (Entering Unit)) offset by 50 towards 90 degrees) facing Default building facing degrees


It looks like one leak, right? But there are actually 2 leaks here; Position of (Entering unit) leaks, but so does the point created by offsetting it. You would take care of this kind of a leak like this:

Trigger:
  • Untitled Trigger 001
    • Events
      • Unit - A unit enters Region 0001 <gen>
    • Conditions
    • Actions
      • Set TEMP_Point = Position of (Entering unit)
      • Set TEMP_Point2 = (TEMP_Point) offset by 50 towards 90 degrees
      • Unit - Create 1 Footman for Player 1 (Red) at TEMP_Point2 facing Default building facing degrees
      • Custom Script: call RemoveLocation(udg_TEMP_Point)
      • Custom Script: call RemoveLocation(udg_TEMP_Point2)


Another type of variable that leaks is a Region, but unless the region is not a default region (Playable Map Area), or a Preplaced region (Region XXXX <gen>), it will not leak. However the custom script to destroy a region is:

JASS:
Custom script:   call RemoveRect(udg_*Temp variable name here*)


This is what a region leak looks like:

Trigger:
  • Untitled Trigger 001
    • Events
      • Unit - A unit enters Region 0001 &lt;gen&gt;
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Region (100.00 200.00 300.00 400.00)))


As you can see this creates a region (Anything you have not already preplaced, leaks), AND a point. You would do the same thing as with the double point leak: set the variables to the leaks, use the variables instead of the leaks, and then remove the variables.

You may also be creating leaks if you are using local handle variables in Jass.

b. Nulling Local Handle Variables

Just like not removing a location can leak, leaving any local handle variable with a value will cause a leak. To fix this, you have to null it.

A handle variable includes every single type of variables, except boolean, integer, real, and string.

So, basically if you have any functions that have a part in them that starts out like this:

local VARIABLETYPE NAME , it is creating a local, and if it's not an integer, real, string, or boolean, it needs to be nulled like this:

JASS:
set NAME = null


There are a few exceptions, however.

If you are not going to ever remove the value of the local handle variable, then there is no point in nulling it.

For example, triggers are almost never destroyed. If you create a trigger like this:

JASS:
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    local trigger t = CreateTrigger()
endfunction


and never destroy the trigger, then it does not need to be nulled.

Players are another great example, as they do not leak, and cannot be destroyed, so there is no need to ever null a player.

B. Trigger Enhanced Spells

This is usually a last resort, as most lag can be solved from simply preloading and removing memory leaks. However, there are exceptions.

Even if all of your leaks are taken care of, there still may be lag from triggered spells.

If it uses any Periodic events with a very small duration (such as 0.05 seconds or lower), it can get laggy.

Here are some tips to keep your map as lag-less as possible

  • Avoid periodic events as often as you can. If it doesn't have to use it, then don't use it.
  • Keep spells that use periodic events limited to units that are few in number, such as heroes.
  • Try optimizing the spell in JASS/vJASS, as it is superior to GUI in terms of speed.
  • Avoid large amounts of special effects, and try to use dummy units as replacements.
  • Try to use slighly larger time intervals for periodic events, such as 0.03 - 0.05 instead of 0.02 or 0.01 the human eye can't see the different much of the time anyways.

D. Massive Amounts of Objects

Try to reduce the amount of objects you have on your map at one time, such as units, destructables, doodads, and special effects.

Instead of having hundreds of units, have only a few hundred, and use stronger units instead. You can also save on graphical power by using dummy units instead of special effects, and removing clumps of doodads (such as excessive wheat).

3. PreLoading

A. Units

Again, everytime a unit or hero is created, the game has to load the unit. You can reduce the in-game lag by preplacing all the units, and as soon as the game starts, remove the units. Even dummy casters should be preloaded, otherwise when the first time an ability is cast, it will lag.

B. Abilities

If you add any abilities to units, then you should also create a special unit, that already has the abilities, just for preloading. Just preplace this unit, and remove it as soon as the map initializes. Make sure to preload spellbooks as well.

4. Optimization Tools

A. Loading Times

All this preloading, and having everything already on the map will cause the map to take longer to load. This can be solved by using an optimization tool, such as the Widgetizer.

The Widgetizer is a tool specially designed to reduce loading time and make your map run a bit faster. All you must do is download the tool, open your map with it, and save it as the filename you will be using to host it, under the downloaded maps area. (Make sure your original map isn't under there, so you don't get confused when hosting it, as the maps will still have the same name). Your map may get bigger, but it will load faster.

What the widgetizer actually does (Thanks to SFilip for this section):

All Warcraft's original object data (such as a footman, knight etc.) is actually stored inside SLK files in the MPQ. When you create something custom you will add it to a special file inside your map which needs to be converted and initialized while the map is loading along with all the SLK files even if you don't use one of the objects. The widgetizer simply preconverts all the custom data intro SLK files thus removing any units/abilities/whatever you haven't used, which can greatly reduce your map's loading time. Yet the problem is that SLK files are larger and they need to contain units even if you haven't changed them at all, so this might increase your map's size.

B. Script Optimization

Thankfully, Vexorian created the Map Optimizer, which will automatically go through your script and clean it up for you. (By removing useless BJ functions, shortening, and optimizing scripts to improve performance)

This really helps increase the speed of your map, and it can also remove some of your memory leaks for you (Just don't rely on it to do everything for you).

Another useful tool to help identify and clean leaks is Im_On_56k's Leak Check tool. It is a tool that will help show you where some of your leaks are in your GUI script.

================

Thanks for reading, and good luck in your maps!

Are you still confused about memory leaks? Try a more in-depth tutorial:

http://www.thehelper.net/forums/showthread.php?t=27219
 

ragingspeedhorn

Is a Banned Asshole
Reaction score
94
Nice tutorial, you may should share a link to emlj3's tutorial about leaks though or give a link to Leak Check v2 by Im_On_56k :)


+rep!
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
ragingspeedh said:
Nice tutorial, you may should share a link to emlj3's tutorial about leaks though or give a link to Leak Check v2 by Im_On_56k :)


+rep!

Thanks. :) I was planning on putting in the link to the Memory Leaks tutorial, but I ran out of time.
 

emjlr3

Change can be a good thing
Reaction score
395
that would be a good idea, good job however

a few comments

nothing at map init will carrie over to the map after it loads, that causes no lag, however doing lots of stuff at say .01 sec game time, will

in the spell section, talk about too many effects at once, or what effects lag more then others, as well as preloading dummy abils, especialy spell books

also maybe talk about peiodic events more indepth, for ex. what is worse then others, as well as multiboard stuff liek that

for ex., showing every units hp and mp in the multibaord every .1 sec can be bad

as can spawning lots of units at one time, or even toomany units on the map at one time, no matter how good your code is
 
L

Lordbevan

Guest
For special effect leaks, does it include effects with normal spells (non-triggered spells). Even for trigger enhanced spells, I assume if u do something like:
attach a special effect to a unit
its considered a leak?

Wouldnt attacking a weapon to a unit be considered a leak too?
 

lh2705

Just another Helper
Reaction score
111
i think it leaks if you dont destroy them after use

btw nice thread here

sry cant rep u

"You must spread some reputation around before giving it to Darthfett again"

lol :D
 

Volkof

Well-Known Member
Reaction score
31
question

I never know how to handle lags so i have a question to ask

_____________________________________________________________
Your next step is to check to see which of these variables leaks.
1 (Integer) = Integers do not leak.
Footman (Unit-Type) = Unit-Types do not leak.
Player 1 (Red) (Player) = Players do not leak.
Position of (Entering unit) (Point)= Points do leak.
Entering unit (Unit)= Units do not leak.
Default buliding facing degrees (Real) = Reals do not leak
____________________________________________________________

Qus1: How do I know what variable type will cause memory leak while others dont? :confused:
 

lh2705

Just another Helper
Reaction score
111
there are only a few
like points, unitgroups, player groups, special effects etc.

he listed them there
 

Volkof

Well-Known Member
Reaction score
31
________________________________________________________________
Another type of variable that leaks is a Region, but unless the region is not a default region (Playable Map Area), or a Preplaced region (Region XXXX <gen>), it will not leak. However the custom script to destroy a region is:

Custom script: call RemoveRect(udg_*Temp variable name here*)
________________________________________________________________

I believe this Custom Script is used only if that specific region is no longer needed, right?
 

SFilip

Gone but not forgotten
Reaction score
633
technically all handles (variable types excluding integer, real, boolean and string) can leak. for example if you create a unit every 0.1 seconds it will take some memory thus ultimately causing a leak much greater than a point leak.
every time you use position of x or center of y you actually create an invisible point in the same manner you create units. this is the problem here - you can't use that point again so it will simply stay somewhere and take memory.
similar thing with unit groups and everything stated.

as for the tutorial...you should add an example for region leak since it seems that a lot of people don't understand it.
Unit - Create 1 Footman for Player 1 (Red) at (Center of (Region(100.00, 200.00, 300.00, 400.00))) facing Default building facing degrees
both of these are leaks - you create a region and then create a point at the middle of it. this would create a new region and a new point every time the trigger runs thus taking memory.

oh and for anyone interested in what the widgetizer actually does:
all warcraft's original object data (such as a footman, knight etc.) is actually stored inside slk files in the mpq. when you create something custom you will add it to a special file inside your map which needs to be converted and initialized while the map is loading along with all the slk files even if you don't use something there. the widgetizer simply directly converts all the custom data intro slk files thus removing any units/abilities/whatever you haven't used which can greatly reduce your map's loading time. yet the problem is that slk files are larger and they need to contain units even if you haven't changed them at all so this might increase your map's size.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Thanks for your feedback, everyone! :)

emjlr3 said:
preloading dummy abils, especialy spell books

I mentioned the dummy abilities, but i'll be sure to put spellbooks in specifically.

emjlr3 said:
also maybe talk about periodic events more in-depth, for ex. what is worse than others, as well as multiboard stuff like that

for ex., showing every units hp and mp in the multibaord every .1 sec can be bad

Are the multiboards themselves slow, or just the idea of doing all of the units at once so often?

I'll be sure to put in some more about periodic events though, since that probably messes up a lot of people's code.

emjlr3 said:
as can spawning lots of units at one time, or even toomany units on the map at one time, no matter how good your code is

I'll probably add a massive amounts of objects on the map section or something to include the SFX, Units, Doodads (Not destructibles, since they aren't really that laggy, and are usually necessary).

Vokofe said:
I believe this Custom Script is used only if that specific region is no longer needed, right?

Yes. Technically my memory leaks section tells you how to find leaks in your code (all the ones without variables already set to them), and then set a temporary variable to it, and then destroy it. I'll add a little tip at the end of that section to explain that if you already have a variable set to it, you should destroy it once it's no longer in use, or just before it will be "overwritten" and you will be unable to destroy it again.

I'm going to be adding another section that explains about nullifying locals at the end of JASS functions, too.

SFilip said:
as for the tutorial...you should add an example for region leak since it seems that a lot of people don't understand it.

I just did, thanks. :)

I'll also fix the description of the Widgetizer.
 

emjlr3

Change can be a good thing
Reaction score
395
more thought

on larger maps, creating weather lags, as does map wide music

as for ashowing stuff on the multiboard, i am not quite sure, I jiust know its not a good idea

yea spell books can add like 1-3 sec in game lag when added

thsi ofcourse makes game loading longer, but we;d rather have that then massive in game lag

another thing is preoading effects, using the PreLoad() native, which is available in GUI, can help for larger effects in first time creation
 

DDRtists

ɹoʇɐɹǝpoɯ ɹǝdns
Reaction score
415
Grammer error:

This tutorial will teach you how to fix all this, and help to make your map run even more smoothly.

should be either:

This tutorial will teach you how to fix all this, and help to make your map run more smoothly.

or

This tutorial will teach you how to fix all this, and help to make your map even more smooth.


Just thought I'd point that out :D :cool:
 
M

Maximus

Guest
Hmm, I think you missed one. When you create an item( I just tried an action Hero - Create item for hero) it will lag. :D
 

ragingspeedhorn

Is a Banned Asshole
Reaction score
94
I find the blue headlines annoying, but besides from that this tutorials content is great, nothing missing or anything, but there is a few paragraphs that could be rewritten abit so that it apears better :)
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
ragingspeedh said:
I find the blue headlines annoying, but besides from that this tutorials content is great, nothing missing or anything, but there is a few paragraphs that could be rewritten abit so that it apears better :)

Is it the color, or just the fact that they're big and in the way? :p

I'll try and make it more readable. Thanks for the feedback! :)
+Rep when I can.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top