Problem updating synchronous variables in Fishnet

I’ve been trying to fix a problem for a few days now and I don’t know how to solve it anymore.
Basically I can’t correctly synchronize my variable with clients. On my GameManager.cs

public static GameManager instance;

public readonly SyncDictionary<NetworkConnection, string> playerNames = new(new SyncTypeSettings( WritePermission.ClientUnsynchronized) );

private void Awake()
{
     instance = this;
}

public void AddPlayerName(NetworkConnection conn)
{
     playerNames.Add(conn, GenerateName()); 
}

public void RemovePlayerName(NetworkConnection conn)
{
     playerNames.Remove(conn);
}
// ......

The data is not being updated using Observer (not even without it). This script is attached on Player (PlayerManager.cs)

 // It works
public override void OnStartServer()
{
     base.OnStartServer();
     GameManager.instance.AddPlayerName(base.Owner);
     UpdateUserboard();
}

    // It dont
public override void OnStopServer()
{
     base.OnStopServer();
     GameManager.instance.RemovePlayerName(base.Owner);
     UpdateUserboard();
}

public override void OnStopNetwork()
{
     base.OnStopNetwork();
     GameManager.instance.RemovePlayerName(base.Owner);
     UpdateUserboard();
}

[ObserversRpc(BufferLast = true)]
void UpdateUserboard()
{
      HUDController.instance.UpdateUserboard();
}

This is the function that updates the HUD interface on HUDController.cs:

public void UpdateUserboard()
{
     playerNames.text = "<b>Players:</b>";
     foreach (var playerName in GameManager.instance.playerNames)
     {
          playerNames.text += "
"+playerName.Value;
     }
}

I even managed to solve my problem using this in my Update on player controller script, but the issue is that I don’t want to consume game resources when updating the player. I would like it to only update when the player is disconnected.
In my logic, everything should work, by the way, when the player is disconnected, the server removes it from the synchronous list and notifies the observers. Where is the problem?

I would assume that in OnStopServer all clients have already been disconnected, and this method is only used to clean up any server-side state. It probably only runs on the server to begin with, with base.Owner being the server (host).

Instead you probably want to be using a kind of OnClientDisconnected callback.

1 Like

I managed to solve my problem. Basically, I discarded the callback functions I was using before and I’m now using only On(Des)SpawnServer to identify when a new client connects. Also, from what I understood, synchronized variables are not directly shared with the clients; they only reside on the server, and the server has to provide them updated to the clients. If I’m mistaken, please correct me.

So, I resolved everything in GameManager.cs:

public static GameManager instance;
public readonly SyncDictionary<NetworkConnection, string> playerNames = new();

private void Awake()
{
    instance = this;
}

public override void OnSpawnServer(NetworkConnection connection)
{
    base.OnSpawnServer(connection);

    playerNames.Add(connection, GenerateName());
    UpdateUserboard(playerNames.Values.ToArray());
}

public override void OnDespawnServer(NetworkConnection connection)
{
    base.OnSpawnServer(connection);

    playerNames.Remove(connection);
    UpdateUserboard(playerNames.Values.ToArray());
}

[ObserversRpc(BufferLast = true)]
void UpdateUserboard(string[] names)
{
    HUDController.instance.UpdateUserboard(names);
}