Hivers, time has come for the community to understand how to synchronize data to get each player his own customized UI 
I'm doing a unit selection panel (check picture provided) and I'd like it to work separetely for each player. It's running fine in solo but I will get automatic desyncs in MP when someone use the buttons.
I've isolated the display parts into GetLocalPlayer() condition block and the only thing I'm doing is to set variables in these blocks to check their value after so remaining actions are executed for everyone.
I've ran a test setting a local integer to get the id of the clicked button inside a GetLocalPlayer() block and use his value after it, this leaded to a crash for every other player.
Then I've stumbled upon this thread trying to understand how I could synchronize my data. I've ran the same test with my local integer but this time with a gamecache and synchronize call methods, it also leaded to a crash.
According to @Taysen, one must call the BlzGetFrameByName function at least once for every players before using it in GetLocalPlayer() blocks, so I did an "anti-desync" function that just use this method upon every frame I got in my unit panel to avoid desyncs.
Now I must confess I feel a bit blocked, here the code involved in the process. ID_XXX are just global integers declared in the same script file.
I hope I can solve it asap because my alpha release is nearly finished
Thanks !
Callback function when a frame is clicked inside the unit panel (pressing the "roll" button will create a desync issue)
GetUICache method

I'm doing a unit selection panel (check picture provided) and I'd like it to work separetely for each player. It's running fine in solo but I will get automatic desyncs in MP when someone use the buttons.
I've isolated the display parts into GetLocalPlayer() condition block and the only thing I'm doing is to set variables in these blocks to check their value after so remaining actions are executed for everyone.
I've ran a test setting a local integer to get the id of the clicked button inside a GetLocalPlayer() block and use his value after it, this leaded to a crash for every other player.
Then I've stumbled upon this thread trying to understand how I could synchronize my data. I've ran the same test with my local integer but this time with a gamecache and synchronize call methods, it also leaded to a crash.
According to @Taysen, one must call the BlzGetFrameByName function at least once for every players before using it in GetLocalPlayer() blocks, so I did an "anti-desync" function that just use this method upon every frame I got in my unit panel to avoid desyncs.
Now I must confess I feel a bit blocked, here the code involved in the process. ID_XXX are just global integers declared in the same script file.
I hope I can solve it asap because my alpha release is nearly finished
Thanks !
Callback function when a frame is clicked inside the unit panel (pressing the "roll" button will create a desync issue)
JASS:
function SelectionUIButtonClick takes nothing returns nothing
local framehandle frameClicked = BlzGetTriggerFrame()
local player trigPlayer = GetTriggerPlayer()
local integer playerIndex = GetConvertedPlayerId(trigPlayer)
local integer unitTypeClicked
local integer goldCost
local integer buttonId = NO_ID
if GetLocalPlayer() == trigPlayer then
if ( frameClicked == BlzGetFrameByName("UnitSelectionUIOption_0", 0) ) then
set unitTypeClicked = LoadInteger(udg_hashRandomUnits, playerIndex, 1)
set goldCost = S2I(BlzFrameGetText(BlzGetFrameByName("UnitSelectionUIAmountText_0" ,0)))
set buttonId = ID_SELECT_UNIT
elseif ( frameClicked == BlzGetFrameByName("UnitSelectionUIOption_1", 0) ) then
set unitTypeClicked = LoadInteger(udg_hashRandomUnits, playerIndex, 2)
set goldCost = S2I(BlzFrameGetText(BlzGetFrameByName("UnitSelectionUIAmountText_1" ,0)))
set buttonId = ID_SELECT_UNIT
....
elseif ( frameClicked == BlzGetFrameByName("UnitSelectionUICloseButton", 0) ) then
call BlzFrameSetVisible(BlzGetFrameByName("UnitSelectionUI", 0), false)
elseif ( frameClicked == BlzGetFrameByName("UnitSelectionUIReRollButton", 0) ) then
set buttonId = ID_ROLL
call StoreInteger(GetUICache(), "btnCache" + I2S(GetPlayerId(trigPlayer)), "id", buttonId)
call SyncStoredInteger(GetUICache(), "btnCache" + I2S(GetPlayerId(trigPlayer)), "id")
elseif ( frameClicked == BlzGetFrameByName("UnitSelectionUILockButton", 0) ) then
set buttonId = ID_LOCK
endif
endif
//Syncs up data
call TriggerSyncReady()
set buttonId = GetStoredInteger(GetUICache(), "btnCache" + I2S(GetPlayerId(trigPlayer)), "id")
//Do actions for everyone according to the clicked button
if buttonId == ID_ROLL then
call IssueImmediateOrder( udg_DRAFTERS[playerIndex], "channel" )
elseif buttonId == ID_SELECT_UNIT then
call CreateUnitInStash(unitTypeClicked, playerIndex, trigPlayer)
call AdjustPlayerStateBJ( -goldCost, trigPlayer, PLAYER_STATE_RESOURCE_GOLD )
if GetLocalPlayer() == trigPlayer then
call BlzFrameSetVisible(frameClicked, false)
endif
endif
set trigPlayer = null
set frameClicked = null
endfunction
GetUICache method
JASS:
function GetUICache takes nothing returns gamecache
if udg_CacheUI == null then
call FlushGameCache(InitGameCache("uiCache"))
set udg_CacheUI = InitGameCache("uiCache")
endif
return udg_CacheUI
endfunction
Attachments
Last edited: