• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Trigger] VERY BIG AND HARD request. Maybe anyone can help.

Status
Not open for further replies.
Level 7
Joined
Dec 31, 2011
Messages
249
This thread is about my map.

See rates on hive - that looks as map at least not very bad.

I VERY want to create more and more heroes for MUGEN MOBA - optimal collection of all heroes from all MOBA games. That's part of my life now.

But my giant map still has main problem, which prevents her real success.

Map still has rare, but desynchronizations.

Problem is that i still DON'T KNOW the reasons.

I read many articles. I remove almost all Wait Game-Time actions. Map has no local actions. And has no big lags (more than, for example, DotA). Map is ideal MOBA for Single-player game :ogre_love: and for me.

I change big part of map into totally JASS code, GUI now only very simple triggers (with instantly actions, so i think not very much difference). I has some ideas for more optimization, but still not sure about the exact reasons.

Desynchronizations can be at 35th minute (not in every game, but if there are - usually at this time). But no specific actions in that time! Leaks? But can leaks create desynchronizations? (Also, if leaks - at least not many: i repeat, map has no big lags).

Maybe, anyone, who is very,very good in triggers and has very many free time, can help me to find the reason. Of course for nickname in Credits, at least!

Here is open version of last build of english version of my map (it's after 3.8c, has some minor fixes and changes). I use Jass New Gen Pack to work with her. Some peoples can't open her, i too don't know, why :( But some peoples can.
http://clawbfs.ucoz.ru/BFSEngNewGreat.w3x

I has no hope, but maybe...
 
Level 7
Joined
Dec 31, 2011
Messages
249
Desynchronizations usually result from using GetLocalPlayer() incorrectly from my knowledge.
I know about it. But that function, if used incorrectly, ALWAYS creates desynchronizations. My problem is a RANDOM desynchronizations (can be, can not be).

for leaks there is a leak finder which can be helpful if your not good at finding them.
I' m at least not very bad: i repeat - no lags ingame and i know about leaks of units, points, groups, effects, etc... and i remove all of that. Anyway, leaks can't be reason of desynchronizations? Or can?

Good luck on your map bro
Thanks.

Any more help?
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
god the title made me come to this thread.

anyway, go in MPQ editor and extract the .j

in notepad or JC, ctrl+f "GetLocalPlayer()" and if theres a single refrence to that post this block

if X = GetLocalPlayer then

...

endif
 
Level 7
Joined
Dec 31, 2011
Messages
249
I know about all of that. I read the articles.
In current version no terrain deformations, about camera - just functions "Set CameraTargetController" and "Apply Camera Object", no "Pan Camera".

But still rare, random, but desynchronizations after 34 minutes.
 
Level 7
Joined
Dec 31, 2011
Messages
249
I repeat, link on full map here: http://clawbfs.ucoz.ru/BFSEngNewGreat.w3x

But who can't or don't want to download it, but can try to help - has any triggers here, for example, some reasons of desynchronizations?


function DestroyEffect2 takes nothing returns nothing
local timer t=GetExpiredTimer()
local effect e=LoadEffectHandle(udg_Hash,GetHandleId(t),4)
call DestroyEffect( e )
call FlushChildHashtable(udg_Hash,GetHandleId(t))
call DestroyTimer(t)
set t=null
set e=null
endfunction

function Trig_destroyspeceffect_Actions takes nothing returns nothing
local timer t = CreateTimer()
local effect e = GetLastCreatedEffectBJ()
call SaveEffectHandle(udg_Hash,GetHandleId(t),4,e)
call TimerStart(t,2,false,function DestroyEffect2)
set t=null
set e=null
endfunction

//===========================================================================
function InitTrig_destroyspeceffect takes nothing returns nothing
set gg_trg_destroyspeceffect = CreateTrigger( )
call TriggerAddAction( gg_trg_destroyspeceffect, function Trig_destroyspeceffect_Actions )
endfunction



function Trig_Insubmersible_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A19K' ) ) then
return false
endif
return true
endfunction

function Insurdamage takes nothing returns nothing
call DisableTrigger(GetTriggeringTrigger())
call SetUnitLifeBJ( GetTriggerUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit()) + ( GetEventDamage() / 2.00 ) ) )
call UnitDamageTargetBJ( GetTriggerUnit(), GetEventDamageSource(), ( GetEventDamage() / 2.00 ), ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL )
if ( not ( GetEventDamageSource() == GetTriggerUnit() ) ) then
call AddSpecialEffectTargetUnitBJ( "chest", GetEventDamageSource(), "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl" )
call ConditionalTriggerExecute( gg_trg_destroyspeceffect )
else
endif
call EnableTrigger(GetTriggeringTrigger())
endfunction

function Insurmersible2 takes nothing returns nothing
local timer t=GetExpiredTimer()
local unit u5=LoadUnitHandle(udg_Hash,GetHandleId(t),2)
local trigger insurdamage=LoadTriggerHandle(udg_Hash,GetHandleId(t),20)
call UnitRemoveAbilityBJ( 'A192', u5 )
call UnitRemoveBuffBJ( 'B0AP', u5 )
call DestroyTrigger(insurdamage)
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash,GetHandleId(t))
set insurdamage=null
set u5 = null
set t = null
endfunction

function Trig_Insubmersible_Actions takes nothing returns nothing
local timer t = CreateTimer()
local unit u5 = GetSpellTargetUnit()
local integer i=0
local trigger insurdamage


set insurdamage=CreateTrigger()
call TriggerRegisterUnitEvent(insurdamage,GetSpellTargetUnit(), EVENT_UNIT_DAMAGED)
call TriggerAddAction(insurdamage,function Insurdamage)

call UnitAddAbilityBJ( 'A192', GetSpellTargetUnit() )
call SaveUnitHandle(udg_Hash,GetHandleId(t),2,u5)
call SaveTriggerHandle(udg_Hash,GetHandleId(t),20,insurdamage)
call TimerStart(t,5,false,function Insurmersible2)
set t=null
set u5=null
set insurdamage=null
endfunction

//===========================================================================
function InitTrig_Insubmersible takes nothing returns nothing
set gg_trg_Insubmersible = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Insubmersible, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Insubmersible, Condition( function Trig_Insubmersible_Conditions ) )
call TriggerAddAction( gg_trg_Insubmersible, function Trig_Insubmersible_Actions )
endfunction



function Trig_Grace_Conditions takes nothing returns boolean
if ( not ( GetLearnedSkillBJ() == 'A175' ) ) then
return false
endif
return true
endfunction


function Grace2 takes nothing returns nothing
local timer t=GetExpiredTimer()
local unit u=LoadUnitHandle(udg_Hash,GetHandleId(t),2)
set udg_unit = u
call SetUnitAbilityLevelSwapped( 'A176', udg_unit, ( 1 + ( ( R2I(GetUnitStateSwap(UNIT_STATE_MAX_MANA, udg_unit)) - R2I(GetUnitStateSwap(UNIT_STATE_MANA, udg_unit)) ) / ( 10 / GetUnitAbilityLevelSwapped('A175', udg_unit) ) ) ) )
call AddSpecialEffectTargetUnitBJ( "hand,left", udg_unit, "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayDamage.mdl" )
call ConditionalTriggerExecute( gg_trg_destroyspeceffect )
call AddSpecialEffectTargetUnitBJ( "weapon", udg_unit, "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayDamage.mdl" )
call ConditionalTriggerExecute( gg_trg_destroyspeceffect )
set t=null
set u=null
endfunction

function Trig_Grace_Actions takes nothing returns nothing
local timer t = CreateTimer()
local unit u = GetTriggerUnit()
call SaveUnitHandle(udg_Hash,GetHandleId(t),2,u)
call TimerStart(t,1,true,function Grace2)
set t=null
set u=null
endfunction

//===========================================================================
function InitTrig_Grace takes nothing returns nothing
set gg_trg_Grace = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Grace, EVENT_PLAYER_HERO_SKILL )
call TriggerAddCondition( gg_trg_Grace, Condition( function Trig_Grace_Conditions ) )
call TriggerAddAction( gg_trg_Grace, function Trig_Grace_Actions )
endfunction



function Trig_MovefromTaverns_Conditions takes nothing returns boolean
if ( not ( IsUnitType(GetSoldUnit(), UNIT_TYPE_HERO) == true ) ) then
return false
endif
return true
endfunction

function Trig_MovefromTaverns_Func003C takes nothing returns boolean
if ( not ( udg_MyNewSide[GetConvertedPlayerId(GetOwningPlayer(GetSoldUnit()))] == "Light" ) ) then
return false
endif
return true
endfunction

function Trig_MovefromTaverns_Func005C takes nothing returns boolean
if ( not ( udg_nhl == false ) ) then
return false
endif
return true
endfunction

function Trig_MovefromTaverns_Func006Func001A takes nothing returns nothing
call SetPlayerUnitAvailableBJ( GetUnitTypeId(GetSoldUnit()), false, GetEnumPlayer() )
endfunction

function Trig_MovefromTaverns_Func006C takes nothing returns boolean
if ( not ( udg_Duplicate == false ) ) then
return false
endif
if ( not ( udg_nhl == false ) ) then
return false
endif
return true
endfunction

function Trig_MovefromTaverns_Actions takes nothing returns nothing
if ( Trig_MovefromTaverns_Func003C() ) then
set udg_point = GetRectCenter(gg_rct_LightHeroSpawn)
else
set udg_point = GetRectCenter(gg_rct_DarkHeroSpawn)
endif
call SetUnitPositionLoc( GetSoldUnit(), udg_point )
if ( Trig_MovefromTaverns_Func005C() ) then
set udg_LimitHeroTraining[GetConvertedPlayerId(GetOwningPlayer(GetSoldUnit()))] = ( udg_LimitHeroTraining[GetConvertedPlayerId(GetOwningPlayer(GetSoldUnit()))] - 1 )
call SetPlayerMaxHeroesAllowed( udg_LimitHeroTraining[GetConvertedPlayerId(GetOwningPlayer(GetSoldUnit()))], GetOwningPlayer(GetSoldUnit()) )
else
endif
if ( Trig_MovefromTaverns_Func006C() ) then
call ForForce( GetPlayersAll(), function Trig_MovefromTaverns_Func006Func001A )
else
endif
endfunction

//===========================================================================
function InitTrig_MovefromTaverns takes nothing returns nothing
set gg_trg_MovefromTaverns = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_MovefromTaverns, EVENT_PLAYER_UNIT_SELL )
call TriggerAddCondition( gg_trg_MovefromTaverns, Condition( function Trig_MovefromTaverns_Conditions ) )
call TriggerAddAction( gg_trg_MovefromTaverns, function Trig_MovefromTaverns_Actions )
endfunction
 
Level 10
Joined
Sep 21, 2007
Messages
517
@Claw, SetCameraTarget is also localized, maybe just avoid the BJ functions. They usually have many bugs. I remember in my FPS demo there was a desync error which made all the players except the host disconnect. Ofc i quit that project a long time ago since it was too code intensive but maybe its the same concept. As for random desyncs, maybe you have event-triggered code that is causing this so mb its not really random? Your really in a pickle here bro ;p What did the desyncs cause btw?
 
Level 7
Joined
Dec 31, 2011
Messages
249
SetCameraTarget is also localized
But that function in my map used in situations, when it moves camera for ALL players in one position. And only for ultimate of one hero (Wisp). So that anyway isn't reason (desynchronizations can be without Wisp, and can not be with him).

About code. Look, please, at my triggers in message # 8, has some problems? And what about:

Can NON-TRIGGERED terrain deformations (in some default spells, like second spell of Mountain King hero in ladder game) be reason of desyncs?!
 
Level 7
Joined
Dec 31, 2011
Messages
249
And again - what about:

Can NON-TRIGGERED terrain deformations (in some default spells, like second spell of Mountain King hero in ladder game) be reason of desyncs?!

Just "yes" or "no" ) If "yes", i just will change 8-10 spells with non-triggered terrain deformations.
 
You have two blocks with GetLocalPlayer(), I don't have time to look at them atm but here they are:

JASS:
function Trig_water_Actions takes nothing returns nothing
    set udg_localplayer = GetLocalPlayer()
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 12
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        if ( Trig_water_Func003Func001C() ) then
            if ( Trig_water_Func003Func001Func001C() ) then
                call SetWaterBaseColorBJ( 100, 0.00, 0.00, 0 )
            else
                if ( Trig_water_Func003Func001Func001Func001C() ) then
                    call SetWaterBaseColorBJ( 0.00, 0.00, 100.00, 0 )
                else
                    if ( Trig_water_Func003Func001Func001Func001Func001C() ) then
                        call SetWaterBaseColorBJ( 0.00, 100.00, 0.00, 0 )
                    else
                        if ( Trig_water_Func003Func001Func001Func001Func001Func001C() ) then
                            call SetWaterBaseColorBJ( 0.00, 0.00, 0.00, 0 )
                        else
                            if ( Trig_water_Func003Func001Func001Func001Func001Func001Func001C() ) then
                                call SetWaterBaseColorBJ( 100.00, 50.00, 0.00, 0 )
                            else
                                if ( Trig_water_Func003Func001Func001Func001Func001Func001Func001Func001C() ) then
                                    call SetWaterBaseColorBJ( 50.00, 0.00, 100.00, 0 )
                                else
                                endif
                            endif
                        endif
                    endif
                endif
            endif
        else
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    set udg_localplayer = null
endfunction

JASS:
function Trig_weather_Actions takes nothing returns nothing
    set udg_localplayer = GetLocalPlayer()
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 12
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        if ( Trig_weather_Func003Func001C() ) then
            if ( Trig_weather_Func003Func001Func001C() ) then
                call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'RAhr' )
                set udg_weather = GetLastCreatedWeatherEffect()
                set udg_WeatherIsHere[GetConvertedPlayerId(GetTriggerPlayer())] = true
            else
                if ( Trig_weather_Func003Func001Func001Func002C() ) then
                    call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'SNhs' )
                    set udg_weather = GetLastCreatedWeatherEffect()
                    set udg_WeatherIsHere[GetConvertedPlayerId(GetTriggerPlayer())] = true
                else
                    if ( Trig_weather_Func003Func001Func001Func002Func002C() ) then
                        call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'LRaa' )
                        set udg_weather = GetLastCreatedWeatherEffect()
                        set udg_WeatherIsHere[GetConvertedPlayerId(GetTriggerPlayer())] = true
                    else
                        if ( Trig_weather_Func003Func001Func001Func002Func002Func002C() ) then
                            call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'WNcw' )
                            set udg_weather = GetLastCreatedWeatherEffect()
                            set udg_WeatherIsHere[GetConvertedPlayerId(GetTriggerPlayer())] = true
                        else
                            if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002C() ) then
                                call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'LRma' )
                                set udg_weather = GetLastCreatedWeatherEffect()
                                set udg_WeatherIsHere[GetConvertedPlayerId(GetTriggerPlayer())] = true
                            else
                                if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002Func002C() ) then
                                    set udg_integer = GetRandomInt(1, 5)
                                    if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002Func002Func004C() ) then
                                        call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'LRma' )
                                    else
                                        if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002Func002Func004Func001C() ) then
                                            call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'LRaa' )
                                        else
                                            if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002Func002Func004Func001Func001C() ) then
                                                call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'RAhr' )
                                            else
                                                if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002Func002Func004Func001Func001Func001C() ) then
                                                    call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'SNbs' )
                                                else
                                                    if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002Func002Func004Func001Func001Func001Func001C() ) then
                                                        call AddWeatherEffectSaveLast( GetPlayableMapRect(), 'WNcw' )
                                                    else
                                                    endif
                                                endif
                                            endif
                                        endif
                                    endif
                                    set udg_weather = GetLastCreatedWeatherEffect()
                                    set udg_WeatherIsHere[GetConvertedPlayerId(GetTriggerPlayer())] = true
                                    set udg_integer = 0
                                else
                                    if ( Trig_weather_Func003Func001Func001Func002Func002Func002Func002Func002Func002C() ) then
                                        call RemoveWeatherEffect( udg_weather )
                                        set udg_WeatherIsHere[GetConvertedPlayerId(GetTriggerPlayer())] = false
                                    else
                                    endif
                                endif
                            endif
                        endif
                    endif
                endif
            endif
        else
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call EnableWeatherEffect( GetLastCreatedWeatherEffect(), true )
    set udg_localplayer = null
endfunction

To answer your question, non-triggered terrain deformations can still cause desyncs in rare cases (you have to use in if block and GetLocationZ() as far as I know, which is caused by some players having lower graphics settings), but I wouldn't change spells just because of that. I'm guessing it's in a triggered terrain deformation -or- one of these blocks I just pasted.
 
Level 7
Joined
Dec 31, 2011
Messages
249
That blocks is just for water and weather effects, and activates only after typing special commands (but desyncs, i repeat, creates usually on 35th minute). So that, as i think, also isn't a problem.

I'm guessing it's in a triggered terrain deformation
I repeat, no triggered terrain deformation now... or show me to them in code.

What about triggers in that post? Has any reasons of desyncs?
 
Level 7
Joined
Dec 31, 2011
Messages
249
I can remove that, but that effects and triggers activates/deactivates just after typing commands like "-wesnow" and "-water red". You really think that is reason? Even without typing that commands? 99.9% of players don't use that commands... Triggers can create problem even without triggering?

Also, one game isn't a indicator, i will test more. Thx, i will try.
 
Nope, triggers cannot cause a problem without triggering. Someone's going to have to look through your uncompiled jass/gui for use of bad 'pan camera' (etc) actions/bj's.

I know it's a pain but you'll probably have to test this yourself by disabling one trigger at a time and playing a game (I know it takes 40 minutes)
 
Level 7
Joined
Dec 31, 2011
Messages
249
I need more than one game, at least five, and with more than 3 peoples each (or, maybe, with War3 Multiple Loader for emulate netplay).
I think, i will start beta-test of next update near end of the month, and for desynchronizations too.
Anyway i remove that triggers now, they are not really needed.
Waiting for, maybe, any more help.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Although you reset the udg_localplayer variable immediately to null in the other blocks, I want to mention that

JASS:
function Trig_GoGoGo_Func004Func001C takes nothing returns boolean
    if ( not ( IsPlayerAlly(ConvertedPlayer(GetForLoopIndexA()), udg_localplayer) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_GoGoGo_Actions takes nothing returns nothing
    call AddSpecialEffectTargetUnitBJ( "overhead", GetTriggerUnit(), "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageDeathCaster.mdl" )
    call ConditionalTriggerExecute( gg_trg_destroyspeceffect )
    call PlaySoundBJ( gg_snd_goku_kamehameha1 )
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 12
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        if ( Trig_GoGoGo_Func004Func001C() ) then
            call AddSpecialEffectTargetUnitBJ( "overhead", GetSpellTargetUnit(), "Abilities\\Weapons\\GlaiveMissile\\GlaiveMissileTarget.mdl" )
            call ConditionalTriggerExecute( gg_trg_destroyspeceffect )
        else
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call IssueTargetOrder( GetTriggerUnit(), "attack", GetSpellTargetUnit() )
    call GroupAddUnitSimple( GetTriggerUnit(), udg_Knights )
    call SetUnitPathing( GetTriggerUnit(), false )
endfunction

would indeed desync. Effects are not interactive objects but they count to the shared id stack that should be kept in sync, nor should you run triggers locally. Another thing, which is probably not severe, is that you desync the string table in the condition blocks of the snippets Codemonkey11 has posted above. "" creates a new string that is internally added to a global string table the first time for recycling purposes.
 
Level 7
Joined
Dec 31, 2011
Messages
249
25.06.2012

I starting the test of new version (after all fixes in that thread)... Two normal games and again desync in third game on 34th minute. Now i just try to optimize some parts of code, really don't know reasons :(

26.06.2012

Hm... No desyncs in last five games 35+ minutes each. I just change my item crafting system totally into JASS code. Maybe leaks in old system or using global values was reason?
Don't know. But anyway situation looks at least is acceptable now.
 
Last edited:
Status
Not open for further replies.
Top