What you see
- Frame rate and responsiveness drop over 30 to 60 minutes.
- Lag spikes grow into short freezes, especially when big waves spawn or die.
- The game's memory use keeps climbing, and very long games may crash near the end.
Why it happens
Many GUI actions create an object you never see. Center of (Playable map area)
creates a point, Units in (Playable map area)
creates a unit group (even inside a condition), All enemies of Player 1
creates a player group, and Create Special Effect
creates an effect. Nothing removes them, so a trigger that runs every second leaks every second.
In JASS, a local variable that still points to a unit, group, timer or effect when the function ends holds a reference, and the handle's id is never recycled.
Lua's garbage collector frees Lua data only. Game objects such as locations and groups leak in Lua maps the same way.
Floods hurt too: one dummy unit per missile, floating texts with no lifespan, tens of thousands of doodads.
How to fix it
- Store the object in a variable, use it, then destroy it with
RemoveLocation,DestroyGroup,DestroyForceorDestroyEffect. In GUI, use custom script lines for the destroy calls, or the GUI actions 3.0 added for them. - Before a GUI group action,
set bj_wantDestroyGroup = truemakes the next group clean itself up. - Never destroy
All players
: it is a constant. - JASS: destroy first, then set the local to
null, before every return. - Give floating texts a lifespan, reuse dummy units for missiles, and cap how many units a wave keeps alive.
How WC3 Map Doctor detects it
- WarningsA location is stored and never removed, so every call leaks one.PERF-L01 · auto-fix:
local-location-remove - WarningsA group made by a BJ function is neither destroyed nor flagged with bj_wantDestroyGroup, so it leaks.PERF-L02
- WarningsA force made by a BJ function is never destroyed, so it leaks.PERF-L03
- SevereA special effect is created and its handle thrown away, so it can never be destroyed.PERF-L04
- InfoA handle local is not set to null before the function returns.PERF-L05
- WarningsA floating text is created with no lifespan, so it stays until the cap (100 before 3.0) is reached.PERF-X01
- SevereA periodic timer with a 0 s period runs every frame.PERF-T01
Operations that fix it on a copy
- leak.hot Stop handle leaks in code that runs all game
- optimize.effects Destroy fire-and-forget effects
The scan also projects how many handles leak per minute and when the map would hit a game limit. That projection feeds the Stability grade.
Sources
Written in our own words from our lab notes; these are the pages behind them.
- forumHive Workshop: Memory leaks tutorial
- publishedBlizzard: Warcraft III Reforged Forsaken Kingdom patch notes (3.0.0 and 3.0.1)
- forumHive Workshop: Lua-Infused GUI, automatic leak prevention
- publishedLiquipedia: Patch 1.29.0 (object and execution limits)
- authorjassdoc: annotated common.j and Blizzard.j