My Networking Woes

I’m having real issues getting my head around unity’s built-in networking.
This post is a mix of my experiences and questions I have.

My main problem so far has been finding a clean way to implement networking, I have tried various different structures and still haven’t found a good one, mabye i’m just thinking about it all the wrong way.

I started off writing game, server and client logic all into one piece of code. That quickly became messy and difficult to handle (lots of “ifServer(do this) else (do this)” and short-circuits for the server as you can’t RPC yourself…).
The next re-write, I split the code into server and client. But that meant replicating the game logic. Didn’t seem right.
The current re-write i’m working on I split into server, client and seperate gameLogic. This seems better but there’s still a lot of replication and special cases that i’m finding frustrating.

Problems I’ve encountered :

  • Server doesn’t seem to call “OnPlayerConnected” for itself and doesn’t appear in the network.connections list.

  • Can’t RPC yourself (Used in the case where you are the server. I would have to call functions directly in the Client logic which again leads to spaghetti code!)

  • NetworkViewID isn’t serializable, you can send it through an RPC directly, but in my case I tried to create a serializable class containing all player Information so I can send all player info in bulk or with a full game state package (eg, to a new connecting client).

  • Can’t RPC byte : not really problem as you can send a byte[ ]. It just means an extra command to pack/unpack from the array. (just don’t understand why it’s not supported…I use a byte for playerID’s, which is another thing, Unity seems to apply it’s own unique ID’s to players (Server is 0) but with no way of accessing that info. It appears in the console with network debugging enabled)

If anyone has any advice on how to seperate server/client/game logic in a clean way I would be eternally grateful!
(Or am I even going about this the right way?)

Owen

Use OnServerInitialized for the server and OnPlayerConnected for the clients if your going for an auth setup. Sending traffic to yourself over the wire is not what you need to do.

Hey Appels,

Thanks for the reply!
I kept playing around with some ideas last night after I posted this and I think I was just thinking about it all the wrong way…
I was trying to write the client logic so that it could be used on both the client and the server (as the server can also be a client).
But now I’ve come to the realisation that it’s just not possible to do that (well, I mean I’m sure it’s possible, just not with my current programming profficency).
So now I have the server logic act as both the server+client in one (without trying to use the seperate client logic I wrote… it means a bit of duplication in places but i’m ok with that, and it’s still quite managable)

But now I have another small question (I have a workaround for it allready though). I can’t send RPCs between server and clients without the RPC existing on both. Is there a reason for that?

A quick example :

Pseudo Logic :

Server requests info from a client (Sends and RPC asking for info)
Client sends info to server (Recieves RPC from server, sends RPC with info)
Server uses info (Recieves RPC from client and does something with the info)

(Code may not be 100% accurate, just an example)
Methods in Server :

void AskClientForInfo(NetworkPlayer player)
{
networkView.RPC("SendInfoToServer", player);
}

[RPC]
void ReceiveInfoFromClient(string someInfo)
{
DoSomethingWithInfo(someInfo);
}

And now the Client :

string someInfo = "hello world";

[RPC]
void SendInfoToServer()
{
networkView.RPC("ReceiveInfoFromClient", RPCMode.Server, someInfo)
}

Now this would be great if It would work this way, the problem is that the RPC’s only exist on one script or the other but not both of them. So the RPCs don’t send (Unity complains that the RPC doesn’t exist on the gameobject it’s being sent from).
The workaround i’m using at the moment is to create the RPC method with the correct signature on both server and client. The method is just empty for the sending side.

So for example I would add this to the end of my server script above :

[RPC]
void SendInfoToServer(){}

And this to the client:

[RPC]
void ReceiveInfoFromClient(string someInfo){}

This all works fine, just a bit messy having to duplicate RPCs on both sides (even if only one side uses that specific RPC)

Sorry if i’m not explaining this very well, explaining networking seems to be like trying to explain how a time machine works :stuck_out_tongue:

Owen.

Unfortunately, thats really a limitation of Unity’s built-in networking. It’s a little difficult to separate client/server logic without using the same scripts and the same RPC names, with lots of isClient/isServer conditionals.

Yep just like legend says, but it’s possible to write readable networking code.

Awesome, thanks guys!

If it’s just a limitation then that’s fine, I had the feeling I was doing something wrong and trying to use the networking system in a way that wasn’t intended.
I think the way i’m doing it now should work out ok without getting too messy. I’ve so much to learn about networking ><