What exactly desyncs?

Korolen

New User (Why do I keep getting those red bars?)
Reaction score
69
I finally got map map to "beta stage", and have started to host it on Battle.net... and have experienced many hurtles of the players getting disconnected from desyncs.

I need some help on a few aspects as to what is causing the desyncs and what I can do to fix them.


At first, everyone got disconnected the instant the game started... I fixed this one by changing
Code:
Custom script:   if GetLocalPlayer() != GetOwningPlayer(GetEnumUnit()) then
Unit - Hide (Picked unit)
Custom script:   endif
to
Code:
Custom script:   if GetLocalPlayer() != GetOwningPlayer(GetEnumUnit()) then
Animation - Change (Picked unit)'s vertex coloring to (100.00%, 100.00%, 100.00%) with 100.00% transparency
Animation - Change (Picked unit)'s size to (0.00%, 0.00%, 0.00%) of its original size
Custom script:   endif


Next, people got disconnected whenever this "floating error" script was run:
Code:
function create_floating_error takes player p, string text, location l returns texttag
    local texttag tag
    if GetLocalPlayer() == p then
        set tag = CreateTextTag()
        call SetTextTagPos(tag, GetLocationX(l), GetLocationY(l), 30)
        call SetTextTagTextBJ(tag, text, 8)
        call SetTextTagPermanent(tag, false)
        call SetTextTagFadepoint(tag, 0.5)
        call SetTextTagLifespan(tag, 1.3) 
    endif
    return tag
endfunction
I fixed it by initializing "tag" to null.

Now, for the unsolved "hurdle". I added a tutorial to the beginning of the map... however, when a player skips it, it disconnects them. I found that the Blizzard cinematic code set the gamespeed, so I copied the "local" code except fo r that from the BJ function into the end_cinematic function, but the players still get disconnected. I'm guessing that there is a problem with fade filters, but I'm not sure. Here is all the relevant code.

The tutorial trigger:
Code:
Tutorial
    Events
    Conditions
    Actions
        Custom script:   local string s
        Cinematic - Turn cinematic mode On for (All players)
        Cinematic - Fade out over 0.00 seconds using texture Black Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Set Playing_Cinematic[((Player number of (Picked player)) - 1)] = True
        Custom script:   call cinematic_message(7, "Welcome to Beast Bloodshed. This is a quick tutorial to introduce you to the game. If you have already played Beast Bloodshed and would like to load your code, press [\\[^ESC^\\]]|r at any time.")
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Environment - Set fog to style Linear, z-start 1000000.00, z-end 10000000.00, density 0.00 and color (100.00%, 100.00%, 100.00%)
        Player Group - Pick every player in Players and do (Camera - Apply Main Area <gen> for (Picked player) over 0.00 seconds)
        Cinematic - Fade in over 1.00 seconds using texture White Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
        Custom script:   call cinematic_message(8.5, "The goal of the Beast Bloodshed is to breed the prefect champion to conquer the other players in competitions.|n|nThis is the main area. Everyone's beasts that are not currently competing are located here.")
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Pan camera for (Picked player) to ((Picked player) start location) over 1.00 seconds
                Camera - Set (Picked player)'s camera Angle of attack to -35.00 over 1.00 seconds
                Camera - Set (Picked player)'s camera Rotation to (Angle from ((Picked player) start location) to (Center of Main Area <gen>)) over 1.00 seconds
                Camera - Set (Picked player)'s camera Distance to target to 1800.00 over 1.00 seconds
        Custom script:   call cinematic_message(6.5, "This is your main base. Purchase new beasts here. New beasts will not appear until the start of the next Main Phase, or directly after the competition.")
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Custom script:   set s = "These are the crafters and the Bet Collector. The Potion Brewer can concoct powerful potions that will help your beasts outside of battle, and the Armor Crafter can forge sturdy armor to protect your beasts in battle. "
        Custom script:   set s = s + "The Bet Collector will allow you to enter your beasts into the competition and to place bets on who will win."
        Custom script:   call cinematic_message(-1, s)
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Pan camera for (Picked player) to (Center of Shops <gen>) over 1.00 seconds
        Wait 1.00 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Rotate camera (360.00 - (Angle from ((Picked player) start location) to (Center of Shops <gen>))) degrees around (Center of Shops <gen>) for (Picked player) over 9.00 seconds
        Custom script:   call cinematic_message(-1, s)
        Wait 9.00 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Custom script:   set s = "Comptetitions such as racing, sumos, deathmatches, and endurance games will happen periodically."
        Custom script:   call cinematic_message(-1, s)
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Pan camera for (Picked player) to (Center of Long Race Start <gen>) over 1.50 seconds
                Camera - Set (Picked player)'s camera Rotation to 0.00 over 1.50 seconds
                Camera - Set (Picked player)'s camera Distance to target to 500.00 over 1.50 seconds
        Wait 1.50 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Pan camera for (Picked player) to (Center of Long Race Finish <gen>) over 1.00 seconds
        Wait 0.80 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Pan camera for (Picked player) to (Center of Figure Eight <gen>) over 1.80 seconds
                Camera - Set (Picked player)'s camera Distance to target to 3500.00 over 1.80 seconds
                Camera - Set (Picked player)'s camera Angle of attack to 304.00 over 1.80 seconds
        Wait 1.80 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Pan camera for (Picked player) to (Center of Arena <gen>) over 0.50 seconds
        Wait 0.50 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Rotate camera 90.00 degrees around (Center of Arena <gen>) for (Picked player) over 1.50 seconds
        Wait 1.50 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Pan camera for (Picked player) to (Center of Sumo <gen>) over 0.50 seconds
        Wait 0.50 seconds
        Custom script:   if udg_Playing_Cinematic[GetPlayerId(GetLocalPlayer())] == false then
        Skip remaining actions
        Custom script:   endif
        Player Group - Pick every player in Players and do (Actions)
            Loop - Actions
                Camera - Set (Picked player)'s camera Distance to target to 0.00 over 1.00 seconds
        Cinematic - Fade out over 0.80 seconds using texture White Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
        Wait 1.20 seconds
        Custom script:   call end_cinematic(GetLocalPlayer())
The "skip" code:
Code:
Skip Cinematic
    Events
        Player - Player 1 (Red) skips a cinematic sequence
        Player - Player 2 (Blue) skips a cinematic sequence
        Player - Player 3 (Teal) skips a cinematic sequence
        Player - Player 4 (Purple) skips a cinematic sequence
        Player - Player 5 (Yellow) skips a cinematic sequence
        Player - Player 6 (Orange) skips a cinematic sequence
        Player - Player 7 (Green) skips a cinematic sequence
        Player - Player 8 (Pink) skips a cinematic sequence
    Conditions
        Playing_Cinematic[((Player number of (Triggering player)) - 1)] Equal to True
    Actions
        Custom script:   call end_cinematic(GetTriggerPlayer())
And the "end_cinematic" function:
Code:
function end_cinematic takes player p returns nothing
    set udg_Playing_Cinematic[GetPlayerId(p)] = false
    if GetLocalPlayer() == p then
        call ResetTerrainFog()
        call ResetToGameCamera(0)
        call PanCameraToTimed(GetPlayerStartLocationX(p), GetPlayerStartLocationY(p), 0)
        call CinematicFadeBJ(bj_CINEFADETYPE_FADEIN, 0.40, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 0, 0, 0, 0)
        call ShowInterface(true, .4)
        call EnableUserControl(true)
        call EnableOcclusion(true)
        call VolumeGroupReset()
        call EndThematicMusic()
        call CameraResetSmoothingFactorBJ()
    endif
endfunction



Now I'm also wondering, if the fade filters are the problem, why Elil's local cinematic be so complex if you could do this... Only the latter looks just like the normal function but with the GetLocalPlayer()==target player comparison in the function instead of outside it. I don't get why the latter would work at all, and if it does, why would it work any better then moving the GetLocalPlayer() comparison outside the function? I'd really like to know exactly what is safe and what is not... I've done a bit of research and have found different opinions.

EDIT: I have also experienced random desyncing when playing my map on bnet; I'll post relevant code as I narrow down what is causing it.
 

Chocobo

White-Flower
Reaction score
409
For filter :

call ResetTerrainFog() : doesn't desync
call ResetToGameCamera() : doesn't desync
call PanCameraToTimed() : doesn't desync

call CinematicFadeBJ() : maybe desync
no idea if GetLocalPlayer() desyncs with strings and timers

call ShowInterface() : doesn't desync
call EnableUserControl() : doesn't desync
call EnableOcclusion() : doesn't desync
call VolumeGroupReset() : doesn't desync
call EndThematicMusic() : no idea of the theme desyncs
call CameraResetSmoothingFactorBJ() : doesn't desync

You should test CinematicFadeBJ() functions, strings and timers can be the problem (also it sets bj_ variables to an another value, so it may return differant values for other computers if it is set to a new value in globality)
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
To conclude, everything You create for a local player, tends to de-sync, almost always (Like you did with the texttag).

Hiding units, showing fade filters and playing sounds for a local player is safe, however.
 

Chocobo

White-Flower
Reaction score
409
To conclude, everything You create for a local player, tends to de-sync, almost always (Like you did with the texttag).

Hiding units, showing fade filters and playing sounds for a local player is safe, however.

For texttags : there is a function to hide texttags and compatible for multiplaying, no one seems to like to use it and create local texttags instead of hiding one for each player

For fade filters : desyncs if people uses the normal fade filter, the advanced one never desyncs.

For sound : no desync, but no idea for music (=! sound)
 

SFilip

Gone but not forgotten
Reaction score
634
Here's a 100% safe version of your texttag
Code:
function create_floating_error takes player p, string text, location l returns texttag
    local texttag tag = CreateTextTag()
    local string tttext = ""
    if GetLocalPlayer() == p then
        set tttext = text
    endif
    call SetTextTagPos(tag, GetLocationX(l), GetLocationY(l), 30)
    call SetTextTagTextBJ(tag, tttext, 8)
    call SetTextTagPermanent(tag, false)
    call SetTextTagFadepoint(tag, 0.5)
    call SetTextTagLifespan(tag, 1.3) 
    return tag
endfunction
So as you can see it creates the same text for every player, but makes the text "" unless that player is p.
In general any function that creates something for only one player can and will desync. Always find a way to hide it somehow instead in order to avoid this.
 

Korolen

New User (Why do I keep getting those red bars?)
Reaction score
69
Here's a 100% safe version of your texttag
Code:
function create_floating_error takes player p, string text, location l returns texttag
    local texttag tag = CreateTextTag()
    local string tttext = ""
    if GetLocalPlayer() == p then
        set tttext = text
    endif
    call SetTextTagPos(tag, GetLocationX(l), GetLocationY(l), 30)
    call SetTextTagTextBJ(tag, tttext, 8)
    call SetTextTagPermanent(tag, false)
    call SetTextTagFadepoint(tag, 0.5)
    call SetTextTagLifespan(tag, 1.3) 
    return tag
endfunction
So as you can see it creates the same text for every player, but makes the text "" unless that player is p.
In general any function that creates something for only one player can and will desync. Always find a way to hide it somehow instead in order to avoid this.
Well, setting the local tag variable to null first seemed to fix the problem. I don't think that the creation of the tag was what caused the desync, as tags are passive. I'm pretty sure that the problem was after I called that function, I stopped the unit, and that function crashed on one computer and not on another. Again, I'm not sure, but I think that the crash was caused by returning a uninitialized handle – why else would initializing it to null help?

For fade filters : desyncs if people uses the normal fade filter, the advanced one never desyncs.
Why?!?! If fadetype == bj_CINEFADETYPE_FADEOUT, the normal fade filter does exactly the same thing as the advanced one. Maybe it's when you pass bj_CINEFADETYPE_FADEIN, which starts a timer, that it desyncs?

Oh well, I'll try replacing my code with advanced fades instead of normal fades and see if it helps :p.


BTW, the latter half of the end_cinematic function was simply the local code in CinematicModeExBJ. Calling the function "normally" also ran "global code" which caused desyncs, I'm sure.
 

Chocobo

White-Flower
Reaction score
409
Why?!?! If fadetype == bj_CINEFADETYPE_FADEOUT, the normal fade filter does exactly the same thing as the advanced one. Maybe it's when you pass bj_CINEFADETYPE_FADEIN, which starts a timer, that it desyncs?

Oh well, I'll try replacing my code with advanced fades instead of normal fades and see if it helps :p.


BTW, the latter half of the end_cinematic function was simply the local code in CinematicModeExBJ. Calling the function "normally" also ran "global code" which caused desyncs, I'm sure.

CinematicModeExBJ already uses GetLocalPlayer() inside it's script, lol.


For filters :

Code:
function CinematicFilterGenericBJ takes real duration,blendmode bmode,string tex,real red0,real green0,real blue0,real trans0,real red1,real green1,real blue1,real trans1 returns nothing
    call AbortCinematicFadeBJ()
    call SetCineFilterTexture(tex)
    call SetCineFilterBlendMode(bmode)
    call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
    call SetCineFilterStartUV(0, 0, 1, 1)
    call SetCineFilterEndUV(0, 0, 1, 1)
    call SetCineFilterStartColor(PercentTo255(red0), PercentTo255(green0), PercentTo255(blue0), PercentTo255(100-trans0))
    call SetCineFilterEndColor(PercentTo255(red1), PercentTo255(green1), PercentTo255(blue1), PercentTo255(100-trans1))
    call SetCineFilterDuration(duration)
    call DisplayCineFilter(true)
endfunction

This desyncs. (I think it's the AbortCinematicFadeBJ, because it destroys a timer)


No idea for the advanced filter (I'm 100% sure it doesn't desync), because I don't remember it's func name.
 

Korolen

New User (Why do I keep getting those red bars?)
Reaction score
69
CinematicModeExBJ already uses GetLocalPlayer() inside it's script, lol.
It also has code that's run for every player, not just the local player. I don't want that code going for every player when just one player skips the cinematic, but that code can't be run localy, so I just copied the code from CinematicModeExBJ that was IN the local block into end_cinematic.
For filters :

Code:
function CinematicFilterGenericBJ takes real duration,blendmode bmode,string tex,real red0,real green0,real blue0,real trans0,real red1,real green1,real blue1,real trans1 returns nothing
    call AbortCinematicFadeBJ()
    call SetCineFilterTexture(tex)
    call SetCineFilterBlendMode(bmode)
    call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
    call SetCineFilterStartUV(0, 0, 1, 1)
    call SetCineFilterEndUV(0, 0, 1, 1)
    call SetCineFilterStartColor(PercentTo255(red0), PercentTo255(green0), PercentTo255(blue0), PercentTo255(100-trans0))
    call SetCineFilterEndColor(PercentTo255(red1), PercentTo255(green1), PercentTo255(blue1), PercentTo255(100-trans1))
    call SetCineFilterDuration(duration)
    call DisplayCineFilter(true)
endfunction

This desyncs. (I think it's the AbortCinematicFadeBJ, because it destroys a timer)


No idea for the advanced filter (I'm 100% sure it doesn't desync), because I don't remember it's func name.
Advanced filter in GUI turns into CinematicFilterGenericBJ
 

Korolen

New User (Why do I keep getting those red bars?)
Reaction score
69
bump

I tried disabling everything in the Tutorial trigger, and it seems to desync the instant the trigger does something – even just a wait – on one computer and not on the other. I'm going to try to wrapping all the actions in the Tutorial trigger except for waits instead of just killing the trigger, so it's still running just not doing anything.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top