• 🏆 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!

Desync questions

Status
Not open for further replies.
Level 12
Joined
Jan 2, 2016
Messages
973
Is it fatal if I have some functions that may cause desyncing?
In DotA (f.ex) - when your hero revives, your camera is paned to the fountain. In theory that should cause a desync between the players, but it doesn't seem to do that in DotA..
I really want to make a 'local' camera movement, but I don't dare to due to the possible desyncing.
And well I have ONE trigger, that's using a trigger sleep action.
JASS:
function Trig_Call_Storm takes nothing returns nothing
    local unit c = GetTriggerUnit()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local weathereffect rain
    local weathereffect wind
    local timer t = GetFreeTimer()
    local integer id = GetHandleId(t)
    local unit d = CreateUnit(GetOwningPlayer(c),'h00C',x,y,0.00)
    local integer lvl = GetUnitAbilityLevel(c,'A019')
    local real spell_radius = 325.00+(25.00*I2R(lvl))
    if udg_Temp_Region == null then
        set udg_Temp_Region = Rect(x-spell_radius, y-spell_radius, x+spell_radius, y+spell_radius)
    else
        call SetRect(udg_Temp_Region,x-spell_radius, y-spell_radius, x+spell_radius, y+spell_radius)
    endif
    call UnitAddAbility(d, 'A01A')
    set rain = AddWeatherEffect( udg_Temp_Region , 'RAhr' )
    set wind = AddWeatherEffect( udg_Temp_Region , 'WNcw' )
    call EnableWeatherEffect( rain , true )
    call EnableWeatherEffect( wind , true )
    call SaveInteger(udg_Table, id, 'maxh' , 6+lvl)
    call SaveInteger(udg_Table, id, 'used' , 1)
    call SaveReal(udg_Table, id, 'tarx' , x)
    call SaveReal(udg_Table, id, 'tary' , y)
    call SaveUnitHandle(udg_Table, id, 'dumy' , d)
    call SaveReal(udg_Table, id, 'rang' , spell_radius)
    call SaveInteger(udg_Table, id, 'levl' , lvl)
    call TimerStart( t, 1.10 - (lvl*0.1), true, function StormEffect)
    set t = null

/////////////////////////////////////////////////////////////////
    call TriggerSleepAction((1.10 - (lvl*0.10))*(7+lvl))
/////////////////////////////////////////////////////////////////

    call UnitApplyTimedLife(d, 'BTLF', 0.01)
    call EnableWeatherEffect( rain , false )
    call EnableWeatherEffect( wind , false )
    call RemoveWeatherEffect( rain )
    call RemoveWeatherEffect( wind )
    set c = null
    set d = null
    set wind = null
    set rain = null
endfunction
Having one trigger with trigger sleep action isn't so bad, is it?
(I kind a couldn't avoid this, without using global variables + indexing for the weather effect, but then I could've just done the whole thing by indexing and global variables, and I didn't want that)

And what is desyncing (exactly) doing?
Does it cause lag for a brief period, or is it building up with time?
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
TriggerSleepAction(), as far as I know, does not cause any desyncs. As a matter of fact, none of your code shows anything that would be prone to a desync. The GetLocalPlayer() native and terrain deformations are the only desyncs I know that can occur (aside from third party tools).

PurgeandFire made a tutorial on GetLocalPlayer() that also briefly explains what desyncs are:
Desyncs occur when data becomes desynchronized between players in a way that affects gameplay. For example, if a unit has position A for player 1 and position B for player 2, Wc3 will realize the game is out of sync. As a result, Wc3 will simply disconnect one of the players.


Dr Super Good also explains something similar in this post.
 
Level 12
Joined
Jan 2, 2016
Messages
973
Okay, that was helpful, and explained a lot.
So there is no risk for desyncing, if I am not using any local blocks?

And hmm, did I understand it wrong, or each variable has its own value for each player (tho it's the same value, if you don't set that variable in a local block), and each trigger/function runs N times (where N is the number of players)?

EDIT:
If that's the case, would it be wise to set some "dice" variable locally? Explaining:
I have a trigger that when a unit spawns - it has a 25% chance to spawn as a "superior" version of itself.
So if 100 units of this type are spawned - about 25 of them will be "superior".
Let's say that every 4-th unit hits that chance (so it'd be easier to explaing what I mean):
Player 1 created 3 units of this type, and they are normal ones, but Player 2 then creates 1 (which is the 4-th in total), and it spawns as the superior version.
Then Player 1 creates 3 more, which spawn normally, and Player 2 spawns 1 more superior.
This way Player 1 will have 75 normal ones, and player 2 will have 25 superior ones.
But if I were "throwing the dice" locally - player 1 would have 18-19 of the superior type, while player 2 will have 6-7.
Note that I'm only setting the chances locally, and then the unit is created the normal way... tho I'm not sure if this will work: if I have as condition "i <= 25" and for player 1 "i = 24" and for player 2 "i = 54", then the condition will be true for player 1, but false for player 2. This will desync, wouldn't it?

Or that's not how it works at all?
 
Level 12
Joined
May 22, 2015
Messages
1,051
Okay, that was helpful, and explained a lot.
So there is no risk for desyncing, if I am not using any local blocks?

And hmm, did I understand it wrong, or each variable has its own value for each player (tho it's the same value, if you don't set that variable in a local block), and each trigger/function runs N times (where N is the number of players)?

EDIT:
If that's the case, would it be wise to set some "dice" variable locally? Explaining:
I have a trigger that when a unit spawns - it has a 25% chance to spawn as a "superior" version of itself.
So if 100 units of this type are spawned - about 25 of them will be "superior".
Let's say that every 4-th unit hits that chance (so it'd be easier to explaing what I mean):
Player 1 created 3 units of this type, and they are normal ones, but Player 2 then creates 1 (which is the 4-th in total), and it spawns as the superior version.
Then Player 1 creates 3 more, which spawn normally, and Player 2 spawns 1 more superior.
This way Player 1 will have 75 normal ones, and player 2 will have 25 superior ones.
But if I were "throwing the dice" locally - player 1 would have 18-19 of the superior type, while player 2 will have 6-7.
Note that I'm only setting the chances locally, and then the unit is created the normal way... tho I'm not sure if this will work: if I have as condition "i <= 25" and for player 1 "i = 24" and for player 2 "i = 54", then the condition will be true for player 1, but false for player 2. This will desync, wouldn't it?

Or that's not how it works at all?

If it is completely random chance, then you can't stop this from happening (and it is unlikely to happen). If you have logic to increase the odds as you get bad rolls, then you could just have some kind array with the numbers you're using in there. The indexes for that array should be GetPlayerId(udg_myPlayer).

As for waits, it doesn't cause desyncs, it forces syncs - which can cause lag if you use a ton of them. One trigger with a wait is definitely not a problem. The problem is when you are spamming them.

They also get inaccurate when there is lag. I used to have my triggers coded really poorly (damn 17-year-old me...) where the timers to indicate when a boss was coming were not actually used to spawn the boss - they were just for display. I had some ugly waits to spawn them and it was just set up to match the boss spawning timer. If someone lagged really badly, the timer would sometimes be way off. I think we managed to have the timer over a minute off.
 
Status
Not open for further replies.
Top