I have been banging my head on this problem for a few hours now and I’ve come to the conclusion that RPCs in Unity Networking are NOT guaranteed to arrive in the order they are sent. I’ve created a very small example project to illustrate my point (Github: GitHub - project-arkana/pingpong: Quick test of Unity RPC ordering).
Examine the following code:
// Called on Server when a Client connects
void OnPlayerConnected(NetworkPlayer player)
{
// Sent to all players, including the server
networkView.RPC("Ping", RPCMode.All);
}
[RPC]
void Ping()
{
Debug.LogError(Time.frameCount + " :: PING!");
if (Network.isServer)
{
// Second RPC sent out to all players from the server
networkView.RPC("Pong", RPCMode.All);
}
}
[RPC]
void Pong()
{
Debug.LogError(Time.frameCount + " :: PONG!");
}
When a client connects to a server, the “OnPlayerConnected()” method is invoked on the server. It then sends out two RPCs in sequential order: Ping and then Pong.
However, the client receives them as Pong and then Ping.
I have been thinking about this one a bit, sorry for the slow reply:
Here is what is happening:
Player connects, method “OnPlayerConnected” is called on the server.
Server sends a RPC to self / client with “ping”
Server / client get ping RPC, only server processes the RPC
Server responds with a pong RPC call to both client and server.
Both client and server process pong RPC
My guess is that unity does not send a packet to the server, but instead directly calls the RPC method. It then makes an RPC call for pong, which is sent. This would appear in order on the server, but possibly not on the client. I would suggest adding latency to test this and see if it might be the case.
Btw, try using RPCMode.AllBuffered, see if that changes the behavior.
Thanks for replying! You are a very brave soul indeed =)
I checked out the answers link you posted – I don’t think this has anything to do with the NetworkView’s synchronization state. I can get this issue on NetworkViews that are totally not syncing any state at all. You are definitely right in that the Server’s executing both Ping and Pong locally without sending a network request. What’s odd to me is that they’re being called on the same frame in a specific order but being received in exactly the opposite order.
In fact, for experiments sake, I went ahead and created an RPC line from A-Z, where RPC “A” calls RPC “B” calls RPC “C”… etc… in the same fashion as the example above. Surely enough, the clients all receive the RPCs in reverse order (Z to A) without fail.
It seems like if you have an RPC call that calls another RPC and they’re performed on the same frame, the receiving clients will get messages out of order. It’s a very annoying bug and the only fix I can see right now is to delay the second RPC by a frame so that they truly come in order again.
The only other solution is to try making sure that you never make an RPC method that calls other RPC methods. That’s an extremely annoying constraint for my system.
Interesting. I will do some experimenting with this. Would you mind posting a test project? That way I ensure I am working in the same environment you are.