SyncVars are unreliable?

I’ve been messing with SyncVars and they’re not adding up. Either I discovered a bug or I’m terribly misguided on how this works.

From my understanding, when the Server sees an update to a SyncVar, it will automatically update to all the Clients. So I tested this;

[SyncVar] public int test;

Void Update()
{
     if (isServer)
     {
          test = 1;
          Debug.Log("Test is " + test);
     }

     if (!isServer)
     {
          Debug.Log("Test is " + test);
     }
}

Both Server and Remote Client claim test = 1. The SyncVar is a success.

So then I try it with a Cmd;

[SyncVar] public int test;

public override void OnStartLocalPlayer()
{
     if (!isServer)
     {
          CmdTest();
     }
     base.OnStartLocalPlayer();
}

[Command]
void CmdTest()
{
     test = 1;
}

Void Update()
{
     if (isServer)
     {
          //test = 1;
          Debug.Log("Test is " + test);
     }

     if (!isServer)
     {
          //Debug.Log("Test is " + test);
     }
}

Here are the Results;

All of a sudden once I update the SyncVar through a Cmd, Test is continually updating as both Zero and One. I know I’ve got to be missing something.

2643954--186163--SyncVar.png

I’ve been trying things for a while and I thought I came up with the answer once, but I found holes in my argument. My only guess is that there might be a case where the Server and the Remote Client get the Update to SyncVar ‘test’, but the Server’s Local Client doesn’t. Which seems strange. Aren’t they connected? Somehow, someway, test is able to be both 0 and 1 at the same time.

That shouldn’t be the case though, considering an Update to the Var is SUPPOSED to change it across the entire Network. I even tried other code like Instantiate, 0 & 1 are both acceptable answers apparently.

Its really hard to tell whats happening in the log because of the Collapsed log. I can’t see anything wrong with the code. Server’s local client is the same instance as the server so they must be the same value.

I’m going to guess that you’re running the server as a Host, and the script with the test SyncVar is attached to the prefab you’ve registered as the player object. If that’s the case, I think you just have two objects spawned. What I think is happening:

  1. The server starts hosting the game. It spawns a player object for itself, A.
  2. A.OnStartLocalPlayer runs on the server. Since this is running on the server A.isServer is true, so A.CmdTest() isn’t called. A.test is 0.
  3. The remote client connects to the game. The server spawns a player object for it, B.
  4. B.OnStartLocalPlayer runs on the remote client. B.isServer is false because we’re running on a client, so it calls B.CmdTest() on the server.
  5. B.CmdTest() runs on the server, setting B.test to 1.
  6. The server runs A.Update and B.Update, reporting 0 and 1. (The remote client also runs A.Update and B.Update, but because isServer is false over there, it doesn’t print anything).

Could this be the problem?

This helped a ton Jirin. I was overlooking the possibility of the SyncVar only updating the variable associated with the PlayerObject that initially called the Command. Based on how the Docs explained it, I assumed the same Var would equal the same across the entire network. I put it to the test and it works!