[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 10
Joined
Jun 9, 2020
Messages
95
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: 33
Level 26
Joined
Feb 2, 2006
Messages
1,504
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.
 
Top