• 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] Multiboards Per Player Cause Desync

Status
Not open for further replies.
Level 4
Joined
May 12, 2008
Messages
49
The title almost says it all:

I'm working on this map, and I'm using multiboards to add more resources, but when I start the triggers with the multiboards it causes desyncing :sad:

Here are the triggers:

  • Map Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Cinematic - Fade out over 0.00 seconds using texture White Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Camera - Set the camera bounds for (Picked player) to (Region centered at (Center of (Playable map area)) with size (10.00, 10.00))
      • Game - Display to (All players) for 30.00 seconds the text: Please wait while m...
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Loading |c0000ff00T...
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Lordaeron Summer - ...
      • Environment - Change terrain type at (Center of (Playable map area)) to Lordaeron Summer - Grass using variation -1 in an area of size 999 and shape Square
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Lordaeron Summer - ...
      • Environment - Change terrain type at (Center of (Playable map area)) to Lordaeron Summer - Grassy Dirt using variation -1 in an area of size 999 and shape Square
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Lordaeron Fall - Gr...
      • Environment - Change terrain type at (Center of (Playable map area)) to Lordaeron Fall - Grassy Dirt using variation -1 in an area of size 999 and shape Square
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Lordaeron Winter - ...
      • Environment - Change terrain type at (Center of (Playable map area)) to Lordaeron Winter - Grassy Snow using variation -1 in an area of size 999 and shape Square
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Lordaeron Winter - ...
      • Environment - Change terrain type at (Center of (Playable map area)) to Lordaeron Winter - Snow using variation -1 in an area of size 999 and shape Square
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Village - Crops
      • Environment - Change terrain type at (Center of (Playable map area)) to Village - Crops using variation -1 in an area of size 999 and shape Square
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Village Fall - Crop...
      • Environment - Change terrain type at (Center of (Playable map area)) to Village Fall - Crops using variation -1 in an area of size 999 and shape Square
      • Wait 1.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Loading |c00ff0000L...
      • Wait 2.00 seconds
      • Game - Display to (All players) for 30.00 seconds the text: Mountains
      • Environment - Change terrain type at (Center of (Playable map area)) to Lordaeron Summer - Grassy Dirt using variation -1 in an area of size 999 and shape Square
      • Neutral Building - Change the special minimap icon to <Empty String>
      • Destructible - Pick every destructible in (Playable map area) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Destructible-type of (Picked destructible)) Equal to Iron Deposit
            • Then - Actions
              • Environment - Change terrain type at (Position of (Picked destructible)) to Lordaeron Summer - Rock using variation -1 in an area of size 2 and shape Circle
            • Else - Actions
      • Destructible - Pick every destructible in (Playable map area) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Destructible-type of (Picked destructible)) Equal to Summer Tree Wall
            • Then - Actions
              • Environment - Change terrain type at (Position of (Picked destructible)) to Ashenvale - Vines using variation -1 in an area of size 2 and shape Circle
            • Else - Actions
      • Cinematic - Fade in over 2.00 seconds using texture White Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Camera - Set the camera bounds for (Picked player) to Vision <gen>
      • Trigger - Run Create Multiboard 1 <gen> (ignoring conditions)
      • Wait 0.01 seconds
      • Trigger - Run Multiboards Init <gen> (ignoring conditions)
      • Trigger - Turn on Food Decrease Copy <gen>
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Unit - Create 1 Pick Your Race for (Picked player) at ((Picked player) start location) facing Default building facing degrees
  • Multiboards Init
    • Events
    • Conditions
    • Actions
      • Player - Set Player 1 (Red) Current gold to 100
      • Player - Set Player 1 (Red) Current lumber to 5000
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Set Food[(Player number of (Picked player))] = 5000
          • Set Population[(Player number of (Picked player))] = 50
          • Trigger - Turn on Population Reaches 0 <gen>
          • Multiboard - Minimize KingdomStatus[(Player number of (Picked player))]
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 1, row 1 to 10.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 2, row 1 to 10.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 1, row 2 to 10.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 2, row 2 to 10.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 2, row 3 to 5.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 1, row 3 to 9.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 1, row 4 to 9.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 1, row 5 to 9.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 1, row 6 to 9.00% of the total screen width
          • Multiboard - Set the width for KingdomStatus[(Player number of (Picked player))] item in column 1, row 7 to 9.00% of the total screen width
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 1, row 1 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 1, row 2 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 2, row 1 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 2, row 2 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 2, row 3 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 2, row 4 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 2, row 5 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 2, row 6 to Show text and Hide icons
          • Multiboard - Set the display style for KingdomStatus[(Player number of (Picked player))] item in column 2, row 7 to Show text and Hide icons
          • Multiboard - Set the icon for KingdomStatus[(Player number of (Picked player))] item in column 1, row 3 to UI\Widgets\Console\Human\infocard-supply.blp
          • Multiboard - Set the icon for KingdomStatus[(Player number of (Picked player))] item in column 1, row 4 to UI\Feedback\Resources\ResourceGold.blp
          • Multiboard - Set the icon for KingdomStatus[(Player number of (Picked player))] item in column 1, row 5 to ReplaceableTextures\CommandButtons\BTNVillagerMan.blp
          • Multiboard - Set the icon for KingdomStatus[(Player number of (Picked player))] item in column 1, row 6 to ReplaceableTextures\PassiveButtons\PASBTNStatUp.blp
          • Multiboard - Set the icon for KingdomStatus[(Player number of (Picked player))] item in column 1, row 7 to ReplaceableTextures\CommandButtons\BTNSacrifice.blp
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 1 to Kingdom Name:
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 2, row 1 to (Name of (Picked player))
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 2 to -------------------...
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 2, row 2 to -------------------...
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 3 to Food:
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 4 to Taxes:
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 5 to Population:
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 6 to Happiness:
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 7 to Sacrifices:
          • Multiboard - Maximize KingdomStatus[(Player number of (Picked player))]
      • Player Group - Pick every player in Undead and do (Actions)
        • Loop - Actions
          • Multiboard - Set the icon for KingdomStatus[(Player number of (Picked player))] item in column 1, row 5 to ReplaceableTextures\CommandButtons\BTNAcolyte.blp
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 5 to Slaves:
      • Player Group - Pick every player in Human and do (Actions)
        • Loop - Actions
          • Multiboard - Set the icon for KingdomStatus[(Player number of (Picked player))] item in column 1, row 5 to ReplaceableTextures\CommandButtons\BTNVillagerMan.blp
          • Multiboard - Set the text for KingdomStatus[(Player number of (Picked player))] item in column 1, row 5 to Population:
  • Create Multiboard 1
    • Events
    • Conditions
    • Actions
      • Set Food[1] = 200
      • Multiboard - Create a multiboard with 2 columns and 7 rows, titled Kingdom Status
      • Set KingdomStatus[1] = (Last created multiboard)
      • Multiboard - Hide KingdomStatus[1]
      • Custom script: if ( GetLocalPlayer() == Player(0) ) then
      • Trigger - Run Create Multiboard 2 <gen> (checking conditions)
      • Multiboard - Show KingdomStatus[1]
      • Game - Display to (All players) the text: Showing 1
      • Custom script: endif
  • Create Multiboard 2
    • Events
    • Conditions
    • Actions
      • Set Food[2] = 200
      • Multiboard - Create a multiboard with 2 columns and 7 rows, titled Kingdom Status
      • Set KingdomStatus[2] = (Last created multiboard)
      • Multiboard - Hide KingdomStatus[2]
      • Custom script: if ( GetLocalPlayer() == Player(1) ) then
      • Multiboard - Show KingdomStatus[2]
      • Custom script: endif
 
  • Game - Display to (All players) the text: Showing 1
Definitely remove it.
Try replacing the action:
  • Multiboard - Hide KingdomStatus[2]
  • Custom script: if ( GetLocalPlayer() == Player(1) ) then
  • Multiboard - Show KingdomStatus[2]
  • Custom script: endif
with
  • Multiboard - Hide KingdomStatus[2]
  • Custom script: if GetLocalPlayer() == Player(1) then
  • Set Show = True
  • Custom script: endif
  • Custom script: call MultiboardDisplay (udg_KingdomStatus[2], udg_Show)
Same goes for Player (0).
 
Level 4
Joined
May 12, 2008
Messages
49
  • Game - Display to (All players) the text: Showing 1
Definitely remove it.
Try replacing the action:
  • Multiboard - Hide KingdomStatus[2]
  • Custom script: if ( GetLocalPlayer() == Player(1) ) then
  • Multiboard - Show KingdomStatus[2]
  • Custom script: endif
with
  • Multiboard - Hide KingdomStatus[2]
  • Custom script: if GetLocalPlayer() == Player(1) then
  • Set Show = True
  • Custom script: endif
  • Custom script: call MultiboardDisplay (udg_KingdomStatus[2], udg_Show)
Same goes for Player (0).

Shouldn't Show be an array?
 
Level 13
Joined
Mar 24, 2010
Messages
950
i had this exact problem when trying to give all the players their own MB and having it desync in multuplayer. You need to not have any actions in the MB do anything with just a triggering player. Also if you want to have a different multi board for each player you need to make the MB's all in LocalPlayer for that local player and only show that MB to that specific player. by no means EVER show the same MB to 2 different players because the thing that makes it have the biggest desync prob is when 1 player has the MB maximized and the other has it minimized and an action is done making the MB both players do something.
 
Level 4
Joined
May 12, 2008
Messages
49
i had this exact problem when trying to give all the players their own MB and having it desync in multuplayer. You need to not have any actions in the MB do anything with just a triggering player. Also if you want to have a different multi board for each player you need to make the MB's all in LocalPlayer for that local player and only show that MB to that specific player. by no means EVER show the same MB to 2 different players because the thing that makes it have the biggest desync prob is when 1 player has the MB maximized and the other has it minimized and an action is done making the MB both players do something.

First of all, that didn't make any sense.
And I managed to make the desync go away, but now it wont show for me.

I moved the run Create Multiboard 2 out of the "if GetLocalPlayer etc."
After the endif, if you didn't get that
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
When you create multiboards for each player you do not perform actions on them locally, you simply control which local player can see each multiboard. If the multiboards are very similar, this creates the "illusion" that there are different values for each player, when in fact it is an entirely different multiboard.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Shouldn't Show be an array?

The Show variable that was used is only so that there aren't any functions called in local code, the only thing that is performed locally is the changing of a boolean variable (which will not cause a desync). That is why you don't need it to be an array, it is simply to alter the flag that will show/hide a multiboard without having to use any functions inside the local if-statement.

I moved the run Create Multiboard 2 out of the "if GetLocalPlayer etc."
After the endif, if you didn't get that

You shouldn't be doing anything inside the local code except for changing the value of the boolean that will change whether or not the multiboard is displayed or hidden from view. Everything else should be done outside of local code.
 
Level 13
Joined
Mar 24, 2010
Messages
950
Yeah, me and Berb tried figuring out a multi board desync prob a while ago and after everything it just ended up being a triggering player function inside it. Like i had players press esc to open/close and it would check if its open or closed and act accordingly, and display to the triggering unit Open! when it was opening.

Just having that in there made it desync if 1 player happened to have it open while another player had it closed using the mouse to manually close/open it. Taking that out got rid of the desync prob.
 
Level 10
Joined
May 27, 2009
Messages
495
i have already fixed this problem myself and I like to share what i've done

I use a jass / vjass script to show / hide the multiboard for a player (probably a separate function from the main function and works as itself)

Here check it:
JASS:
function ShowBoard takes multiboard mb, boolean b, player p returns nothing
    if GetLocalPlayer == p then
          call MultiboardDisplay(mb,b)
    endif
endfunction

function MainFrame takes nothing returns nothing
     //Call the showboard function
     set mb = YourMultiboard
     call ShowBoard(mb,true,GetTriggerPlayer())
endfunction

that is the function i am using in my map and it never gives me problems and works as it is. I try merging it to the main function but there are chances especially with multiplayer that other players may not see their own board

Hope this helps
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
JASS:
function ShowBoard takes multiboard mb, boolean b, player p returns nothing
    if GetLocalPlayer == p then
          call MultiboardDisplay(mb,b)
    endif
endfunction

I wouldn't trust that to not cause a desync (even if once in awhile), but I've definitely seen problems using it before; if you're using it fine now then you can proceed to but you don't want something like this becoming a problem in the future. What I would recommend is something like:

JASS:
function MultiboardDisplayLocal takes multiboard mb, player p, boolean flag returns nothing
    local boolean b = IsMultiboardDisplayed(mb)
        if GetLocalPlayer() != p then
            set flag = b
        endif
        call MultiboardDisplay(mb, flag)
endfunction

Mr.Kronos said:
And I managed to make the desync go away, but now it wont show for me.

So what exactly is the problem now?

Mr.Kronos said:
I moved the run Create Multiboard 2 out of the "if GetLocalPlayer etc."
After the endif, if you didn't get that

That's the rest of your message, it doesn't sound like you had any additional problems. Is this thread solved?
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Because I want every player who isn't the designated one to retain their multiboard visibility, which is why I set flag = b so that only the specified player has flag = flag.

It's kinda ½ solved, since player 2 gets to see the multiboard, but I don't?
And all I did was move that "Run Create Multiboard 2" out of the local code

Okay well I would just remove whatever implementation of if GetLocalPlayer() == Player(0) then that you have and simply use the function that I posted to display the multiboards to each player. It's guaranteed to work without any desyncs, and it is a lot less confusing for you than having to worry about what to place inside/outside of the local if-statement.
 
Level 4
Joined
May 12, 2008
Messages
49
So I should do like this:

Remove all use of GetLocalPlayer in my current create multiboard triggers
Create a multiboard, define it (with or without an array?)
make a new trigger
paste the jass code you posted
and change MB to name of MB Variable?

Correct me if I'm wrong
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Remove all use of GetLocalPlayer in my current create multiboard triggers
Create a multiboard, define it (with or without an array?)
make a new trigger
paste the jass code you posted
and change MB to name of MB Variable

I would paste the code I posted in the Custom Script section (click on the map name in the Trigger Editor in the tree-dialog on the left).

Definitely use an array for your multiboards so they can be looped through easily, and what you're going to want to do is use the code I posted (with custom script actions) to display the multiboard, rather than the GUI action. For player "1" you're going to want to use my function to display "MultiBoardVar[1]" and then so on.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Okay, let's say you've got a multi-board array named Board. Keep in mind that in JASS the names of GUI variables are all given the udg_ prefix. With this in mind, your Board variable is going to be referenced as: udg_Board - in addition to the index of a specific element in the array.

In this example I'll just use bj_forLoopAIndex, which is what is used when you have a For each "Integer A" loop in GUI.

  • Custom script: call MultiboardDisplayLocal(udg_Board[bj_forLoopAIndex], bj_forLoopAIndex-1, true)
This will perform the same actions as if you were to use the "Multiboard - Show/Hide" actions except it will only perform them locally for a specified player. It only needs to be called once for each associated player, so you'll simply loop through each player index (1 through 12) and use the custom script that I posted above inside the loop. The code I posted also assumes you're using Integer A, rather than Integer B or a custom integer variable.
 
Level 4
Joined
May 12, 2008
Messages
49
Yeah, I'm using IntegerA.

But I'm also using PlayerNumber of (Picked Player)

But so all I need to do is create a trigger that runs on start (Not map INIT)
and use that custom script (change the udg_Board to udg_KingdomStatus).

But should I make a trigger like this:

  • Multiboard
    • Events
      • Time - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • Multiboard - Create a multiboard with 1 columns and 1 rows, titled Test
          • Set Board[(Integer A)] = (Last created multiboard)
and a trigger like this:

  • Multiboard Show
    • Events
      • Time - Elapsed game time is 0.02 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • Custom script: call MultiboardDisplayLocal(udg_Board[bj_forLoopAIndex], bj_forLoopAIndex-1, true)


And paste:

JASS:
function MultiboardDisplayLocal takes multiboard mb, player p, boolean flag returns nothing
    local boolean b = IsMultiboardDisplayed(mb)
        if GetLocalPlayer() != p then
            set flag = b
        endif
        call MultiboardDisplay(mb, flag)
endfunction

in the Custom Script Code area when I press the mapname on the top of the trigger tree?

Right?
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Okay that's probably not the line where the problem is, the syntax checker isn't very good at detecting exact locations of error. Post the previous 3-4 lines of code.

Actually I think I see where the problem is:

  • Custom script: call MultiboardDisplayLocal(udg_Board[bj_forLoopAIndex], bj_forLoopAIndex-1, true)
Instead of "bj_forLoopAIndex-1" it should be "Player( bj_forLoopAIndex-1 )".
 
Level 4
Joined
May 12, 2008
Messages
49
Sure, I changed it again, and haven't tested it yet though.

  • Show Multiboards
    • Events
      • Time - Elapsed game time is 0.03 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to (Number of players in (All players matching (((Matching player) controller) Equal to User))), do (Actions)
        • Loop - Actions
          • Multiboard - Hide (Last created multiboard)
          • Custom script: call MultiboardDisplayLocal(udg_KingdomStatus[bj_forLoopAIndex], Player( bj_forLoopAIndex-1 ), true)
          • Multiboard - Maximize KingdomStatus[(Integer A)]
      • (DISABLED!) For each (Integer A) from 1 to (Number of players in (All players matching (((Matching player) slot status) Equal to Is playing))), do (Actions)
        • Loop - Actions
          • Custom script: call MultiboardDisplayLocal(udg_KingdomStatus[bj_forLoopAIndex], Player( bj_forLoopAIndex-1 ), true)
        • Trigger - Turn on Food Decrease Copy <gen>
Ignore the second For Each integer.
That's the show code
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Okay well first of all you don't need to hide the multiboard, by default multiboards are not revealed (you have to show them, at least I'm pretty sure that's the case) so you can simply use the function I provided.

Secondly you do not need to wait 0.03 seconds into game-time, a value of 0.00 should still suffice.

Another thing I would recommend is changing your loop to run through players 1 to 12; the loop is only going to iterate once and you're probably slowing things down by using tons of BJ functions anyways - it's easier to just give it a constant. Also if you've arranged players specifically then your loop isn't going to be guaranteed to work; in the situation where there are 7 players considered users but the seventh player is in the eighth player's slot (thus he would be referenced Player(7) instead of Player(6)) then your loop is going to miss that player.

After you've tested this code following my recommendations please post back with the results. Be sure to post your code when you do.
 
Status
Not open for further replies.
Top