Building a simple online game server for Unity
Asked Answered
P

2

8

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 tried to build my own server with Nodejs là socket.io for server-client communication. It's very simple: receive data from one and broadcast 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 explodes, then broadcasts it to the other clients. Not to mention the cheating clients, with the network latency, the physics simulation of the clients will vary. For example, a tank might be hit on one client but it finds cover behind the wall on another one and stays alive, but the tank behind it catches the bullet and explodes, because of the latency. In these cases, the server doesn't know which one to listen to.

Update

  • As @Catwood mentioned below, Photon PUN is another option for me. I had followed one of their tutorials before. Photon doesn't need a player to be the "server" like Unity networking. But how do I implement my game logic on the server? (for authoritative server purposes)
  • Apparently Smartfoxserver is another good (and pricey) option. I haven't taken a deeper look at their API documentation. I don't know if I could implement my gaming logic and rules on this (their tutorial skip this part for the sake of simplicity).

In conclusion, I need a suggestion for my game server:

  • Is an authoritative server
  • Can handle game rules and decide what will happen (maybe it should have its own physics engine)
  • Works well with Unity2D
  • Javascript, C#, Java are preferred!

Am I going in the right direction, because seems like some game server services (such as Photon, Unity networking) 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!

Persons answered 28/5, 2015 at 9:20 Comment(0)
G
23

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

  • The size of the map
  • The number of player
  • Data about each player (Health point, position, size, attack speed...)
  • Any other information required to make decisions

Now, the client should always send very small signal to the server like the following

  • Move left
  • Join party
  • Shoot
  • Rotate right
  • etc...

Based on user's action and user's data, the server can run a "simulation" of the game.

  • Check if the action is allowed
  • If it's allowed, simulate the action. If it's not, put it in a queue
  • Send to users informations about what is happening (Player one hit, player two dies, player four moves left etc..)

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

  • be homemade
  • Only receive actions from clients
  • Simulate the game
  • Send clients information about what is happening
  • Synchronize at regular interval with clients

Hope this help =)


Here are some explanation on how to add logic inside your server. Small disclaimer before, I've never used NodeJS so I don't know if this is achievable using NodeJS, I usually use C++.

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.

Gariepy answered 28/5, 2015 at 10:11 Comment(10)
Thank you for you information. I believe you was talking about client prediction, interpolation, and server reconciliation. I've been working on it for a day or two. In your answer I think the "Server should simulate the game" part is my problem right now, since my server is just a "dumb server" and I don't how to implement some logic on it for the simulation =)Persons
@Persons well, it's not that hard but depends mostly on what your game is doing. I'll edit my answer to add some presicionGariepy
yeah that's pretty straightforward. But how about when a player being shot and bumps into the rock behind him, then bounces back into an other direction with different rotation, and that is where he's shot by the second bullet and explodes? Man, it's getting real complex right here, I think the server has to have some physics engine rather than some simple code. Am I thinking wrong direction?Persons
@Persons you don't necessarily need the physics engine inside your server. As you don't need your server to run a perfect simulation of the game. The "bump" is quite simple since it's just a movement opposite to the direction of the shot. Now for the "bounces back", if your don't want to calculate it, don't. Let the client send you it's position after the bounce. Your server just need to check if it's inside some bounce limit. If yes, the server accepts the client new position. You don't need to be fully authoritative about every aspect of the game.Gariepy
@Persons However, if you want a server fully authoritative, you'll need to implement a simulation of 2D physics. But in this case, you'll probably have a lot of problems because your server's physics engine need to behave like Unity physics engine.Gariepy
I am implementing ODE ( an open sourced physics engine) on my server. I think all the physics engine would behave same way if they have the same inputs, because they share same physics laws right?Persons
@Persons In a perfect world yes, but in reality this is not true. Each physics engine try to simulate "real physics", but since it's too CPU intensive, each physics engine includes his own approximation. Some are better than others. Here's an example media.giphy.com/media/o9awDl6tjqBvG/giphy.gif. However, since 2D physics is simplier than 3D physics, you should have a similar result. Just in case you should include a margin of error.Gariepy
Is it better if the server remained online 24/7? I know that a little sync gives a minor delay to update and monitor the game's event while server is out for a while.Capwell
@DavidDimalanta It depends on your game and the importance of client-server communication. Usually speaking it's better to have the server online 24/7. However, if your server is used only for leaderboard or other non-essential features you can have regular downtime without impact for players. Be sure that your client behaves “normally” during downtime. Throwing regular errors like “Connection timeout” can be very annoying.Gariepy
@GaryOlsson On top of that, I'm also concerned about basic necessities such as power bill. It needs to manage expenses before decided to do server online 24/7 in order to keep track on every player clients every second.Capwell
E
3

There is an asset on the asset store called Photon that is an authoritative server. It is free too for non mobile devices. This will handle the first part of your question for sure.

This great Tutorial will help.

Especially answered 28/5, 2015 at 9:36 Comment(10)
Remember Photon has restriction of 20 concurrent users. Currently there is ulink also but will have to purchase licence for that but its tutorials are easy compared to photon. Then there is dark rift which is also free but it has same restriction as 20 concurrent users. ulink : developer.muchdifferent.com/unitypark/Downloads dark rift : assetstore.unity3d.com/en/#!/content/16711Exon
I did not know that about the 20 concurrent users. That is very limiting, which is a shame.Especially
ya indeed but ulink doesnot have it and you can use it for testing as it is a evaluation copy but before releasing you will need licensing for that . Actually i havent found any multiplayer plugin which is truly free; though dark rift offers plugin dark rift pro for 50$ for 200 concurrent users dark rift pro : assetstore.unity3d.com/en/#!/content/16712 then they have $650 one for unlimited concurrent usersExon
@Exon "Remember Photon has restriction of 20 concurrent users" - it depends on which version you get. Free is 20; They also have 100; 500; and 1000 CCU versionsUndergrowth
@Especially hey do you have any experience using it? I've updated my answer for more information.Persons
@Persons I do a little bit, but not for any massive projects. I found it surprisingly easy and not much different from using the Unity networking.Especially
@Exon thank you, that was really helpful! But DarkRift doesn't support running server on Linux right? ulink seems to be powerful and well-documented..Persons
@Persons im not sure about dark rift running on linux server as i have never used it. So far i have used is ulink which was really easy to implement and also you can run it on linux and has authoritative serverExon
Very limited documentationPavement
DarkRift supports running on Linux now, via Mono. It also has examples of embedding, i.e. running a server instance inside a Unity scene build.Phenocryst

© 2022 - 2024 — McMap. All rights reserved.