- Joined
- Apr 11, 2006
- Messages
- 338
Hello, guys,
I'm the developer of Jungle Trolls Reborn - quite a hardcore survival game created more than eight years ago and frequently updated each few months since then.
The previous version of the game - JTR 5.5, was partially converted to JASS by the other developer, sadly not active anymore. The problem is that since then there is a desynchronisation at game start: while bot hosting at the moment the first player chooses game difficulty and all starting triggers are ran, some of the players get desynchronized. The more players in the game, the more desyncs (average 1 desync per 4 players).
Reverting back to GUI as it was is not an option - the game had too many interconnected improvements, so I must work with what I have.
I am fully aware that a desync issue may have many reasons behind it. I have studied similar topics (1, 2, 3), but I can't find a solution in them.
I'm not using GetLocalPlayer function.
As you may see, testing of this issue is quite impossible: I have to do the change, bot host a multiplayer game, gather at least 4-6 players and see what it happens - for every try to fix it. That's why I need help from an experienced JASS developer.
I suspect that something in this trigger might be wrong:
If you are able to help and willing to review more triggers, I would send you an unprotected copy of the game and I'll give my best to explain whatever needed (the game is huge, complicated and having many interconnected functions).
I have put much efforts in this game, even though I have no profit from it. Still, I am willing to rent a bot for hosting it, because it is loved by its fans. It deserves to live.
I'm the developer of Jungle Trolls Reborn - quite a hardcore survival game created more than eight years ago and frequently updated each few months since then.
The previous version of the game - JTR 5.5, was partially converted to JASS by the other developer, sadly not active anymore. The problem is that since then there is a desynchronisation at game start: while bot hosting at the moment the first player chooses game difficulty and all starting triggers are ran, some of the players get desynchronized. The more players in the game, the more desyncs (average 1 desync per 4 players).
Reverting back to GUI as it was is not an option - the game had too many interconnected improvements, so I must work with what I have.
I am fully aware that a desync issue may have many reasons behind it. I have studied similar topics (1, 2, 3), but I can't find a solution in them.
I'm not using GetLocalPlayer function.
As you may see, testing of this issue is quite impossible: I have to do the change, bot host a multiplayer game, gather at least 4-6 players and see what it happens - for every try to fix it. That's why I need help from an experienced JASS developer.
I suspect that something in this trigger might be wrong:
JASS:
function Trig_Player_ini_Func001C takes nothing returns boolean
if ( not ( udg_MB_ModeAction == "Yes" ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func002C takes nothing returns boolean
if ( not ( udg_MB_ModePlenty == "Yes" ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func004C takes nothing returns boolean
if ( not ( udg_TeamNumber[1] > 0 ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func005C takes nothing returns boolean
if ( not ( udg_TeamNumber[2] > 0 ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func006C takes nothing returns boolean
if ( not ( udg_TeamNumber[3] > 0 ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func008Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func008C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(0)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func010Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func010C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(1)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func012Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func012C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(2)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func014Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func014C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(3)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func016Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func016C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(4)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func018Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func018C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(5)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func020Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func020C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(6)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func022Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func022C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(7)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func024Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func024C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(8)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func026Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func026C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(9)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func028Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func028C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(10)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func030Func006002 takes nothing returns nothing
call RemoveUnit( GetEnumUnit() )
endfunction
function Trig_Player_ini_Func030C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(11)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction
function Trig_Player_ini_Func045A takes nothing returns nothing
call ForceUICancelBJ( GetEnumPlayer() )
endfunction
function Trig_Player_ini_Actions takes nothing returns nothing
local integer i = 0
if ( Trig_Player_ini_Func001C() ) then
else
call DestroyTrigger( gg_trg_Action_Mode_JASS )
endif
if ( Trig_Player_ini_Func002C() ) then
else
call DestroyTrigger( gg_trg_Plenty_Mode_JASS )
call TriggerRegisterTimerEventSingle( gg_trg_StopItemDrop_and_Visibility, 5000.00 )
endif
// Set Totem Kit for Teams
if ( Trig_Player_ini_Func004C() ) then
call SetItemInvulnerableBJ( udg_TotemKit[1], true )
else
call RemoveItem( udg_TotemKit[1] )
set udg_TotemOwned[1] = true
endif
if ( Trig_Player_ini_Func005C() ) then
call SetItemInvulnerableBJ( udg_TotemKit[2], true )
else
call RemoveItem( udg_TotemKit[2] )
set udg_TotemOwned[2] = true
endif
if ( Trig_Player_ini_Func006C() ) then
call SetItemInvulnerableBJ( udg_TotemKit[3], true )
else
call RemoveItem( udg_TotemKit[3] )
set udg_TotemOwned[3] = true
endif
// Player1
if ( Trig_Player_ini_Func008C() ) then
call PanCameraToTimedLocForPlayer( Player(0), GetPlayerStartLocationLoc(Player(0)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0338, Player(0) )
else
set udg_PactWithTheDevil[1] = true
set udg_Hero_Troll[1] = gg_unit_h009_0340
call KillUnit( gg_unit_h009_0340 )
call RemoveUnit( gg_unit_h017_0338 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(0)), function Trig_Player_ini_Func008Func006002 )
endif
// Player2
if ( Trig_Player_ini_Func010C() ) then
call PanCameraToTimedLocForPlayer( Player(1), GetPlayerStartLocationLoc(Player(1)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0066, Player(1) )
else
set udg_PactWithTheDevil[2] = true
set udg_Hero_Troll[2] = gg_unit_h009_0341
call KillUnit( gg_unit_h009_0341 )
call RemoveUnit( gg_unit_h017_0066 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(1)), function Trig_Player_ini_Func010Func006002 )
endif
// Player3
if ( Trig_Player_ini_Func012C() ) then
call PanCameraToTimedLocForPlayer( Player(2), GetPlayerStartLocationLoc(Player(2)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0097, Player(2) )
else
set udg_PactWithTheDevil[3] = true
set udg_Hero_Troll[3] = gg_unit_h009_0342
call KillUnit( gg_unit_h009_0342 )
call RemoveUnit( gg_unit_h017_0097 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(2)), function Trig_Player_ini_Func012Func006002 )
endif
// Player4
if ( Trig_Player_ini_Func014C() ) then
call PanCameraToTimedLocForPlayer( Player(3), GetPlayerStartLocationLoc(Player(3)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0150, Player(3) )
else
set udg_PactWithTheDevil[4] = true
set udg_Hero_Troll[4] = gg_unit_h009_0343
call KillUnit( gg_unit_h009_0343 )
call RemoveUnit( gg_unit_h017_0150 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(3)), function Trig_Player_ini_Func014Func006002 )
endif
// Player5
if ( Trig_Player_ini_Func016C() ) then
call PanCameraToTimedLocForPlayer( Player(4), GetPlayerStartLocationLoc(Player(4)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0238, Player(4) )
else
set udg_PactWithTheDevil[5] = true
set udg_Hero_Troll[5] = gg_unit_h009_0344
call KillUnit( gg_unit_h009_0344 )
call RemoveUnit( gg_unit_h017_0238 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(4)), function Trig_Player_ini_Func016Func006002 )
endif
// Player6
if ( Trig_Player_ini_Func018C() ) then
call PanCameraToTimedLocForPlayer( Player(5), GetPlayerStartLocationLoc(Player(5)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0204, Player(5) )
else
set udg_PactWithTheDevil[6] = true
set udg_Hero_Troll[6] = gg_unit_h009_0345
call KillUnit( gg_unit_h009_0345 )
call RemoveUnit( gg_unit_h017_0204 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(5)), function Trig_Player_ini_Func018Func006002 )
endif
// Player7
if ( Trig_Player_ini_Func020C() ) then
call PanCameraToTimedLocForPlayer( Player(6), GetPlayerStartLocationLoc(Player(6)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0218, Player(6) )
else
set udg_PactWithTheDevil[7] = true
set udg_Hero_Troll[7] = gg_unit_h009_0346
call KillUnit( gg_unit_h009_0346 )
call RemoveUnit( gg_unit_h017_0218 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(6)), function Trig_Player_ini_Func020Func006002 )
endif
// Player8
if ( Trig_Player_ini_Func022C() ) then
call PanCameraToTimedLocForPlayer( Player(7), GetPlayerStartLocationLoc(Player(7)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0229, Player(7) )
else
set udg_PactWithTheDevil[8] = true
set udg_Hero_Troll[8] = gg_unit_h009_0347
call KillUnit( gg_unit_h009_0347 )
call RemoveUnit( gg_unit_h017_0229 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(7)), function Trig_Player_ini_Func022Func006002 )
endif
// Player9
if ( Trig_Player_ini_Func024C() ) then
call PanCameraToTimedLocForPlayer( Player(8), GetPlayerStartLocationLoc(Player(8)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0339, Player(8) )
else
set udg_PactWithTheDevil[9] = true
set udg_Hero_Troll[9] = gg_unit_h009_0348
call KillUnit( gg_unit_h009_0348 )
call RemoveUnit( gg_unit_h017_0339 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(8)), function Trig_Player_ini_Func024Func006002 )
endif
// Player10
if ( Trig_Player_ini_Func026C() ) then
call PanCameraToTimedLocForPlayer( Player(9), GetPlayerStartLocationLoc(Player(9)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0232, Player(9) )
else
set udg_PactWithTheDevil[10] = true
set udg_Hero_Troll[10] = gg_unit_h009_0349
call KillUnit( gg_unit_h009_0349 )
call RemoveUnit( gg_unit_h017_0232 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(9)), function Trig_Player_ini_Func026Func006002 )
endif
// Player11
if ( Trig_Player_ini_Func028C() ) then
call PanCameraToTimedLocForPlayer( Player(10), GetPlayerStartLocationLoc(Player(10)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0234, Player(10) )
else
set udg_PactWithTheDevil[11] = true
set udg_Hero_Troll[11] = gg_unit_h009_0350
call KillUnit( gg_unit_h009_0350 )
call RemoveUnit( gg_unit_h017_0234 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(10)), function Trig_Player_ini_Func028Func006002 )
endif
// Player12
if ( Trig_Player_ini_Func030C() ) then
call PanCameraToTimedLocForPlayer( Player(11), GetPlayerStartLocationLoc(Player(11)), 0 )
call SelectUnitForPlayerSingle( gg_unit_h017_0235, Player(11) )
else
set udg_PactWithTheDevil[12] = true
set udg_Hero_Troll[12] = gg_unit_h009_0351
call KillUnit( gg_unit_h009_0351 )
call RemoveUnit( gg_unit_h017_0235 )
set bj_wantDestroyGroup=true
call ForGroupBJ( GetUnitsOfPlayerAll(Player(11)), function Trig_Player_ini_Func030Func006002 )
endif
call PlaySoundBJ( gg_snd_StartGameMusic )
call StartTimerBJ( udg_TotemCheck, false, 60.00 )
call StartTimerBJ( udg_DayTimer, true, 500.00 )
call StartTimerBJ( udg_WeatherTimer, true, 360.00 )
call StartTimerBJ( udg_HelpTimer, true, 25.00 )
call StartTimerBJ( udg_Timer10sec, true, 10.00 )
call DisplayTimedTextToForce( GetPlayersAll(), 10.00, "TRIGSTR_1213" )
call StartTimerBJ( udg_Totem_timer, false, 600.00 )
call CreateTimerDialogBJ( udg_Totem_timer, "TRIGSTR_1298" )
set udg_Totem_window = GetLastCreatedTimerDialogBJ()
call TimerDialogDisplayBJ( true, udg_Totem_window )
call ConditionalTriggerExecute( gg_trg_Create_MultiBoard )
call EnableTrigger( gg_trg_Update_MultiBoard )
call EnableTrigger( gg_trg_Show_and_Swap_Multiboard )
call ForForce( GetPlayersAll(), function Trig_Player_ini_Func045A )
call DestroyTrigger( GetTriggeringTrigger() )
call TriggerSleepAction( 0.10 )
loop
exitwhen i > 11
if ( GetPlayerController(Player(i)) != MAP_CONTROL_USER ) then
if IsUnitType(udg_Hero_Building[i+1], UNIT_TYPE_DEAD) == false then
call IssueNeutralImmediateOrderById( Player(i), udg_Hero_Building[i+1], 'H001' )
call TriggerSleepAction( 0.10 )
set udg_PactWithTheDevil[i+1] = true
call KillUnit( udg_Hero_Troll[i+1] )
else
set udg_PactWithTheDevil[i+1] = true
call KillUnit( udg_Hero_Troll[i+1] )
call KillUnit( udg_Troll_Spirit[i+1] )
endif
endif
set i = i + 1
endloop
endfunction
//===========================================================================
function InitTrig_Player_ini takes nothing returns nothing
set gg_trg_Player_ini = CreateTrigger( )
call TriggerAddAction( gg_trg_Player_ini, function Trig_Player_ini_Actions )
endfunction
If you are able to help and willing to review more triggers, I would send you an unprotected copy of the game and I'll give my best to explain whatever needed (the game is huge, complicated and having many interconnected functions).
I have put much efforts in this game, even though I have no profit from it. Still, I am willing to rent a bot for hosting it, because it is loved by its fans. It deserves to live.
Last edited: