Multiplayer data exchange


I recently came up with an idea for multiplayer game. And I’m using Google Play’s real time multiplayer services(Android App). Now I know Google play services don’t have anything to do with Unity forums, but It’s not that I want to talk about.

My game excists of 2 players, and is real time turn based. To exchange data to the other user, I use the following line of code:

PlayGamesPlatform.Instance.RealTime.SendMessageToAll(reliable, data);

Where reliable true = TCP, false = UDP.
Data is a byte array.

Now 2 players are in the exact same scene, just on another device, and when player1 does something in his scene, I have to let player2 know of what he did, so player2 can change it in his scene.

Now let’s say we have a bowl, full of spheres with rigidbodys, all affected by gravity and forces, and one player can drag one sphere around, which interacts with all the other spheres of course. How should I handle this data? I tried:

  • Sending the dragged sphere’s position and name to the other player using UDP reliability, but when a packet is out of order, the physic interactions won’t be exactly the same on both hosts (and it has to be close to perfect). Also I have to loop trough all the spheres, in order to find the dragged one first, before I can change the position, which is a huge performance sucker for mobile devices, because it’s done multiple times per second.
  • exactly the same with TCP, but the hosts scene will just crash, or go VERY slow.

Oh, and the way I serialize the data to a byte array:

Serializable class:

public class BlockController
	public string Name { get; set; }
	public Vector3 Position { get; set; }
	public BlokController(string name, Vector3 position)
		Name = name;
		Position = position;

Serialize this class before sending:

private static byte[] ObjectToByteArrayBlock(BlockController obj)
	if(obj == null)
		return null;
	BinaryFormatter bf = new BinaryFormatter ();
	MemoryStream ms = new MemoryStream ();
	bf.Serialize (ms, obj);
	return ms.ToArray ();

and deserialize on receiving:

  public static BlockController ByteArrayToObjectBlock(byte[] arrBytes)
    	MemoryStream memStream = new MemoryStream ();
    	BinaryFormatter bf = new BinaryFormatter ();
    	memStream.Write (arrBytes, 0, arrBytes.Length);
    	memStream.Seek (0, SeekOrigin.Begin);
    	BlockController obj = (BlockController)bf.Deserialize (memStream);
    	return obj;

So basicly, what data should I send to the other host, to make sure the same physic interactions and all the sphere positions are updated? You may also correct my way of serializing, or if you have something better, shoot!

Thanks for your precious time!

my suggestion is let the phisics done by active player device, for example like this: player A phisic calculated by device A, and the position simple sent to device B, player B calculated by device B, and sent the postion to device A