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

GetLocalPlayer

"Handles that have their own stack will never desync!"

I speak JASS, but I don't know what that means. Handle stacks?

The stacks refer to handle ID's.

The main stack begins at 0x100000 (hex), which is 1048576. The reason why it is called a stack is because of the way handle ID's are assigned. Normally, handles will be +1 the last value. So the first handle will be 1048576, the next 1048577, the next 1048578, etc. Once a handle is destroyed, that slot becomes available. So if the stack is currently at 1049000, but the handle at 1048600 is available, then the next handle created will go to that slot.

That "general" stack applies to most handles, including units, triggers, rects, locations, and more. However, some handle types have special stacks. For example, texttags have their own stack that starts off at 0 and goes to 99 (or the other way around, I don't remember). The same thing happens for ubersplats and lightning handles (iirc). There are probably a few others as well.

As a general rule of thumb, those can be created within GetLocalPlayer() without desyncs. I can't say I've tested them all though, but I can guarantee that texttags work when created/destroyed locally.

However, those handles having a separate stack might not be the reason that they don't desync when created locally. We don't really have that much insight on how Blizzard coded Wc3. It is just an observed pattern.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Yes, them having their separate id pools is a factor. The main handle stack needs to be synced because types like units transmit information to other clients. The unit must be identifyable on the other side and this is done by having the same id. Now, not all included types really do this, like rects. You can however read them out (GetRectMinX, GetRectCenterY, ...) and often the won data is then applied in a supposed sync manner. So it is probably a security reason for them.

It really does not make sense for types like special effect, multiboard/multiboarditem.
 
Level 14
Joined
Aug 8, 2010
Messages
1,021
Just to point out something - i have been trying to make MPI quests in my map. Everything was good but i had a desync. I was wondering what was the problem. I thought that the problem could never be in the special effects, and guess what.. they were the actual problem... So i am warning you. Use this
  • Custom script: if GetLocalPlayer() == Player(0) then
  • Set Effect = Abilities\Spells\Human\DispelMagic\DispelMagicTarget.mdl
  • Custom script: endif
  • Special Effect - Create a special effect attached to the overhead of Peasant 0001 <gen> using Effect
not this
  • Custom script: if GetLocalPlayer() == Player(0) then
  • Special Effect - Create a special effect attached to the overhead of Peasant 0001 <gen> using Effect
  • Custom script: endif
This means that if the special effect is not created for all players, it causes desync. But if it's created and only the effect's path is changed to <Empty string> then everything is OK.
 
Yes. The tutorial shows that method with this example:
  • Special effect for one player
  • Events
    • Player - Player 1 (Red) skips a cinematic sequence
  • Conditions
  • Actions
    • Set Effect = <Empty String>
    • Custom script: set udg_Player = GetLocalPlayer()
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • Player Equal to Player 1 (Red)
      • Then - Actions
        • Set Effect = Abilities\Spells\Other\TalkToMe\TalkToMe.mdl
      • Else - Actions
        • Special Effect - Create a special effect attached to the overhead of Peasant 0001 <gen> using Effect
 
Well I can tell you for sure that #13 desync's 100% no matter what. You can't create a unit for one player unless I did something wrong which I hope someone points out because I really needed this to work. =(

[trigger=]
Melee Initialization
Events
Map initialization
Conditions
Actions
Custom script: set udg_Player = GetLocalPlayer()
Visibility - Disable fog of war
Visibility - Disable black mask
[/trigger]
[trigger=]
Untitled Trigger 001
Events
Time - Elapsed game time is 2.00 seconds
Conditions
Actions
Player Group - Pick every player in (All players) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Player Equal to (Picked player)
Player Equal to Player 1 (Red)
Then - Actions
Unit - Create 1 Knight for (Picked player) at (Center of (Playable map area)) facing Default building facing degrees
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Player Equal to (Picked player)
Player Equal to Player 2 (Blue)
Then - Actions
Unit - Create 1 Knight for (Picked player) at (Center of (Playable map area)) facing Default building facing degrees
Else - Actions
[/trigger]



[trigger=]
Untitled Trigger 002
Events
Player - Player 1 (Red) types a chat message containing - as An exact match
Conditions
Actions
Set UnitType1 = No unit-type
Set UnitType2 = Peasant
Set UnitType3 = UnitType1
Set Point = (Target of current camera view)
Set Player = (Triggering player)
Custom script: if GetLocalPlayer() == udg_Player then
Set UnitType3 = UnitType2
Custom script: endif
Unit - Create 1 UnitType3 for Player at Point facing Default building facing degrees
Custom script: call RemoveLocation(udg_Point)
[/trigger]




No matter what they can't work sadly.... =( Could have almost been a new age for WC3. Units have to be the same in everything apparently otherwise clients don't like that.
 
Level 6
Joined
Oct 31, 2015
Messages
95
Do you guys have any idea if modifying Terrain Fog causes desync? Just to be clear, I'm talking about Terrain Fog not Fog of War.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Since the new natives were introduced, did anyone already tried to use this kind of method to them?
Let's say the new function for the tooltips that allows us to change it in-game...

Will it cause desync?

To be honest, the implemented SetAbilityTooltip is not versatile than SetUnitAbilityTooltip for me.
That is why I have a thought of using this method for it.
 
The amount of variables don't matter (except you hit the op limit in jass). What matter is that the local changes result into the same game state and the same checksums for all players.

In Warcraft 3 everyone computs and simulates the game by oneself based on shared userinput. This has the consequent that one has to check if the players are still playing the same game. Therefore checksums are shared and compared. If such a comparision fails one gets a dc.
 
Level 23
Joined
Jun 26, 2020
Messages
1,838
The amount of variables don't matter (except you hit the op limit in jass). What matter is that the local changes result into the same game state and the same checksums for all players.

In Warcraft 3 everyone computs and simulates the game by oneself based on shared userinput. This has the consequent that one has to check if the players are still playing the same game. Therefore checksums are shared and compared. If such a comparision fails one gets a dc.
Thank you.
 
Level 23
Joined
Jun 26, 2020
Messages
1,838
Do we have a tutorial updated for 2023?
I don't think things are now that different, maybe the additions of frames and the sync function, but the idea is the same: don't create handles in GetLocalPlayer blocks or another thing that changes the outcome, maybe using the functions BlzGetOriginFrame or BlzGetFrameByName for a frame for the first time in a GetLocalPlayer block cause a desync because when used for the first time, it creates a handle for those frames.
 
Top