Networking - Best way to Sync Rigidbodies?

Hello,

I’m working on a type of pool/billiard game over a local network using Unity’s builtin networking for iOS. I’m trying to figure out the best way to sync position of the balls.

Basically, I want it so when it’s Player One’s turn, that device only applies the actual velocity to the balls when hit, and then syncs the outcome of the position to the client / Player Two. And the same for when its Player Two’s turn. So who’s ever turn it is, will essentially control the balls physics, and sync it to the client.

What I’ve done so far is this, which is attached to all the balls (FYI, the initial force applied to the balls are also called locally, and synced in the same manor):

function Update(){

	if(GC.NETWORK.myTurn){

		networkView.RPC("SyncVelocity", RPCMode.Others, 	rigidbody.velocity.x,
															rigidbody.velocity.y,
															rigidbody.velocity.z);
	}
}


@RPC
function SyncVelocity(x : float, y : float, z : float){

	rigidbody.velocity.x = x;
	rigidbody.velocity.y = y;
	rigidbody.velocity.z = z;
}

Note how I’m only sending that RPC to ‘others’ … so the player that ISNT playing. Is this the correct way to do it? I’m worried that because I’m sending this every frame it might ‘overload’ the clients network listener … if thats even a thing?

I had also synced the local position and rigidbody velocity before, but when testing on my iPad2, and being the player who ISNT playing, everything went laggy, suggesting that there was too much data being sent from the current players RPC? (Although I didnt get lag when on my iPhone5 as being the ‘none player’. Maybe because its just generally better at processing it all).

I don’t know, just need a point in the right direction really?!

Thanks.

You are making a turn-based game, which makes things a lot easier for you.
Floating point operations may give different results on different platforms, so expecting that same setup will have same results is ingenuous. And proper realtime networking of physics is a very complex problem, usually combining prediction (what you do, local physics calculation) and corrections based on data from server.

But as i said, you don’t need to deal with this since your game is turn based. So why not just record the ball movement in frames (on the server), send it (and wait for the client to receive the whole “movie”)) and then, after all data is transmitted, simply replay the motion? No need for real-time simultaneous ball motion on all PCs, unless you want to be able to shoot them.

Having all physics being calculated on server will simplify the coding and prevent cheating.

I would have the server NetworkInstantiate all the balls, so that it is the owner. Have the NetworkView of each ball observe its Transform (it is by default) and set the transfer mode to unreliable.

Now, playing as the server is simple, as all computation is done locally and merely transmitted to the other players. But, how to allow the remote player to actually play? Easy enough: have each remote player send the parameters of each original strike to the cueball to the server. Then the server performs this strike and transfers all positions over the network.

This method will need to be improved if you have a fancy 3D pool-game where you actually hit balls with sticks and allow the physics to handle the rest (mainly because of the lag between hitting the ball and it actually starting to move can be discernable). But for a 2D, top-down view the only things you need to transfer over the network from clients to the server are

  • the angle at which the cueball was hit (direction)
  • the power of the hit (speed)
  • possibly which part of the ball was hit (for curve-balls)

In one sentence: Only send the parameters of the strike to the cueball to the server, and forget about controlling balls remotely.