Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Trying to sync data for chests/containers

Discussion in 'Multiplayer' started by Chris-Trueman, Jan 22, 2018.

  1. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    I'm trying to sync data like chest/container contents. These containers are placed by players and may spawn in the world naturally.

    I can get the data synced when the client opens the chest by sending the data when it gets opened. The problem I'm having is how to sync it up when a client connects. I have some containers that function like chests but perform an action on whats in the container, like a furnace in Minecraft. I would like to sync that data when the client loads the scene.

    Trying SyncVar on a struct with a byte array holding the contents works, but that updates all clients with this information. Right now I have it updating individual slots in the inventory when they get changed and this is then Rpc'd out to the connected clients so I'm not sending the whole stash at once to minimize on bandwidth. So when a client connects the SyncVar is out of sync and then needs to be updated which in turn sends that data to the already connected clients, that have a synced version of the data already.

    Is there anyway to send that data when the client joins so it has the right data synced with the server, but then be able to update individual slots after the initial data sync.
     
  2. Deleted User

    Deleted User

    Guest

    Why would you do that? Why not just send the data when a client opens a chest? Otherwise, it's just a waste of bandwidth. And in other hand, it is potentially hack-able, for instance, a hacker could write a hack, similar to ESP in order to see content of the every single chest without opening it on your map. So you basically give the hacker an opportunity to decide which chest he would like to open based on its loot. If you would do the way that I've suggested - the hacker would not know anything about the chests on your map.
     
  3. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Preferably send the content of the chest when a client gets within range. Otherwise you will have to hide the latency.
     
    Deleted User likes this.
  4. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    The chest functions as more than just storage, it has a process which it does to the contents like a furnace in Minecraft. This process is visualized on clients like the furnace in Minecraft, as it lights up when its doing it thing. Mine on the other hand is not just "lighting up" it displays some information that needs to be updated as it is processing so all clients see the same thing. Which is why I send slot updates as Rpc's to all clients that contain little data. This data is much less than the whole inventory as it is usually an int for slot index an int for item type and an int for count so it would be 12 bytes.

    After writing this out, I have solved the issue with a call to all of the objects that need this data to be updated from the players OnStartLocalPlayer. I loop through them all calling CmdUpdateItemData that passes the NetworkInstanceId of the item and then the server finds the local object gets the data then TargetRpc's the data back to that object.

    I am thinking to refactor the system so it will syncvar that its processing and send a bit of info that updates the visual. Then once the client opens the container, it will get the correct container data. I'm trying to minimize the bandwidth so i'm sending as little data as possible. The game is a sandbox type so it will have thousands of player placed objects, and its procedural so changes need to be synced. These changes need to be as small as possible to achieve that goal

    Not too worried about that, its a co-op p2p type game so its not at the competitive/MMO level that would require that kind of scrutiny that would be better suited to dedicated server type online play. If it does become an issue I can deal with it then, no need to worry about it unless the majority want it.

    If you have any other suggestions I am open to them.
     
  5. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    This will come later on, when I start to get into network visibility as its not a small map for each game. Its not endless, but its not small and will have thousands of items. In a single player version it was around 100k+ objects, with a quadtree like system to keep things out of the area inactive. Still running at quite an impressive rate, and the save was under 6mb(could be smaller with other techniques, and is when I use straight BinarySerialization.) I would like to only stream the info need to the clients as they move about and not send it all at once. Not sure how this will all work yet, and will need to do testing to see it all in action. Just learning about multiplayer as I convert a project from single player to multiplayer.
     
  6. Deleted User

    Deleted User

    Guest

    Oh well.

    First of all, you would not achieve 12 bytes per message with unet HLAPI. Why? Well, let's take a look at the source code. CMDs, RPCs, TargetRpcs have some kind of this data structure:

    Code (CSharp):
    1.  public struct CommandMessage
    2.     {
    3.         public int cmdHash;
    4.         public string cmdName;
    5.         public byte[] payload;
    6.     }
    as you can see, you have 4 bytes of hash + string name overhead, let's assume it's 8 bytes more. So for a single command or Rpc you have 12 bytes of overhead + don't forget about UDP header. SyncVar has the same overhead or even more, you can read about that in this post: https://forum.unity.com/threads/ban...rs-features-clientrpc-command-syncvar.404890/

    But again, it depends on player count.