What you see
- The map loads, but waves never spawn, some triggers never fire, or the multiboard never appears.
- No error is shown.
- Or the game stops responding at one event, such as a wave or an item pickup.
Why it happens
The operation limit. Each JASS thread may only do so much work. A long initialisation function that hits the limit simply stops, and nothing after that point runs.
Lua has no operation limit. A loop that waits for something that cannot change inside it runs forever, and the game freezes.
Re-entry. A pickup handler that gives an item fires the pickup event again; a damage handler that deals damage triggers itself.
UI created too early. Multiboards, leaderboards and timer dialogs created during map initialisation never show. Created in a JASS globals block, they can crash.
How to fix it
- Split big setup work into several functions, each started in its own thread with
ExecuteFunc, or chain them with 0 second timers. - Spread long loops over timer ticks, and print a debug line at the end of each init function to see which one died.
- Replace busy-wait loops with timers or events.
- Guard re-entrant handlers: disable the trigger while you make the change, then enable it again.
- Create boards from a timer about 0.1 seconds after the game starts.
How WC3 Map Doctor detects it
- WarningsA loop runs more than 8190 iterations, and the thread stops at the operation limit before it finishes.LOGIC-loop-op-limit
- WarningsA loop has no exitwhen or return, so it runs until the operation limit stops the thread.LOGIC-endless-loop
- WarningsA multiboard, leaderboard or timer dialog is created during map initialisation, where it never shows.LOGIC-multiboard-at-init
- ErrorsA handle-creating native runs in the globals block, which crashes the game on load or on save.CRASH-globals-handle-create
- InfoAn event-response native is read after a wait, when it may already point at another event.LOGIC-event-after-wait
Sources
Written in our own words from our lab notes; these are the pages behind them.