• 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.

Can this desync?

Status
Not open for further replies.
Level 14
Joined
Oct 18, 2013
Messages
724
JASS:
function PlayMusicExt takes string Normal, string External returns nothing
local integer i=0
local string s=""
       loop
        exitwhen i>11 
                if GetLocalPlayer()== Player(i) then
           if GetSoundFileDuration(External) > 0 then
          set s=External
          else
          set s=Normal
          endif
          endif 
        set i=i+1
      endloop
      call StopMusic(false)
      call PlayMusic(s)
      
endfunction
 
Last edited:
Level 14
Joined
Jul 1, 2008
Messages
1,314
I would set the StopMusic/PlayMusic calls into the GetLocalPlayer() block to be sure, it does not desync. I dont know what happens, if you do this to a computer player though.

edit: sry did not see waterknights response.
 
Level 26
Joined
Aug 18, 2009
Messages
4,099
I would set the StopMusic/PlayMusic calls into the GetLocalPlayer() block to be sure, it does not desync. I dont know what happens, if you do this to a computer player though.

How would putting it into the async block diminish the chance for desync? You cannot apply it to a computer player. For explanation:

All the human players (clients) join the same game, which is of the same map. They all got the same map script and execute it. Since they follow the same instructions and are determined, this keeps the game in sync. GetLocalPlayer however defies this by introducing dependence on local information. For the client that hosts player 0 it returns player 0, for the one that hosts player 1 it returns player 1 etc. The computer players are no own game instances, they do not execute any script or anything on their own. They are just part of the environment every client realizes locally but normally in an equal fashion.

The above scenario could basically semantically be expressed as:

The script player 0 got to execute:

JASS:
function PlayMusicExt takes string Normal, string External returns nothing
local integer i=0
local string s=""
       loop
        exitwhen i>11
                if Player(0)== Player(i) then
           if GetSoundFileDuration(External) > 0 then
          set s=External
          else
          set s=Normal
          endif
          endif
        set i=i+1
      endloop
      call StopMusic(false)
      call PlayMusic(s)
     
endfunction

The script player 1 got to execute:

JASS:
function PlayMusicExt takes string Normal, string External returns nothing
local integer i=0
local string s=""
       loop
        exitwhen i>11
                if Player(1)== Player(i) then
           if GetSoundFileDuration(External) > 0 then
          set s=External
          else
          set s=Normal
          endif
          endif
        set i=i+1
      endloop
      call StopMusic(false)
      call PlayMusic(s)
     
endfunction

Here the GetLocalPlayer-block is unnecessary, though. The loop over all clients neutralizes the local block since every client got their exact match. It can be simply rewritten as:

JASS:
function PlayMusicExt takes string Normal, string External returns nothing
    local string s = Normal

    if (GetSoundFileDuration(External) > 0) then
        set s = External
    endif

    call StopMusic(false)
    call PlayMusic(s) 
endfunction
 
Last edited:
Level 14
Joined
Oct 18, 2013
Messages
724
I just made it so that I can feed a sound file that's in the map, and a sound file that the player will only have if they installed my soundpack.

So, another desync question;

call PlaySound(udg_Sound)

If only players with the soundpack have the sound, can this desync?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
If only players with the soundpack have the sound, can this desync?
It should not, as sounds are pretty much asynchronous as is.

One just has to be careful with sound handles and path strings as both those trigger objects can cause a desync. If the sound is the same between players, or even exists, should not matter as long as a sound object exists for all players.
 
There is no much you can do wrong in regards to using external sounds, as long as you don't use the "KillSoundWhenDone" native.

I highly recommend initializing all strings globally. Never initialize a new string inside a local block. For some reason, this can cause desyncs eventually. And the annoying part about this is that this string-based desync almost never happens instantly, but after a longer game session, which makes it hard to find the issue once people start to report desyncs.

As a rule of thumb: Always define filepaths as constant global variables, then just use one or the other in a local block.
 
Level 19
Joined
Dec 12, 2010
Messages
2,074
There is no much you can do wrong in regards to using external sounds, as long as you don't use the "KillSoundWhenDone" native.

I highly recommend initializing all strings globally. Never initialize a new string inside a local block. For some reason, this can cause desyncs eventually. And the annoying part about this is that this string-based desync almost never happens instantly, but after a longer game session, which makes it hard to find the issue once people start to report desyncs.

As a rule of thumb: Always define filepaths as constant global variables, then just use one or the other in a local block.

I do rely on async strings both on dota & lod. so far (3 years) no desyncs whatsoever. Strings aren't agents, and only reason they are cached in some way is to improve WC3' perfomance. C doesn't really like to work with strings, so devs opted it via caching. Any given player could have totally different set of strings given. Just think about translations, customkeys, etc. Strings cannot cause desync whatsoever, unless proved wrong.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
I do rely on async strings both on dota & lod. so far (3 years) no desyncs whatsoever. Strings aren't agents, and only reason they are cached in some way is to improve WC3' perfomance. C doesn't really like to work with strings, so devs opted it via caching. Any given player could have totally different set of strings given. Just think about translations, customkeys, etc. Strings cannot cause desync whatsoever, unless proved wrong.
And yet dozens of OOS issues in the past have been caused by local strings...

WC3 caches strings for some unknown, but likely lazy, reason. Sure it allows fast string comparison but it makes string creation painfully slow. Additionally due to no reference counter system it is impossible for strings to be recycled so as the hashtables fill up the string creation performance falls even further.

This is why in StarCraft II strings are unique objects which are automatically garbage collected. This is also how Java programming language does it. StarCraft II also uses text for localized content so that strings are always in sync between clients.

The issue seems to be with unique string creation. As long as all clients have the same strings cached in the same order there does not seem to be a problem. In game localized text is likely separate from the string system.
 
Level 14
Joined
Oct 18, 2013
Messages
724
Any update on this? As a preventative measure, I'll probably just set the filepaths on init anyways, just curious as to whether this can desync or not.
 
Status
Not open for further replies.
Top