I'm trying to build an online game server for my Tank game 2D (Unity). In my game there will be 2-4 players control their tanks and fight each other.
I've tried to use Unity networking, it was not really suitable for my game because we have to choose 1 of the players in the room to become the "server", which is not really flexible for my future development (e.g. when the "server" quit, I have to do a lot of work to remain connections between the other players).
Then I've tried to build my own server with Nodejs là socket.io for server-client communication. It's very simple: receives data from one and broadcasts them to the others. It seems to work fine until the physics part comes in: the server must trust the clients when they say there's something being hit or explode, then broadcasts it to the other clients. Not to mention the cheated clients, with the network latency, the physics simulation of the clients will vary. For example, a tank might be hit on this client but it should be covered behind the wall on the other one and stay alive, but the tank behind him catches the bullet and explodes, because of the latency. In these cases the server doesn't know which one to listen to.
In conclusion, I need a suggestion for my game server:
Am I going the right direction, because seems like some game server services (such as Photon, Unity networking) just don't care about how to implement game logic on the server. And does it make them not an authoritative server?
I am very new to this field, anything will be appreciated!
I would advise to create your own server for your game like you did with NodeJS. Most of the solution I know are quite hard to use and cannot do eveything you want to.
For example, Blizzard game's Hearthstone is based on Unity for the client and have a custom made server side.
Here are some advice on how to create your game server.
It seems to work fine until the physics part comes in: the server must trust the clients when they say there's something being hit or explode, then broadcasts it to the other clients.
When creating your server you must make every important decision server-side and not client-side. It is the server who start the party, so the server must have the following information
Now, the client should always send very small signal to the server like the following
Based on user's action and user's data, the server can run a "simulation" of the game.
With this, the server knows when something happens and decide what happens. You do not rely on client side information, you only recieve the player's desired actions.
However, as you said, because of latency and other network factors, your client cannot be too dependent of the server. In modern games, the client have the same data about the player than the server and do not always rely on the server to display on screen what is happening.
If you played some online games, you may have noticed that when a connection with the server is lost, there's a small amount of time during which you can continue to play (move, shoot, etc..) but nothing moves except you. This is because the client continue to "run" the game based on your action even without server's informations.
However, to avoid any huge difference between what is displayed by the client to the player and what is happening in the server's simulation, the client and the server "synchronize" at regular interval.
For example, if you decide to move left, the client knows your move speed so it can display the movement without relying on the server.
When the synchronization occurs, the server send to the client critical information and the client change any currently displayed informations with what the server send.
Whith the left movement example, if your movement speed is different on the server and on the client, when the client receives a synchronisation order, you'll notice that your player will be "teleported" from the displayed position to another. This can also occurs if some packet are lost or because of high latency.
Handling lantency is a huge challenge when creating an online game both on server and client side and it's not the topic of this question.
To summarize, your server should
Hope this help =)
Now for your game, I'll assume that the player can only use the action MOVE.
When a user connect to you server, you can launch the game. Because your user can move, it means that there's a 2D map, that your user have a size and an initial position and a speed. So your server should start a new "GameParty" and initialize the above data. For the example, let's assume the following defaults value are set.
map_width = 512;
map_height = 512;
user_width = 2;
user_height = 2;
user_speed = 1;
user_posx = 20;
user_posy = 20;
When a client wants to MOVE, he send a packet to the server saying he wants to move. You can use any protocol you want for client<->server communication, I use a binary protocal but let's say you use Json
{action: move; value: left};
With this, your server will know that the user wants to move to the left.
So, you just have to decrease user_posx
by the value user_speed
to have, server side, your new position. If this position are on the edge of the map, you have two choice, making the user appear on the other edge of the map of forbid the action.
At regular interval of time, your server will send to the client the player's current position.