Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design my online Game Server for Unity3d?


Recently, I have been doing multiplayer game development in unity3d. I have got the pretty good idea of how the Unity's MasterServer works in unity.
But now I want to make my own game server from scratch. I researched and got to know that we can use the Google cloud compute and the app engine for making our own matchmaking server and the game host server.
But I am totally clueless how do we start doing coding my server. Do we do it using simple http request and json result? Or is there any other technique that can in real time work with FPS type games also. I dont think that the sending http requests and waiting for it result can be fast enough to work in a FPS type games where every seconds we send more than 100s of datas.
At first I thought of writing php scripts and hosting it to some url, and then sending request to that url and wait for its response. But I found out that if I use this process then for just getting one response from the server it would take me atleast 0.5 seconds or more. In this condition, there would be a lot of lag in game.
I know that game servers work on some kind of tcp or udp networking. But my question is this that what kind of application shall I make for the server to receive these datas and send the processed results fast.

like image 283
rsinha Avatar asked Apr 21 '17 13:04

rsinha


1 Answers

First of all I think that you are confusing MasterServer with the connection required to send and receive game data during gameplay.

MasterServer is used to retrieve the information of the server that created the game such as IP Address and port number. After you retrieve the IP and port number, the client can directly connect to the server with these information.

Do we do it using simple http request and json result?

For MasterServer, yes you can. You can also use it in combination with PHP to save game sessions on the database.

For example, when player wants to create a new game, you take you take their game information such as game name, password, max players, player's ip address, port number then serialize it to json and send using RESTful.

You can use PHP to receive that game information and store it into server so that other players can find it.

This shouldn't affect performance since you only using it to create, query and destroy game seasons. You are not using it to send game data during game play.


As for sending data during gameplay, you do this with raw socket. Either TCP or UDP with C#. Go native with C++ with if you want to get the maximum performance sine Unity's UNet is written in C++. Most FPS server's are written in C++ and this is to make sure that they get the maximum performance ever.

Remember there are many types of servers so I can't cover all of them in this post. I will just focus on MasterServer which tells client the IP addresses on Games created then Relay which is used when direct connection between players cannot be established.

I suggest you use Google's Protobuf over Json for its performance and lightweight. If you find any serialization API that's faster than Protobuf then use it.

Direct Connection:

Server:

1.Use Nat to perform port forwarding.

2.Create Game by creating TCP/UDP server.

3.Send the Game Info(game name, ip, port number) to the MasterServer.

4.When client connects with that information, start sending data by serializing the data(FPS player position?) with Protobuf send, to client.

5.When you receive data from the client, deserialize it with Protobuf.

Client:

1.Connect to the MasterServer and retrieve running Game Informations.

2.Create a TCP/UDP client and connect to one of the IP and port number.

To send and receive data, use steps from Server #4 and #5.


Sometimes, port forwarding won't work on some devices. In that case, two players with different global IP Addresses cannot connect together and this is where a relay and C++ comes into play. The relay should not be done with http requests, json or php. It should be made with C++ or some similar fast language such as python.

Again, there are many ways to do this. The easiest way is to generate a private key for each game that is created. When server/client send data to one another, they must include this key in that data and this key will be used to determine who the relay server should send the data to.

Connection with Relay:

Server:

1.Create Game by connecting to sending the Game Info(game name) to the MasterServer.

2.MasterServer responds by generating a private key and returning it to the Server.

3.Connect to the relay server with that private key.

4.To send data to other players, serialize the data(FPS player position?) with Protobuf then send to the Relay server. That data must also contain the private key.

5.Relay server receives data from this server, reads the private key and forward/send the data to any other client with the-same private key.

6.When you receive data from the Relay server that the other player sent, deserialize it with Protobuf.

Repeat from #4 to #6 as long as the connection is still alive and game is still not over.

Client:

1.Connect to the MasterServer and retrieve running Game Informations.

2.MasterServer responds by returning a private key of that game to the client.

3.Connect to the relay server with that private key.

4.To send data to other players, serialize the data(FPS player position?) with Protobuf then send to the Relay server. That data must also contain the private key.

5.Relay server receives data from this server, reads the private key and forward/send the data to any other client with the-same private key.

6.When you receive data from the Relay server that the other player sent, deserialize it with Protobuf.

Repeat from #4 to #6 as long as the connection is still alive and game is still not over.

like image 83
Programmer Avatar answered Nov 06 '22 17:11

Programmer