• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Will this desync?

Status
Not open for further replies.
Level 17
Joined
Dec 11, 2014
Messages
2,004
The title says enough, will this desync?
Or in other words: Is the GetLocalPlayer() safe to use here?

_______

The System is meant to be a music system, both having an External and a Normal music system. the External music will support three files in the file typed in and the tracks "ATfaH - 1/2/3". It DOES work in singleplayer, but I don't know about Multiplayer or LAN.

PS: yes the array size of my timers are set to 8.


  • MS Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Sound - Set music volume to 0.00%
      • For each (Integer A) from 1 to 8, do (Actions)
        • Loop - Actions
          • Trigger - Add to MS Register <gen> the event (Player - (Player((Integer A))) types a chat message containing -Music External as A substring)
          • Trigger - Add to MS Normal <gen> the event (Player - (Player((Integer A))) types a chat message containing -Music Normal as An exact match)
  • MS Register
    • Events
    • Conditions
    • Actions
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Set MS_Filename[(Player number of (Triggering player))] = (Substring((Entered chat string), 17, (Length of (Entered chat string))))
      • Set TempString = MS_Filename[(Player number of (Triggering player))]
      • Set TempString = (TempString + (\\ + ATfaH - 1.mp3))
      • Custom script: if GetSoundFileDuration(udg_TempString) > 0 then
      • Set MS_Has_EF[(Player number of (Triggering player))] = True
      • Set Temp_PlayerGroup = (Player group((Triggering player)))
      • Game - Display to Temp_PlayerGroup the text: Ezio's Family Detec...
      • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • Custom script: else
      • Set Temp_PlayerGroup = (Player group((Triggering player)))
      • Game - Display to Temp_PlayerGroup the text: Ezio's Family Missi...
      • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • Custom script: endif
      • Custom script: endif
      • -------- - --------
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Set TempString = MS_Filename[(Player number of (Triggering player))]
      • Set TempString = (TempString + (\\ + ATfaH - 2.mp3))
      • Custom script: if GetSoundFileDuration(udg_TempString) > 0 then
      • Set MS_Has_N[(Player number of (Triggering player))] = True
      • Set Temp_PlayerGroup = (Player group((Triggering player)))
      • Game - Display to Temp_PlayerGroup the text: Nightsong Detected.
      • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • Custom script: else
      • Set Temp_PlayerGroup = (Player group((Triggering player)))
      • Game - Display to Temp_PlayerGroup the text: Nightsong Missing.
      • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • Custom script: endif
      • Custom script: endif
      • -------- - --------
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Set TempString = MS_Filename[(Player number of (Triggering player))]
      • Set TempString = (TempString + (\\ + ATfaH - 3.mp3))
      • Custom script: if GetSoundFileDuration(udg_TempString) > 0 then
      • Set MS_Has_I[(Player number of (Triggering player))] = True
      • Set Temp_PlayerGroup = (Player group((Triggering player)))
      • Game - Display to Temp_PlayerGroup the text: Ironforge Detected.
      • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • Custom script: else
      • Set Temp_PlayerGroup = (Player group((Triggering player)))
      • Game - Display to Temp_PlayerGroup the text: Ironforge Missing.
      • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • Custom script: endif
      • Custom script: endif
      • -------- - --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MS_Has_EF[(Player number of (Triggering player))] Equal to False
          • MS_Has_I[(Player number of (Triggering player))] Equal to False
          • MS_Has_N[(Player number of (Triggering player))] Equal to False
        • Then - Actions
          • Game - Display to Temp_PlayerGroup the text: |cFFFF0000Playing E...
          • Sound - Set music volume to 0.00%
          • Set MS_Filename[(Player number of (Triggering player))] = <Empty String>
        • Else - Actions
          • Sound - Set music volume to 100.00%
          • Set MS_MusicCounterEx[(Player number of (Triggering player))] = 0
          • Countdown Timer - Start MS_Timer[(Player number of (Triggering player))] as a One-shot timer that will expire in 1.00 seconds
  • MS Normal
    • Events
    • Conditions
    • Actions
      • Set MS_Has_EF[(Player number of (Triggering player))] = False
      • Set MS_Has_N[(Player number of (Triggering player))] = False
      • Set MS_Has_I[(Player number of (Triggering player))] = False
      • Sound - Set music volume to 100.00%
      • Set MS_MusicCounter[(Player number of (Triggering player))] = 0
  • MS Core
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer TempInt) from 1 to 8, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Remaining time for MS_Timer[(Player number of (Triggering player))]) Less than or equal to 0.00
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • MS_Has_EF[TempInt] Equal to False
                  • MS_Has_I[TempInt] Equal to False
                  • MS_Has_N[TempInt] Equal to False
                • Then - Actions
                  • Sound - Set music volume to 100.00%
                  • Set MS_MusicCounter[TempInt] = ((MS_MusicCounter[TempInt] + 1) mod 5)
                  • Set TempInt2 = MS_MusicCounter[TempInt]
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • TempInt2 Equal to 0
                    • Then - Actions
                      • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                      • Sound - Stop music Immediately
                      • Sound - Play SadMystery01 <gen>
                      • Custom script: endif
                      • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of SadMystery01 <gen>) seconds
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • TempInt2 Equal to 1
                        • Then - Actions
                          • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                          • Sound - Stop music Immediately
                          • Sound - Play MainTheme <gen>
                          • Custom script: endif
                          • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of MainTheme <gen>) seconds
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • TempInt2 Equal to 2
                            • Then - Actions
                              • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                              • Sound - Stop music Immediately
                              • Sound - Play HeroicVictory01 <gen>
                              • Custom script: endif
                              • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of HeroicVictory01 <gen>) seconds
                            • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • TempInt2 Equal to 3
                                • Then - Actions
                                  • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                                  • Sound - Stop music Immediately
                                  • Sound - Play IllidansTheme <gen>
                                  • Custom script: endif
                                  • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of IllidansTheme <gen>) seconds
                                • Else - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • TempInt2 Equal to 4
                                    • Then - Actions
                                      • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                                      • Sound - Stop music Immediately
                                      • Sound - Play BloodElfTheme01 <gen>
                                      • Custom script: endif
                                      • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of BloodElfTheme01 <gen>) seconds
                                    • Else - Actions
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • TempInt2 Equal to 5
                                        • Then - Actions
                                          • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                                          • Sound - Stop music Immediately
                                          • Sound - Play Comradeship01 <gen>
                                          • Custom script: endif
                                          • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of Comradeship01 <gen>) seconds
                                        • Else - Actions
                • Else - Actions
                  • Sound - Set music volume to 100.00%
                  • Set MS_MusicCounterEx[TempInt] = ((MS_MusicCounterEx[TempInt] + 1) mod 4)
                  • Set TempInt2 = MS_MusicCounterEx[TempInt]
                  • Set TempString = MS_Filename[(Player number of (Triggering player))]
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • TempInt2 Equal to 0
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • MS_Has_I[TempInt] Equal to True
                        • Then - Actions
                          • Set TempString = MS_Filename[TempInt]
                          • Set TempString = (TempString + (\\ + ATfaH - 1.mp3))
                          • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                          • Sound - Stop music Immediately
                          • Custom script: call PlayMusic(udg_TempString)
                          • Custom script: endif
                          • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of IllidansTheme <gen>) seconds
                        • Else - Actions
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • TempInt2 Equal to 1
                        • Then - Actions
                          • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                          • Sound - Stop music Immediately
                          • Sound - Play MainTheme <gen>
                          • Custom script: endif
                          • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of MainTheme <gen>) seconds
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • TempInt2 Equal to 2
                            • Then - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • MS_Has_EF[TempInt] Equal to True
                                • Then - Actions
                                  • Set TempString = MS_Filename[TempInt]
                                  • Set TempString = (TempString + (\\ + ATfaH - 2.mp3))
                                  • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                                  • Sound - Stop music Immediately
                                  • Custom script: call PlayMusic(udg_TempString)
                                  • Custom script: endif
                                  • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of Comradeship01 <gen>) seconds
                                • Else - Actions
                            • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • TempInt2 Equal to 3
                                • Then - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • MS_Has_N[TempInt] Equal to True
                                    • Then - Actions
                                      • Set TempString = MS_Filename[TempInt]
                                      • Set TempString = (TempString + (\\ + ATfaH - 3.mp3))
                                      • Custom script: if GetLocalPlayer() == ConvertedPlayer(udg_TempInt) then
                                      • Sound - Stop music Immediately
                                      • Custom script: call PlayMusic(udg_TempString)
                                      • Custom script: endif
                                      • Countdown Timer - Start MS_Timer[TempInt] as a One-shot timer that will expire in (Length of Comradeship01 <gen>) seconds
                                    • Else - Actions
                                • Else - Actions
            • Else - Actions


Thanks in advance!
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
I haven't checked all system yet, but first of all MS Register trigger will cause desync because you are creating/destroying a player group inside GetLocalPlayer block.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
if you do anything that requires network inside local block, you will run into desync sooner or later.

Things that are safe: Setting strings(you can desync too, but I have yet to see a case of async string tables desyncing), creating lightnings, creating text tags, setting various things on unit such as vertex color, scale, printing shit to user's screen(text).

Dont quote me on this, but I think if you set boolean in local block and then check it ouside of the local block, you get desync too

You can just create the sound, play it, set volume to 0 and do the locality check, and set the volume of the sound to 100 in the block.

It should also simplify this by quite a bit
 
strings shouldnt because they work differently(string table), and I know texttags wont. But I think even the "elementary" types will desync if you try to read from them. Maybe it depends on operation you use it with

It depends on the operation you use it with. If you read a value that is out of sync, it won't desync on the spot. For example:
JASS:
local boolean flag = false
if GetLocalPlayer() == Player(0) then
    set flag = true
endif
if flag then
    // this acts as a local block
    call PlayMusic("example.mp3")
endif

That would run just fine, and would be equivalent to just moving the PlayMusic within the local block. Since the value is out of sync, you have to keep that in mind and ensure that the functions within the if-block are async-safe.
 
Level 17
Joined
Dec 11, 2014
Messages
2,004
Thank you all!

EDIT:

Did this in the register trigger and it doesn't work now... It says "Track 1/2/3 missing.".

  • MS Register
    • Events
    • Conditions
    • Actions
      • Set MS_Filename[(Player number of (Triggering player))] = (Substring((Entered chat string), 17, (Length of (Entered chat string))))
      • Set TempString = MS_Filename[(Player number of (Triggering player))]
      • Set TempString = (TempString + (\\ + ATfaH - 1.mp3))
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Custom script: if GetSoundFileDuration(udg_TempString) > 0 then
      • Set MS_Has_1[(Player number of (Triggering player))] = True
      • Custom script: endif
      • Custom script: endif
      • -------- - --------
      • Set TempString = MS_Filename[(Player number of (Triggering player))]
      • Set TempString = (TempString + (\\ + ATfaH - 2.mp3))
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Custom script: if GetSoundFileDuration(udg_TempString) > 0 then
      • Set MS_Has_2[(Player number of (Triggering player))] = True
      • Custom script: endif
      • Custom script: endif
      • -------- - --------
      • Set TempString = MS_Filename[(Player number of (Triggering player))]
      • Set TempString = (TempString + (\\ + ATfaH - 3.mp3))
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Custom script: if GetSoundFileDuration(udg_TempString) > 0 then
      • Set MS_Has_3[(Player number of (Triggering player))] = True
      • Custom script: endif
      • Custom script: endif
      • -------- - --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MS_Has_1[(Player number of (Triggering player))] Equal to False
          • MS_Has_3[(Player number of (Triggering player))] Equal to False
          • MS_Has_2[(Player number of (Triggering player))] Equal to False
        • Then - Actions
          • Game - Display to Temp_PlayerGroup the text: |cFFFF0000Playing E...
          • Sound - Set music volume to 0.00%
          • Set MS_Filename[(Player number of (Triggering player))] = <Empty String>
        • Else - Actions
          • Sound - Set music volume to 100.00%
          • Set MS_MusicCounterEx[(Player number of (Triggering player))] = 0
          • Countdown Timer - Start MS_Timer[(Player number of (Triggering player))] as a One-shot timer that will expire in 1.00 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MS_Has_1[(Player number of (Triggering player))] Equal to True
        • Then - Actions
          • Set Temp_PlayerGroup = (Player group((Triggering player)))
          • Game - Display to Temp_PlayerGroup the text: Track 1 Detected.
          • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
        • Else - Actions
          • Set Temp_PlayerGroup = (Player group((Triggering player)))
          • Game - Display to Temp_PlayerGroup the text: Track 1 Missing.
          • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MS_Has_2[(Player number of (Triggering player))] Equal to True
        • Then - Actions
          • Set Temp_PlayerGroup = (Player group((Triggering player)))
          • Game - Display to Temp_PlayerGroup the text: Track 2 Detected.
          • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
        • Else - Actions
          • Set Temp_PlayerGroup = (Player group((Triggering player)))
          • Game - Display to Temp_PlayerGroup the text: Track 2 Missing.
          • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MS_Has_3[(Player number of (Triggering player))] Equal to True
        • Then - Actions
          • Set Temp_PlayerGroup = (Player group((Triggering player)))
          • Game - Display to Temp_PlayerGroup the text: Track 3 Detected.
          • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
        • Else - Actions
          • Set Temp_PlayerGroup = (Player group((Triggering player)))
          • Game - Display to Temp_PlayerGroup the text: Track 3 Missing.
          • Custom script: call DestroyForce(udg_Temp_PlayerGroup)

Any help appreciated :)
 
Last edited:
Oops. Arad I think you misunderstood--my post was actually just directed towards what edo said. I didn't mean for you to actually create a boolean variable--it'll still desync.

Go back to your last trigger. You have to do it without using player groups. Instead of displaying text to a force, you can use the function DisplayTextToPlayer:
native DisplayTextToPlayer takes player toPlayer, real x, real y, string message returns nothing

JASS:
call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "Track 1 Missing.")
^ That is just an example. It would display the message "Track 1 Missing" to the triggering player.

GetLocalPlayer is tricky in general. I recommend that you be very careful with it--desyncs can make or break a map (if a player desyncs, sometimes they just won't play the map again). So it is really important to get it all correctly implemented and tested!
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
showing text to player will not desync in local block, because its local event :D

Creating group will desync most likely instantly, because the game state gets out of sync.

You can just remove the group, and move all the operations you wanted to do with the group into the local block itself. Or you can just move the Player Group(Triggering Player) before the local block, so that it will be shared among people, and use it inside the local block(the problem here is there are some operations that may desync, maybe ForForce?[Enumerate players of player group])
 
Level 17
Joined
Dec 11, 2014
Messages
2,004
showing text to player will not desync in local block, because its local event :D

Creating group will desync most likely instantly, because the game state gets out of sync.

You can just remove the group, and move all the operations you wanted to do with the group into the local block itself. Or you can just move the Player Group(Triggering Player) before the local block, so that it will be shared among people, and use it inside the local block(the problem here is there are some operations that may desync, maybe ForForce?[Enumerate players of player group])

What??!?
 
Don't use GetLocalPlayer() so widespread. Only localize the string and StartSound command and you'll be fine.

Remember to not concatenate strings inside a local block. Due to how the string table works, this might desync players at a random point in your game, which makes it a very hard to track bug.

Always initialize every string globally before using it locally.

Here's how to play a local sound for a local player in a nutshell:

JASS:
globals
     sound TRACK_01 = null
     string FILE_01 = "whateverpath\\whateverfile.mp3"
endglobals

function whateverthefuck takes nothing returns nothing

local string play = ""
if GetSoundFileDuration(s) > 0 then
     set play = FILE_01
endif
if TRACK_01 == null then
     set TRACK_01 = CreateSound(play, false, false, "")
endif
if GetLocalPlayer() == GetTriggerPlayer() then
     call StartSound(TRACK_01)
endif

endfunction

Make sure your paths are global variables. That avoids a lot of trouble with the string table.
 
Last edited:
Status
Not open for further replies.
Top