random desync issue possibly related to GetLocationZ

Level 12
Joined
Mar 21, 2008
Messages
375
i'm working on a map that worked fine prior to reforged, but ever since reforged released it's had major issues with random desyncs. as in, i can play through a game without issues in one instance, and then in another game i could get a desync 3 mins in. there is seemingly no obvious singular thing that is causing it so i could never pinpoint the cause at all, and i'm kinda at the end of my rope here

the map uses GetLocationZ a lot which might be the culprit, but this map doesn't use terrain deformations and walkable doodads which are apparently a source of desyncs if you're using GetLocationZ. the map also forces SD mode so no inconsistencies between SD/HD i believe? all i can really assume is that GetLocationZ is just fundamentally ass, but sadly this map relies heavily on its usage so i can't just remove it. and to reiterate this map worked pretty well before reforged

ok basically i have multiple questions:
1. can GetLocationZ cause random desyncs? (barring the things mentioned earlier like terrain deformations etc.)
2. are there any GetLocationZ alternatives that don't desync? i found this but i can't use it since it's lua
3. also can someone take a quick look at my map to find anything else that might cause desyncs? i hate to ask this since this is basically "do my work for me lol" but i have no recourse woop

map attached below

i might just be the embodiment of skill issue and the desyncs might be caused by something else entirely though
 

Attachments

  • Battle Project v0.11.4 Fix1.w3x
    4 MB · Views: 3
Level 45
Joined
Feb 27, 2007
Messages
5,578
GetLocationZ does not cause a desync just by being called. The issue is when using the Z-height for something in gameplay if the value returned to all players was not synced. You have to have done something with the asynchronous value to actually desync a player.
 
Level 12
Joined
Mar 21, 2008
Messages
375
GetLocationZ does not cause a desync just by being called. The issue is when using the Z-height for something in gameplay if the value returned to all players was not synced. You have to have done something with the asynchronous value to actually desync a player.
okey good to know

also as a slightly less vague lead, i played a game where one player crashed as soon as i killed him. these are the two triggers that would run on player death. if theres anything that could cause a desync in here let me know

  • dm kill
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Dying unit) is A Hero) Equal to True
    • Actions
      • Custom script: local integer c = GetConvertedPlayerId(GetOwningPlayer(GetKillingUnit()))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Killing unit) Equal to No unit
              • (Owner of (Killing unit)) Equal to (Owner of (Dying unit))
              • (Owner of (Killing unit)) Equal to Neutral Hostile
              • (Owner of (Killing unit)) Equal to Neutral Passive
        • Then - Actions
          • Set VariableSet dm_kills[(Player number of (Owner of (Dying unit)))] = (dm_kills[(Player number of (Owner of (Dying unit)))] - 1)
          • Set VariableSet tempInteger[0] = 0
          • For each (Integer A) from 1 to 24, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Player((Integer A))) controller) Equal to User
                  • ((Player((Integer A))) slot status) Equal to Is playing
                  • (Player((Integer A))) Not equal to Neutral Passive
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • dm_kills[(Player number of (Owner of (Dying unit)))] Equal to dm_kills[(Integer A)]
                    • Then - Actions
                      • Set VariableSet tempInteger[0] = (tempInteger[0] + 1)
                    • Else - Actions
                      • Custom script: set bj_forLoopAIndex = 24
                • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • tempInteger[0] Equal to players
            • Then - Actions
              • Set VariableSet dm_highest_kills = dm_kills[(Player number of (Owner of (Dying unit)))]
            • Else - Actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Killing unit) Not equal to No unit
          • (Owner of (Killing unit)) Not equal to Neutral Passive
          • (Owner of (Killing unit)) Not equal to Neutral Hostile
        • Then - Actions
          • Set VariableSet dm_kills[(Player number of (Owner of (Killing unit)))] = (dm_kills[(Player number of (Owner of (Killing unit)))] + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • dm_kills[(Player number of (Owner of (Killing unit)))] Greater than dm_highest_kills
            • Then - Actions
              • Set VariableSet dm_highest_kills = (dm_highest_kills + 1)
            • Else - Actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • dm_kills[(Player number of (Owner of (Killing unit)))] Greater than or equal to dm_highest_kills
        • Then - Actions
          • Set VariableSet tempPlayerGroup[0] = (Player group(Player 1 (Red)))
          • Player Group - Remove all players from tempPlayerGroup[0].
          • For each (Integer A) from 1 to 24, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • dm_kills[(Integer A)] Equal to dm_highest_kills
                  • ((Player((Integer A))) controller) Equal to User
                  • ((Player((Integer A))) slot status) Equal to Is playing
                  • (Player((Integer A))) Not equal to Neutral Passive
                • Then - Actions
                  • Player Group - Add (Player((Integer A))) to tempPlayerGroup[0]
                • Else - Actions
          • Game - Display to (All players) the text: (String((Number of players in tempPlayerGroup[0])))
          • Game - Display to (All players) the text: (String(dm_highest_kills))
          • Game - Display to (All players) the text: (String(dm_kills[(Player number of (Owner of (Dying unit)))]))
          • Set VariableSet tempInteger[0] = 0
          • For each (Integer A) from 1 to 24, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • dm_kills[(Integer A)] Equal to dm_highest_kills
                • Then - Actions
                  • Set VariableSet tempInteger[0] = (tempInteger[0] + 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • tempInteger[0] Equal to (Number of players in tempPlayerGroup[0])
                    • Then - Actions
                      • Set VariableSet tempString[0] = (tempString[0] + (playercolor[(Integer A)] + ((Name of (Player((Integer A)))) + |r )))
                      • Custom script: call BlzFrameSetVisible(ScoreText, true)
                      • Custom script: call BlzFrameSetText(BlzGetFrameByName("TestStringValue", 0), "Current Leaders|n" + udg_tempString[0] + "(" + I2S(udg_dm_highest_kills) + ")" )
                      • Custom script: set bj_forLoopAIndex = 24
                      • Set VariableSet tempString[0] = <Empty String>
                    • Else - Actions
                      • Set VariableSet tempString[0] = (tempString[0] + (playercolor[(Integer A)] + ((Name of (Player((Integer A)))) + |r, )))
                • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of players in tempPlayerGroup[0]) Greater than or equal to 2
            • Then - Actions
              • For each (Integer A) from 1 to 24, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • dm_kills[(Integer A)] Equal to dm_highest_kills
                    • Then - Actions
                      • Set VariableSet tempInteger[0] = (tempInteger[0] + 1)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • tempInteger[0] Equal to (Number of players in tempPlayerGroup[0])
                        • Then - Actions
                          • Set VariableSet tempString[0] = (tempString[0] + (playercolor[(Integer A)] + ((Name of (Player((Integer A)))) + |r )))
                          • Custom script: call BlzFrameSetVisible(ScoreText, true)
                          • Custom script: call BlzFrameSetText(BlzGetFrameByName("TestStringValue", 0), "Current Leaders|n" + udg_tempString[0] + "(" + I2S(udg_dm_highest_kills) + ")" )
                          • Custom script: set bj_forLoopAIndex = 24
                          • Set VariableSet tempString[0] = <Empty String>
                        • Else - Actions
                          • Set VariableSet tempString[0] = (tempString[0] + (playercolor[(Integer A)] + ((Name of (Player((Integer A)))) + |r, )))
                    • Else - Actions
            • Else - Actions
              • Custom script: call BlzFrameSetText(BlzGetFrameByName("TestStringValue", 0), "Current Leader|n" + udg_playercolor[c] + GetPlayerName(GetOwningPlayer(GetKillingUnit())) + "|r (" + I2S(udg_dm_highest_kills) + ")" )
          • Custom script: call DestroyForce(udg_tempPlayerGroup[0])
          • Custom script: set udg_tempPlayerGroup[0] = null
        • Else - Actions
  • death
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Dying unit) is A Hero) Equal to True
    • Actions
      • Custom script: call ExecuteFunc("respawn")
      • Custom script: endfunction
      • Custom script:
      • Custom script: function RespawnInvulEnd takes nothing returns nothing
      • Custom script: set udg_tempInteger[0] = GetTimerData(GetExpiredTimer())
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • round_over Equal to False
        • Then - Actions
          • Unit - Make UDexUnits[tempInteger[0]] Vulnerable
        • Else - Actions
      • Unit - Remove Attachment: Divine Shield from UDexUnits[tempInteger[0]]
      • Custom script: call ReleaseTimer(GetExpiredTimer())
      • Custom script: endfunction
      • Custom script:
      • Custom script: function respawn takes nothing returns nothing
      • Custom script: local timer t=NewTimer()
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Killing unit) Not equal to No unit
          • (Killing unit) Not equal to (Dying unit)
          • (Killing unit) Not equal to [Lava damage] 0033 <gen>
          • (Killing unit) Not equal to [Barrier] 0036 <gen>
        • Then - Actions
          • Game - Display to (All players) the text: (playercolor[(Player number of (Owner of (Killing unit)))] + ((Name of (Owner of (Killing unit))) + (|r killed + (playercolor[(Player number of (Owner of (Dying unit)))] + (Name of (Owner of (Dying unit)))))))
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Killing unit) Equal to No unit
                  • (Killing unit) Equal to (Dying unit)
            • Then - Actions
              • Game - Display to (All players) the text: (playercolor[(Player number of (Owner of (Dying unit)))] + ((Name of (Owner of (Dying unit))) + |r committed suicide))
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Killing unit) Equal to [Lava damage] 0033 <gen>
                  • (Killing unit) Equal to [Barrier] 0036 <gen>
            • Then - Actions
              • Game - Display to (All players) the text: (|cffFFFFFF + ((Name of (Killing unit)) + (|r killed + (playercolor[(Player number of (Owner of (Dying unit)))] + (Name of (Owner of (Dying unit)))))))
            • Else - Actions
      • Custom script: call AddUnitAnimationProperties(GetTriggerUnit(),"swim",false)
      • Animation - Change (Dying unit) flying height to 0.00 at 1000000000.00
      • Animation - Change (Dying unit)'s animation speed to 100.00% of its original speed
      • Unit - Unpause (Dying unit)
      • Unit - Remove Attachment: Enduring Spirit from (Dying unit)
      • Unit - Remove Status: Deflection from (Dying unit)
      • Unit - Remove Status: Mind's Eye from (Dying unit)
      • Unit - Remove Status: Superarmor from (Dying unit)
      • Unit - Remove Status: Airborne from (Dying unit)
      • Unit - Remove Status: Parry from (Dying unit)
      • Unit - Remove Status: Spark from (Dying unit)
      • Unit - Remove Status: Blade Catapult from (Dying unit)
      • Unit - Remove Status: Drain Stance (Scythe) from (Dying unit)
      • Unit - Remove Status: Combo Meter Full from (Dying unit)
      • Unit - Remove Status: Buffered Roll from (Dying unit)
      • Unit - Remove Status: Buffered Wakeup Attack from (Dying unit)
      • Unit - Remove Status: Hitstun from (Dying unit)
      • Unit - Remove Status: Lion's Maw from (Dying unit)
      • Unit - Remove Status: Lion's Maw Prevention from (Dying unit)
      • Unit - Remove Status: Flash Step Stance from (Dying unit)
      • Unit - Remove Status: Reversal from (Dying unit)
      • Unit - Remove Attachment: Parry Damage Bonus from (Dying unit)
      • Unit - Remove Attachment: Parry Damage Bonus (Wind's Favor) from (Dying unit)
      • Unit - Remove Attachment: Channeling Aura from (Dying unit)
      • Unit - Remove Attachment: Channeling Aura (Green) from (Dying unit)
      • Unit - Remove Attachment: Volatile Flame Lv.1 from (Dying unit)
      • Unit - Remove Attachment: Volatile Flame Lv.2 from (Dying unit)
      • Unit - Remove Attachment: Volatile Flame Lv.3 from (Dying unit)
      • Unit - Remove Attachment: Volatile Flame Lv.4 from (Dying unit)
      • Unit - Remove Attachment: White Buff (Boss) from (Dying unit)
      • Unit - Remove Attachment: Magic Shield (Red) from (Dying unit)
      • Unit - Remove Attachment: Magic Shield (Yellow) from (Dying unit)
      • Unit - Remove Attachment: Firebomb from (Dying unit)
      • Unit - Remove Mana Degeneration from (Dying unit)
      • Unit - Hide bufferUnit[(Player number of (Owner of (Dying unit)))]
      • Set VariableSet atkComboMeter[(Custom value of (Dying unit))] = 0.00
      • Set VariableSet atkVFChargeLevel[(Custom value of (Dying unit))] = 0
      • Set VariableSet atkVFCharge[(Custom value of (Dying unit))] = 0.00
      • Wait 5.00 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Owner of (Dying unit)) slot status) Equal to Has left the game
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (game deselect <gen> is on) Equal to True
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • game_one_life Equal to True
        • Then - Actions
          • Set VariableSet tempPlayerGroup[0] = (Player group((Owner of (Dying unit))))
          • Game - Display to tempPlayerGroup[0] the text: There is no respawn...
          • Custom script: call DestroyForce(udg_tempPlayerGroup[0])
          • Skip remaining actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • game_ffa Equal to False
        • Then - Actions
          • Set VariableSet tempLoc[0] = (Random point in game_spawn[team[(Player number of (Owner of (Dying unit)))]])
        • Else - Actions
          • Set VariableSet tempLoc[0] = (Random point in game_spawn[(Random integer number between 1 and 24)])
      • Camera - Pan camera for (Owner of (Triggering unit)) to tempLoc[0] over 0.00 seconds
      • Hero - Instantly revive (Dying unit) at tempLoc[0], Hide revival graphics
      • Unit - Make (Dying unit) Invulnerable
      • Unit - Add Attachment: Divine Shield to (Dying unit)
      • Custom script: call SetTimerData(t, GetUnitUserData(GetDyingUnit()))
      • Custom script: call TimerStart(t, 5, false, function RespawnInvulEnd)
      • Selection - Select (Dying unit) for (Owner of (Dying unit))
      • Custom script: call RemoveLocation(udg_tempLoc[0])
      • Custom script: set udg_tempLoc[0] = null
      • Set VariableSet tempu = (Dying unit)
      • Trigger - Run stamina regen initialize <gen> (checking conditions)
      • Trigger - Run tilt initialize <gen> (checking conditions)
 
also as a slightly less vague lead, i played a game where one player crashed as soon as i killed him

Hmm... crashes and desyncs typically happen for different reasons. Did the player's whole game crash or was it just a disconnection?

I think the first course of action is to determine whether your code related to GetLocationZ is causing the issue or not. There have been some instances where people reported issues (particularly since reforged):
While they do mention walkable-destructables, I still figure there might be lurking issues with the fact that GetLocationZ's values aren't guaranteed to be synced across clients. And so if you do some conditional logic off that (as Pyrogasm mentioned), you can easily run into a desync. A common example is with missile systems--as they often do a bunch of Z checks to see if they collided with something or not--and then they trigger some game logic (e.g. doing damage), which can then lead to desyncs.

So I recommend doing the following:
  1. Make a copy of your map. Open up that map in an MPQ editor and right-click the war3map.j and select "Edit" to open it in a text editor.
  2. Search for "endglobals", and right below it, add this function:
    JASS:
    function DummyGetLocZ takes location l returns real
        return 0.0
    endfunction
  3. Do a find-and-replace in your text editor, replacing "GetLocationZ" with "DummyGetLocZ". Save.
  4. Go back to the MPQ editor, and it should prompt you to update the file in the MPQ with your changes. Select "yes".
  5. Open up the war3map.j again and just confirm that if you search for "GetLocationZ" you don't get any results. Don't open the
  6. Host the map on battle.net and try to see if you're no longer disconnecting when playing. Most jumps/projectiles/spells will probably be broken (because now they'll treat the Z like it is 0 everywhere), but hopefully this will at least let you determine if this was the main source of the desyncs.
I've gone through those steps and attached the map below in case you want to host it and run some tests on it. Just be careful--if you save the map in the editor, it'll switch the code back to using GetLocationZ(), so I recommend that you don't open it up in the editor.

If you're no longer having desyncs, awesome! But if you still get a desync, then perhaps it isn't related to GetLocationZ() after all. Instead, you'll have to look towards any areas where the code uses GetLocalPlayer() to perform specific actions for a given player. In your map, it seems like the variable "localplayer" is assigned to the local player and then used in around 36 places. I have a tutorial in my signature that explains what to look for, but perhaps you should first rule out GetLocationZ() and then we can see where to go from there?
 

Attachments

  • Battle Project v0.11.4 DebugZ.w3x
    4.6 MB · Views: 1
Level 12
Joined
Mar 21, 2008
Messages
375
Hmm... crashes and desyncs typically happen for different reasons. Did the player's whole game crash or was it just a disconnection?

I think the first course of action is to determine whether your code related to GetLocationZ is causing the issue or not. There have been some instances where people reported issues (particularly since reforged):
While they do mention walkable-destructables, I still figure there might be lurking issues with the fact that GetLocationZ's values aren't guaranteed to be synced across clients. And so if you do some conditional logic off that (as Pyrogasm mentioned), you can easily run into a desync. A common example is with missile systems--as they often do a bunch of Z checks to see if they collided with something or not--and then they trigger some game logic (e.g. doing damage), which can then lead to desyncs.

So I recommend doing the following:
  1. Make a copy of your map. Open up that map in an MPQ editor and right-click the war3map.j and select "Edit" to open it in a text editor.
  2. Search for "endglobals", and right below it, add this function:
    JASS:
    function DummyGetLocZ takes location l returns real
        return 0.0
    endfunction
  3. Do a find-and-replace in your text editor, replacing "GetLocationZ" with "DummyGetLocZ". Save.
  4. Go back to the MPQ editor, and it should prompt you to update the file in the MPQ with your changes. Select "yes".
  5. Open up the war3map.j again and just confirm that if you search for "GetLocationZ" you don't get any results. Don't open the
  6. Host the map on battle.net and try to see if you're no longer disconnecting when playing. Most jumps/projectiles/spells will probably be broken (because now they'll treat the Z like it is 0 everywhere), but hopefully this will at least let you determine if this was the main source of the desyncs.
I've gone through those steps and attached the map below in case you want to host it and run some tests on it. Just be careful--if you save the map in the editor, it'll switch the code back to using GetLocationZ(), so I recommend that you don't open it up in the editor.

If you're no longer having desyncs, awesome! But if you still get a desync, then perhaps it isn't related to GetLocationZ() after all. Instead, you'll have to look towards any areas where the code uses GetLocalPlayer() to perform specific actions for a given player. In your map, it seems like the variable "localplayer" is assigned to the local player and then used in around 36 places. I have a tutorial in my signature that explains what to look for, but perhaps you should first rule out GetLocationZ() and then we can see where to go from there?
d00d thanks for the detailed reply. i just tested your version with someone and it still crashed lol. guess it's not GetLocationZ then

also yeah it's a crash since you get the "application has encountered an unexpected error" window

btw my bad for mixing "desyncs" and "crashes" together. it's just that in previous wc3 versions it was a desync, like you'd get the ingame message saying it was a desync. that was like a year and a half ago though. in the most recent wc3 version it just straight up crashes, like the game fully closes instead of just booting you from the map

i'll check out the getlocalplayer stuff, i might've been careless with it potentially

also the player i was testing with said the game crashed when he left. dunno how relevant this is but thought i'd mention it

edit: looked at the places where i use the variable localplayer, and i've used it for two purposes:
1. playing a sound for a specific player, so something like:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • localplayer Equal to (Triggering player)
    • Then - Actions
      • Sound - Play Error <gen>
    • Else - Actions
2. changing transparency of a unit for a specific player:

  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • team[(Player number of (Picked player))] Equal to 1
      • localplayer Equal to (Picked player)
    • Then - Actions
      • Animation - Change base_progressbar_red[(Integer A)]'s vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
    • Else - Actions

idk if these are problematic but i haven't had issues using these in the past. i don't believe i use getlocalplayer for anything else in the map
 
Last edited:
Haha, good to know you could rule out the Z stuff. :D As for GetLocalPlayer(), playing a sound and updating vertex color should be fine to do locally.

The best thing to do next is to see if you can reproduce it reliably. If you can reproduce the crash reliably, then that's like 90% of the battle. I'm not sure if the triggers you posted are necessarily prone to crashing, but I remember seeing some threads about some of the UI natives crashing after patch 2.0? Not sure if those have been fixed. It might be worth disabling any BlzFrame natives and seeing if the crashes go away?
 
Level 12
Joined
Mar 21, 2008
Messages
375
The best thing to do next is to see if you can reproduce it reliably. If you can reproduce the crash reliably, then that's like 90% of the battle.
yee thats the hard part since it's so random

anyways i recently played on a version where i removed like 99% of the models and it didn't desync/crash. i dunno if this definitively means it's an issue with the models but i get the feeling that this might be it. i've done a lot of personal model edits for this map so i'd bet there's some weird faulty models here and there. if i figure this out ill report back i guess

edit: also dont think its an issue with frames, since i played a much older version of the map without frames and it still crashed. well i might still try disabling it tho who knows
 
Level 12
Joined
Mar 21, 2008
Messages
375
double post but i don't think the models are the issue sadly

i made a version of the map with most imports removed and playtested it, and it coincidentally didn't crash the 1st time, but the 2nd time i playtested it ended up crashing

my only real option is to host older versions and try to find the earliest version of the map that crashes, but this is really difficult considering how inconsistent/random it is. i have to test each version for like a minimum of 20 mins and even that's not enough because sometimes simply a crash will not occur at all. that and i need 1 other guy to afk which i won't always have available

im basically fucked thx blizzard

i guess i'll continue to test older versions of the map when i can since it's the only option anyway

i think it's worth noting that all the crashes that occur are usually for a single player, and it's somehow never me that crashes. also, the crash seems to occur in the first ~10-20 or so minutes but idk
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
You can test on LAN, no need to go online with others. Launch the client from the BNET app, then minimize after you load into the game and launch it again.

Anyway, just glossing over your first two triggers, and I mean this with all due respect, but they're a mess. The death trigger looks like it'd crash the game just from the sheer amount of stuff going on there. With so much Custom Script perhaps it'd be better just to write Jass directly, it'll definitely improve the efficiency and maybe help avoid these crashes/desyncs/etc. Desyncs are a major pain, hopefully you can get it sorted out.
 
Level 12
Joined
Mar 21, 2008
Messages
375
You can test on LAN, no need to go online with others. Launch the client from the BNET app, then minimize after you load into the game and launch it again.

Anyway, just glossing over your first two triggers, and I mean this with all due respect, but they're a mess. The death trigger looks like it'd crash the game just from the sheer amount of stuff going on there. With so much Custom Script perhaps it'd be better just to write Jass directly, it'll definitely improve the efficiency and maybe help avoid these crashes/desyncs/etc. Desyncs are a major pain, hopefully you can get it sorted out.
didnt know you could run 2 wc3 instances like that lol, ill try out lan, thanks

and yes my triggering is garbage but i would find it more helpful if you pointed out a more specific issue that might be linked to the map desyncing. well, maybe you're right though and my map is just such a cesspool of bad triggering practices that it just implodes lol. in that case i guess there's nothing to say.

i only know gui anyways lmao and i dont feel like dumping a time investment into learning jass when from my perspective there isn't even a clear cut guarantee that it'll even fix this map

to reiterate again this map worked perfectly fine pre-reforged in spite of my awful triggers. same with my other map monter2 (yes monter has the same issue) and that map somehow has even worse triggers than this
 
Level 24
Joined
Feb 27, 2019
Messages
833
Did you look at this?
 
Level 12
Joined
Mar 21, 2008
Messages
375
Did you look at this?
yea, most of these aren't relevant to my map though i haven't tried checking these yet:

a. Numerous "Player slot comparison"s, for example to check if a player is connected (source: my map. I recommand storing a player group for connected players updated with a trigger on event "player leaves the game").
b. Numerous "Player controller comparison"s (source: my map).
i'll check these next 4 sure since this map uses player slot/controller comparisons a lot

edit - update on the autistic desync saga:

i replaced all player slot/player controller conditions with a player group check. it appeared to work, since i did multiple tests in LAN by myself. first was 30 mins, second 40 mins, third around 20 minutes. no crash in any of them. i also tested to see if crashes could even occur by myself in LAN so i tested a version that i knew would crash, and it crashed 10 minutes in

i really thought this was the fix, but when i hosted on bnet with two other players, one of them crashed. the other may have left voluntarily, not sure.

not sure what to do now. i guess i'll try disabling frames for now.

also for all i know there could be multiple things causing desync which would make it difficult to know if changing one thing fixes it or not. all the things that i have tested thus far probably need to be tested again, namely getlocationz and the models...........

this is kind of a pain since i seemingly am unable to produce a crash when testing by myself in LAN, but it still crashes on bnet lol. i think i'm fucking cooked
 
Last edited:
Top