Search Unity

"Global" State synchronization

Discussion in 'Multiplayer' started by Flamboozle, May 15, 2019.

  1. Flamboozle

    Flamboozle

    Joined:
    Mar 14, 2017
    Posts:
    3
    Hello I am new to Unity networking and I am refactoring a single player game from the ground up to include multiplayer. I need help figuring out how to sync a game state.

    In my game, there is a world class that holds a big 2D array of tiles that has some information about the tile (it ID, Variation,etc...). I want to make a peer to peer game (like minecraft), where the host chooses one of his worlds to load up. When a new player joins, it should load that same world.

    And as for updating the tiles, I imagine each player would now have a copy of the world. When one player breaks a tile, it will update that information to all players/possibly re-render the chunk for any player in range.

    Right now, I have the WorldManager as a singleton class where the Player can interact with the current world. (world.SetTile(x,y), world.BreakTile(x,y), world.HasTile(x,y), etc...). I can't just use a syncvar because it is a big class with non primitive data types. What is the best way to redesign this structure so that I can keep a "global" state class that satisfies these two conditions:

    1. The host loads the world state when he starts the server/each player loads the current world state when they join.
    2. Any time a player affects the world state it will change the state for all players
    (Think of it exactly like a minecraft multiplayer server)

    Any help or advice is appreciated, thanks.
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Don't just now start learning Unet a year after it has been deprecated and Unity has started purging it from the scripting reference. Choose another network API.

    Off the top of my head, I'd have the server/host in charge of actually modifying the world state. All clients simply receive updates to the world state from the server but don't directly make any changes to it themselves. So a client wants to break a block, it sends a message to the server that the client is trying to break the block, the server breaks the block, the server sends all clients an update that the block is now broken.

    As for when a client joins you have a variety of options. If your game world is generated from a seed the host can just send the seed to any connecting clients to generate the exact same original game world, and then the host sends any changes which have been made by players.

    You can have the server send the entire original game world to any connecting clients, and then a replay of all changes ever made to the game world. The client then recreates the original game world and then replays all changes to be in sync. This may be important if one change affects the next and would need to be done in order, but it suffers from the loading of the game may become long if the game world is large and the game has been long running.

    You can have the server send the entire current state of the game world to any connecting clients. This is probably what I'd do if the game world isn't generated from a seed, and there is no need for clients to replay game world changes in order to be in sync with the server. Like above it can suffer from long loading times if the game world is very large.

    Any of these game loading methods may produce rather large messages, so you may need to use a network API with message fragmentation support, or split up the data into small messages yourself. Unet has a limited message fragmentation system (max size of a message to be fragmented was still fairly small) which is buggy anyways. So if you stuck with Unet you're probably writing your own message fragmentation system.
     
    wlwl2 and Flamboozle like this.
  3. Flamboozle

    Flamboozle

    Joined:
    Mar 14, 2017
    Posts:
    3
    Thank you for the response. I definitely have to use the last option you suggested as the world might be heavily affected from the time of generation and recreating it in that fashion isn't feasible. I think I understand how it works I just can't figure out how to write it in code. I know Unet is getting deprecated over the course of the next 2 years, but their new multiplayer solution isn't really finished or well documented at all. What other multiplayer services would you suggest for this project?
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Look at many of the available options here:
    https://forum.unity.com/threads/wha...of-available-network-solutions-assets.609088/

    In my case for a somewhat network heavy game I replaced Unet with a solution I developed myself to better fit my requirements.