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

Panning camera with GetLocalPlayer() - safe?

Status
Not open for further replies.
Level 8
Joined
Mar 12, 2008
Messages
437
I want the camera to pan a fixed distance, but I didn't find a way to fetch the camera position for a specific player, for whatever reason.

So this is what I have so far:

  • Custom script: if ( udg_Pl[1] == GetLocalPlayer() ) then
  • Set R[7] = (Target X of current camera view)
  • Set R[8] = (Target Y of current camera view)
  • Set P[3] = (Point((R[7] + R[5]), (R[8] + R[6])))
  • Camera - Pan camera for Pl[1] to P[3] over 0.00 seconds
  • Custom script: endif
R[x] are reals, P[x] are points and Pl[1] is a player. The points are cleared immediately after. Can I do this thing with GetLocalPlayer() without causing desyncs?
 
Panning a camera is fine to do locally, but you shouldn't create objects locally.

In your case, you create a "point" object within the local-player block. That will cause a desync. You can do it this way instead:
  • Set R[7] = (Target X of current camera view)
  • Set R[8] = (Target Y of current camera view)
  • Set P[3] = (Point((R[7] + R[5]), (R[8] + R[6])))
  • Custom script: if udg_Pl[1] == GetLocalPlayer() then
  • Camera - Pan camera for Pl[1] to P[3] over 0.00 seconds
  • Custom script: endif
As far as I know, that should work fine. Technically the point "P[3]" is out of sync (it will point to different points for each player, based on their camera view), but it won't desync on that. If you want to be extra careful, then only use coordinates, like so:
  • Set R[7] = (Target X of current camera view)
  • Set R[8] = (Target Y of current camera view)
  • Custom script: if udg_Pl[1] == GetLocalPlayer() then
  • Custom script: call PanCameraTo(udg_R[7] + udg_R[5], udg_R[8] + udg_R[6])
  • Custom script: endif
I'm positive that will not desync.
 
Level 8
Joined
Mar 12, 2008
Messages
437
Panning a camera is fine to do locally, but you shouldn't create objects locally.

In your case, you create a "point" object within the local-player block. That will cause a desync. You can do it this way instead:
  • Set R[7] = (Target X of current camera view)
  • Set R[8] = (Target Y of current camera view)
  • Set P[3] = (Point((R[7] + R[5]), (R[8] + R[6])))
  • Custom script: if udg_Pl[1] == GetLocalPlayer() then
  • Camera - Pan camera for Pl[1] to P[3] over 0.00 seconds
  • Custom script: endif

But what happens with R[7] and R[8] in this case? Whose camera view will they store?
 
Level 8
Joined
Mar 12, 2008
Messages
437
For each player they will be a different value.

The value will their camera position, which is different for everyone.

I'm just calling the function (Target X/Y of current camera view), which should just have one and only one output value, not one per player. It's going to store one value, not one per player. Whose camera position will it store?
 
I'm just calling the function (Target X/Y of current camera view), which should just have one and only one output value, not one per player. It's going to store one value, not one per player. Whose camera position will it store?

Some values, such as camera coordinates, behave a bit differently than you'd expect. They are unsynchronized, which means that each player has his own camera coordinates and knows only his own camera coordinates.

Synchronization is just a matter of keeping values consistent between computers ("clients"). For example, let's say you have a map with two players, and some unit "Bob" is being attacked. When Bob takes damage, his hit points should be kept in sync between the two players. If he is at 300 hp for player 1, then he should be at 300 hp for player 2. If that isn't kept in sync, then weird things can happen. Let's say Bob has 10 hp left on player 1's client and 100 hp left on player 2's client. If he takes 10 damage, then he'll die for player 1 but not for player 2. Obviously, that can make for some really weird gameplay. Wc3 has all sorts of communication in the background to ensure that that doesn't happen. If it does happen, it will kick players (desync).

Anyway, certain things need to be kept in sync. For example, whether Bob is dead should be kept in sync between all players. If Bob is dead for player 1, he should be dead for player 2, 3, 4, etc.. If he is alive for player 1, he should be alive for player 2, 3, 4, etc..
Synchronized.png

However, keeping all this in sync is expensive and difficult, so wc3 only does a limited number of checks and tries to send as little info as possible. For example, wc3 doesn't bother syncing certain visual stuff like animations, special effect rendering, UI stuff, etc. Same applies for the camera. There isn't any reason that player 2 needs to know where player 1's camera is, so they don't send that. And cameras moved around a ton, so syncing it "properly" is difficult. That is why the GUI action doesn't allow you to choose which player's coordinates you want to retrieve. Normally we think of a variable as having one, universal value. But with unsynchronized values, it can have a different value depending on whose computer is running it. For example, if you had variables X and Y and wanted to set it to the (Target X/Y of current camera view), this is how it would actually be set:
Unsynchronized.png

X = 500 for player 1, X = 400 for player 2, X = 200 for player 3, etc. This is really similar to the way that GetLocalPlayer() allows you to run a particular code only on one person's computer. GetLocalPlayer() is also unsynchronized!

In your case, this is just fine. You only need to get a player's camera coordinates, add a number, and update the camera for that specific player. No other player needs to know about the update. So the code I posted should work just fine.

If you, for some reason, need other players to know about other player's camera coordinates, then you'll need to synchronize the data yourself manually. It is pretty advanced though, and most people will use scripts like TriggerHappy mentioned.
 
Status
Not open for further replies.
Top