Best practices for sync'ing state using custom room properties in a multiplayer session?

We are working on a multiplayer game that has up to 4 players in the current room.

In one of the levels, we have a scene with multiple tile maps.

As a player travels through the scene, tiles are revealed and a fog in another tile map is also removed.

During a session, RPC's call are being made to let the other players sync. the state of the tile map.

As well, data is added to a hash table for the current room.

In the case that a player joins a session in progress, the contents of the hash table are iterated through to get the current tile map state.

private void ProcessTable(PhotonHashTable mapTable)
{
   Debug.Log("Process data table");
   foreach (string key in mapTable.Keys)
   { 
     ...
   }

We are seeing issues where the hash table does not appear to be correct. There are times when a tile state is such that it is set to null in the hash table to remove it. It seems this is not working (?).

PhotonHashTable table = new PhotonHashTable() { { key, null} };
PhotonNetwork.CurrentRoom.SetCustomProperties(table);

Working with the tile map Vector3Int, we are creating a key value for each tile and associating some a boolean with the generated key in some cases.

var key = Constants.KeyPrefixUnblockedTile + tilePosition.GetHashCode();

We are looking for advice on best practices in dealing with such data and also how to troubleshoot any issues:

  • How do we force an update to all the player sessions to ensure they are sync'ed?
  • A general question - is a hash table with key value pairs on the current room adequate to maintain the state for a tile map with hundreds of tiles? The tile type at a position get changed to a different tiles depending on game events. For now, Vector3Int are converted to a coordinate using a Vector3 when the position needs to be stored. As mentioned before, some data is stored using a generated hash key such that the value can be removed if the state changes.

Comments

  • I did some more work on my code & there was some bugs with how the hash table was being used. But still, we would like some tech support.

    Anther question. are there any diagrams like a UML time sequence diagram showing what happens when a scene is loaded in comparing the session for a player in the Photon session and a player who has just joined the Photon session. It would be very helpful to see the order of events with the player game object created and when the callback occurs:

    OnPlayerEnteredRoom.
    

    This might be causing some problems with the sequence in which code logic is being executed.

  • Hi @ManjitB,

    Thank you for choosing Photon!

    How do we force an update to all the player sessions to ensure they are sync'ed?

    I think what you are doing is correct but I could get rid of the RPCs and just listen to properties updates via OnRoomPropertiesUpdate callback. No need to send an RPC + update corresponding properties if it's the same thing.

    You need to be aware of timing and the asynchronous nature of properties update though (on client who sets those). Read more here.

    is a hash table with key value pairs on the current room adequate to maintain the state for a tile map with hundreds of tiles?

    Yes and no. Hundreds could be too many and probably too big if values are big enough? It depends on how compressed and optimized this is.

    are there any diagrams like a UML time sequence diagram showing what happens when a scene is loaded in comparing the session for a player in the Photon session and a player who has just joined the Photon session

    No diagrams sorry. But I can tell you that when a level/scene is being loaded the message loop/pump is paused so no incoming message is dispatched and processed until the loading is done. This way no received message is lost and you get the messages on the new scene. Read more here.

  • Hello John, thanks for the reply.

    Yes, we could probably could remove some RPC code with some of the data elements in the hash table.

    Can you describe in more detail how the hash table is sent over the network layer? Is the transmission broken up into multiple packets per se depending on the size?

    In absence of a flow diagram. Can you describe the sequence of event timings when a player joins a session in progress? We experienced an issue where the new player is in the session but getting the other player objects fails in the context of knowing where a player can be positioned in a game map:

    playerGameObjects = GameObject.FindGameObjectsWithTag("Player");