How to send a large file to all clients

We have a 4-player platformer-metroidvania full of switches and one-time collectables.

Any joining clients will need a copy of the the host’s progress.

Ideally the file would be small, but I’m definitely not at the optimisation stage and need to send a respectable blob of data to start testing. I can serialize the save file to a byte array using UnityEngine.Serialization, but I don’t know how I should send it, or even what kind of handshake to trigger once it’s successfully received.

Thanks in advance for any advice or guidance you can offer.

Hey there, one option is to use our Cloud Storage offering - it’s meant for exactly this: game configuration type data that doesn’t need real time sync: Cloud Storage | coherence Documentation

The game host would keep a key up-to-date on their particular game session and joiners would retrieve the data from the key at first start. During continued gameplay you can use commands to keep things in sync from there (among other ways).

Does something like that suit your needs?

That sounds like it would be ideal and is probably what I will try first.

2 problems remain:

  1. How do I broadcast to all clients that the host has uploaded to the cloud successfully?
  2. Is there a way to do this without the cloud? I’m thinking of situations like a game expo where the internet falls over at ironic moments, so if possible we’d try to run a replication server locally - LAN party style. A fallback solution would be nice to have in such an instance.

Hey!

How do I broadcast to all clients that the host has uploaded to the cloud successfully?

Once the CloudStorage operation finishes you can use a broadcast command to notify other players.

Is there a way to do this without the cloud? I’m thinking of situations like a game expo where the internet falls over at ironic moments, so if possible we’d try to run a replication server locally - LAN party style. A fallback solution would be nice to have in such an instance.

While we are already working on support for synchronization of arrays/list of arbitrary size, right now you could achieve the same using commands:

  1. Split your data into chunks of up to 500 bytes each
  2. Assign an ID to each chunk
  3. Send broadcast command with (id, totalChunks, chunkData)
  4. On the receiving side wait until you receive totalChunks number of commands
  5. Reassemble the data based on received chunks, using ID for ordering

The ID is required because commands are not guaranteed to be delivered in the same order they were sent. Alternatively you could use SendOrderedCommand

This simple approach is effective, however it has one major flaw - it will eat all of your available bandwidth for as long as chunks are transferred. You could improve it by implementing some kind of throttling where chunks are smaller and are sent in some interval (say every 100ms).

Hope this helps!