[Crash] List of WarCraft III Crashes

Level 1
Joined
Jan 2, 2023
Messages
15
Setting an ability (adding or incrementing it) to the unit may cause crash if the unit is dead. Since the interpreter is not instant, sometimes the script will trigger properly on an alive unit, but during its execution a unit becomes dead.
This bug happens on v1.27.
To fix that issue before adding/setting ability level on the unit check whether the unit is alive.
 
Level 1
Joined
Jan 2, 2023
Messages
15
The interpreter is instant. Simulation time is paused while it is executing. Execution order is well defined for network synchronisation purposes.
Do I really need to prove myself?
No interpreter is instant, not even compiled machine code. You can say it is fast in comparison to 100 frames per second on the screen, but who knows what is the order if not the internal game logic then virtual machine it is run on, if not vm then the processor itself?

Nevertheless, this problem remained to be a source of a crash. Since you are a spell reviewer, please check it out:
Here is an auto-cast ability: "Parasite" which can be cast on alive players exclusively
Enter trigger: catch a spell cast by a player
Trigger condition: if a caster is a specific unit
Trigger logic: add/set/increment ability level (buff) to the mob

The result: without a check "is mob alive" it would crash the system after ~20..100 trigger runs.

Below is the code. It's just a cleaned up JASS converted from GUI. I have 3 similar scrips, all of them crashed the system before i have added the above mentioned check:

JASS:
function Trig_Spell_BARB_Battle_Cry_Actions takes nothing returns nothing
    local integer ilevel
    local unit ucurr
    local unit utarget = GetSpellTargetUnit()
    local player powner
    local location lpoint = GetUnitLoc( utarget )
    local group gunits = GetUnitsInRangeOfLocAll(300.00, lpoint)
 
    // Auto caster for the defense lowering ability
    loop
        set ucurr = FirstOfGroup(gunits)
        exitwhen ucurr == null
        call GroupRemoveUnit( gunits, ucurr )
    
        set powner = GetOwningPlayer( ucurr )
        if ( ( powner == Player(11 - 1) ) or ( powner == Player(12 - 1) ) ) then
            // ! it's very important to check if unit is alive ! crashes otherwise
            if ( IsUnitAliveBJ( ucurr ) ) then
                set ilevel = GetUnitAbilityLevel( ucurr, 'A01N' )
                if ( ilevel == 0 ) then
                    call UnitAddAbility( ucurr, 'A01N' )
                elseif ( ilevel < 5 ) then
                    call IncUnitAbilityLevel( ucurr, 'A01N' )
                endif
            endif
        endif
    endloop
    call RemoveLocation( lpoint )
    call DestroyGroup( gunits )
 
    call AddSpecialEffectTargetUnitBJ( "origin", GetTriggerUnit(), "Abilities\\Spells\\Other\\HowlOfTerror\\HowlTarget.mdl" )
    call DestroyEffectBJ( GetLastCreatedEffectBJ() )

    // clean up local variable pointers
    set lpoint = null
    set gunits = null
    set powner = null
    set utarget = null
    set ucurr = null
endfunction

function Trig_Spell_BARB_Battle_Cry_Conditions takes nothing returns boolean
    return ( GetUnitTypeId(GetTriggerUnit()) == 'h005' )
endfunction

//===========================================================================
function InitTrig_Spell_BARB_Battle_Cry takes nothing returns nothing
    set gg_trg_Spell_BARB_Battle_Cry = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(0), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(1), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(2), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(3), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(4), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(5), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(6), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Spell_BARB_Battle_Cry, Player(7), EVENT_PLAYER_UNIT_SPELL_CAST )
 
    call TriggerAddCondition( gg_trg_Spell_BARB_Battle_Cry, Condition( function Trig_Spell_BARB_Battle_Cry_Conditions ) )
    call TriggerAddAction( gg_trg_Spell_BARB_Battle_Cry, function Trig_Spell_BARB_Battle_Cry_Actions )
endfunction

Also a philosophical question: both towers and mobs can cast abilities and they do in fact. Which is a faster trigger? The one that is attached on each "Ability cast" or the one presented here, attached to human players? There can be up to a 100 towers per player (assume 80% are casters) and up to 200 monsters per player.
 
Last edited:
Level 2
Joined
Jul 20, 2023
Messages
2
Not sure if other factors are important, too but I definitively had buildings which crashed my AI and after changing the pathing requirement it worked, maybe the pathing texture/collision was also missing.
I ran into this problem extensively. It gave me such a hard time because it was extremely hard to pin point. I set a Tavern building with no pathing Ai so that they could be set closer to each other and take up less space (dockyard and smaller building Ai works best). If you set it to none, the game plays fine without Ai. If you have an Ai play, the moment they go to expand with an undead gold mine or possibly night elf, the game crashes as soon as it orders their worker the command. Extremely wierd way to crash. However, that won't happen if the building is like >10,000 units away from the expansion gold mine.
 
I ran into this problem extensively. It gave me such a hard time because it was extremely hard to pin point. I set a Tavern building with no pathing Ai so that they could be set closer to each other and take up less space (dockyard and smaller building Ai works best). If you set it to none, the game plays fine without Ai. If you have an Ai play, the moment they go to expand with an undead gold mine or possibly night elf, the game crashes as soon as it orders their worker the command. Extremely wierd way to crash. However, that won't happen if the building is like >10,000 units away from the expansion gold mine.
This is probably a division-by-zero problem with the way the AI calculates its pathing.
 
Level 12
Joined
Jun 9, 2020
Messages
145
where do we find this info? I checked crash logs after latest patch and it's the same info as before
Here, as I promised, my fellow map maker. It doesn't happen all the time, but it has helped me to deal with a few crushes already.
 

Attachments

  • Screenshot (1906).png
    Screenshot (1906).png
    13 KB · Views: 66
Level 28
Joined
Feb 2, 2006
Messages
1,628
Initialization of region variables in globals blocks leads to crashes on saving the game and endless lags
Having this in the map script:

JASS:
globals
    region r = CreateRegion()
endglobals

Leads to the game crashing when saving it.
Took me some time to find this cause.
Regions must be initialized in some function instead.

Also when loading save games in Reforged framehandles become invalid and accessing them will crash the game.
Hence, they must be recreated after loading a game before being accessed again.
Systems like FrameLoader help with this issue.


Researches with maximum HP increase effects lead to overflows
Researches which increase maximum HP of units lead to very strange behavior instantly killing units at some point.
It is probably some kind of overflow.
Maybe the bonus only allows some values up to 255 or something.
Percentages or absolute values lead to strange behavior.

Use
JASS:
native BlzSetUnitMaxHP                             takes unit whichUnit, integer hp returns nothing
instead.


Too little ground space even with waygates will lead to crashes for starting AI campaign scripts

In my map there are different start locations for AI players.
They all have AI campaign scripts.
Whenever the AI starts at a location where it has too little ground space and only sea around even connected to the rest of the map with a waygate, the game will crash.
After adding more ground terrain around, it did not crash anymore.
It might be related to the number of buildings etc. the AI has to construct in the AI script.


String literals with more than 1023 characters will lead to crashes on loading save games

The maximum number of characters in a string literal is 1023. However, the Reforged World Editor does not crash anymore with longer literals BUT loading save games with maps using longer string literals will crash the game.
The limit has been documented here: [Documentation] String Type
 

Attachments

  • baradeslongstrongcrash.w3x
    17.4 KB · Views: 7
Last edited:

Macielos

Hosted Project: W3E
Level 23
Joined
Jul 9, 2010
Messages
396
I've got another fine addition to your collection - SuicideOnPlayer() in a custom AI script on a map that has 256+ in size crashes the game on Reforged.

Also reproduced on a different map which was 288x256 in size.

I wonder if this can be fixed in some other way than by cutting the map. Is there some game constant or something else that can be changed? I doubt I'm the first one with this issue.
 
Last edited:
Level 2
Joined
Jun 16, 2024
Messages
6
Spawning a unit with both coordinates outside the map boundary will cause a crash. If it's only the x or the y, it won't crash. I found this when I used a trigger that spawns a unit at the coordinates of another unit minus a certain offset. If the trigger unit was too close to one of the map corners, the map would crash when attempting to spawn the other unit. I confirmed the cause through testing.
 
Top