FPS (First Person Shooter) Networking Architecture

Hi friends,
first post in the the multiplayer networking forum. Please be gentle.
In short,
I would like to try to make a FPS multiplayer game with option for dedicated servers and up to 50 players in a game.

I completed Leepo’a networking tutorial and read the networking refernece guide. I also looked briefly at the official unity networking examples project.

Below is the architecture that I am considering:
Server
Non authoritative : Easier to implement. If the game gets that popular that someone cheats I will be honored. Then perhaps a ‘simple’? voting system can be put in place to kick a certain player.
Dedicated : the server itself is not running the game. It is responsible for the communication between clients. This is the same unity made application as the game itself.
Non dedicated : a user starts a server and can also play the game. Other clients connect. For small lan networks.
Master Server : master server for listing dedicated and non dedicated servers.

Is this correct? Is this doable entirely in unity? Should I consider external solutions like Photon? (which is free for 50 concurrent clients). I would prefer to do everything in unity if possible.

It all looks nice and simple conceptually: each client runs its own game with physics simulations; sends updates about player commands to server; receives updates about other player commands; performs necessary computations. Server manages communations only.
If only there was no latency, lag, ping… (I am not worried about bandwidth as of now)
But since there is, I need to use techniques to combat lag. Luckily, though, I can find all the relevant techniques for dealing with lag in the networking examples.

So my first questions are:
Are the statements I made above correct? Is my high level understanding correct?
It looks a little too easy to make a multiplayer game like this in unity, which makes me suspicious. What am I missing?
Are there any FPS games that can support up 50 players made with unity out there?

You will need to interpolate all positioning and have the server agree where you both should be. Sending just the commands will lead to a lot of lag, plus consider this scenario:

time 0: player A moved to X. player A’s physics are updated.
time 0: player B moved to Y. player B’s physics are updated.

time 20: player B is in a completely different place on his computer while player A’s isn’t.

Without the server performing corrections, physics on two different machines will gradually go completely out of sync and this isn’t even compensating for the concept of a player’s packets getting dropped, then sending commands that happened a long time ago.

Proper networked physics that actually work, send information to the server which does have its own local physics, and the server overrides player physics transforms and forces.

On top of that, those changes are interpolated for smoothness.

This absolutely will not work for long.

thanks mate. Now that I re-read my post, I see it was not clear. I meant that IF there was no lag, it would be nice and simple. Since there is lag I need to use the techniques from the networking examples. I am going to be sending positions and rotations and inerpolating buffered states. (as in the examples).
If I understand correctly you are saying I should use authoritative server instead?

Maybe check out the thread I started over here, as if you do want an authoritative server you’re going to run into the same issue.

I would guess that Unity’s networking could handle 50 players in an authoritative FPS if you were extremely careful about sending data and lowered the network send rate slightly. You would be putting a great deal of load on the server, and would probably hit CPU issues at the same time as networking limits, if not sooner. You would need Unity pro as you would need to run the server headless.

If you want to use something like Photon you can no longer (realistically) have an authoritative server, as it won’t have any way to access the level geometry unless you write your own rendering, raycasting, and culling system inside the server and have some way to load the collision data into it. Ultimately there is no point unless you’re doing it for fun, and you’d be better of using another engine for an FPS with this kind of requirement that includes a solid dedicated server already. Note that handling the amount of traffic that >64 players would require in an FPS is mind-boggling enough without these problems.

Interestingly, nobody seems to consider how they’re going to get the world geometry into Photon, Badumna, or whatever when they’re planning their super-ambitious MMO games in Unity. This problem alone should be enough to bring most people to their knees, as they’re not going to have NPCs or line-of-sight code without it.

Bottom line: stick with Unity, use an authoritative approach, and live with whatever upper limit you hit for network players per server. Brute force it with expensive server hardware. The only alternative is to pretty much write your own simplistic game engine inside Photon or something, and you’d have to be really keen on Unity to resort to this instead of just rolling with something like (urgh) Torque3d or UDK. You could of course not bother with an authoritative approach at all, but having that come back to bite you in the ass at the end of development with no way to correct it would be heartbreaking.

thanks xomg.
I have unity pro.
I will stick with unity.
Why should I use authoritative server though? How does authoritative server help with lag? I fail to see the benefit of authoritative server other than making cheating for players harder (which I don’t care about). But seems like both you and hippocoder suggest that I use authoritative server.
The way I see it is this: the clients calculate everything. Client 1 receives updates from server only for other clients’ positions and actions. which are buffered and delayed at say 200ms. So client 1 will see client 2’s position with 200ms delay. (even if it arrives earlier). Same is true for client 2 though (he will see client’s 1 position with 200ms delay) so it is a fair game.
There are of course problems with this. Say if client 2 is sitting still around a corner. Client 1 is running and sees client 2 sitting there and shoots him. Client 2 doesn’t know what hit him since he hasn’t even seen client 1 appear (he will see him in 200ms).
So players can take advantage of the delay by running around. But even with authoritative server this problem is still there.
And if you get killed too often when camping, then so be it. You have the option to run around like the other players.

I just thought I’d mention this in here as once you head down a non-auth approach it’s going to be horrible to change your mind later. If you’re happy to deal with the very real (and easy) possibility of people taking your client and modifying it to let them instantly kill everybody in your game at the press of a key, then stick with a non-auth approach. If you’re planning on actually releasing this game and want people to play it, you can’t really consider a non-auth approach but that’s just my opinion.

There are good examples of interpolation and extrapolation in the Unity networking examples and the M2H networking tutorials. The problems you mention about latency and prediction are just things that players have to live with, as it’s what most games like Call of Duty implement. You’ll probably want to have your game perform raycasts (server-side) based on the state of each player 100ms in the past, not their current position, which means that the player on the receiving end of the bullet might think he ducked behind cover in time but the shooter clearly saw the bullet hit that player in the face when he was visible. This gives the advantage to the player who rushes around the corner too, which I think is the opposite of what you describe above.

Check out this page detailing how Valve perform lag compensation. There is no perfect solution to this, but again I would say that none of it really matters if your game is hacked to pieces on the day of release because you have to trust the client instead of having an authoritative server.

thanks mate. I had read valve’s page. I will re-read it. As for cheating, I don’t think the game will ever be that popular. It’s more an exercise for me. (after I finish my simple cards multiplayer game for which lag is really not an issue). But just if it happens that I surpass myself and people do cheat on my game, I think a simple voting system to kick out a player would be sufficient…

For the moment ignore lag, as this can be fixed up later. Do something along these lines:

  1. server is running the game. It does all the physics and so forth as expected.
  2. client sends current transform + control input + timestamp*
  3. server solves these physics server side running as normal and sends the new positions to clients that can see that object
  4. client gets server data, and then updates its physics objects to match the forces and transforms from server
  • timestamp is only used if your networking solution doesn’t handle out of order packets ie timestamp them so that if you get a packet that is older than the packet you recieved before, you can discard the packet instead of acting on it. The web being the web, you’re not guaranteed to recieve packets in the order they are sent.

So for now just try making the clients and server do all the maths, and server’s data overrides client data. When this works, you will want to interpolate the forces and transforms of the client objects so they smoothly warp to the server’s idea of what things look like. Going further than this, you also could send inputs as well so that the client can predict where objects will be. But thats a polishing step at the end.

thanks hippocoder.
Bear with me though for a second.
You say I should go with authoritative server approach, but I fail to see the real benefit of it.
What is the problem with this:

  1. server is not running the game itself.
  2. client send current transform + control input + timestamp *
  3. server sends current transform + control input + timestamp to relevant clients
  4. client gets server data and updates to match transforms that it received from server

I don’t think things will go out of wack with this approach, will they? Transforms sent from other clients will be converging to their correct positions. If 2 players happen to be in the exact same position (which I don’t think will happen that often) I will solve this locally for the observing client. Sure they are a little out of sync, but when the next updates arrive they will move towards correct positions.

Start your game from the FPS example in the M2H tutorial. It includes basic interpolation to make remote players appear to be moving smoothly. You don’t need to send any inputs to the server if you’re going to trust clients, you can just rely on the built-in network views attached to the players through Unity. Clients send their location and rotation to the server, and the server believes this and relays it to other connected players. The clients of each connecter player updates the position and rotation of remote clients locally, and the interpolation/extrapolation makes them move smoothly instead of only updating every time a packet arrives. The server is doing nothing except relaying locations/rotations around and triggering things like explosions or opening doors through RPC calls.

When players fire their weapons they perform a raycast locally and tell the server where their bullet impacted. The server can then spawn an impact prefab at this location through an RPC. If the client tells the server that they’ve shot somebody, then the server subtracts health from that player.

Well yes you can trust clients if you really want to avoid the master server approach, but clients are still going to enforce their positions on you, and it is open to really easy speed hacks and so on.

The master server is nothing to do with cheat prevention, and we’ve already established that he’s not interested in using an authoritative server.

What you describe IS authoritative (assuming 2. is sent to server only) and I don’t think point #1 has much to do with being authoritative or not. It’s also a bit redundant to send control input data AND transform.

Non-authoritative would be like this:

  1. clients send updates to everybody about their location (no need to send control input – they just need to tell where to put that object)
  2. clients update that player object’s location based on received data

Non-authoritative servers can be more responsive because you’re not relaying anything through the server, but you’ll be less able to put a stop to cheating because there’d be no central governing client.

Authoritative servers would work like this:

  1. clients send control input to server (no need to send location – server decides that anyway)
  2. server calculates what that input would result in and whether or not it is valid
  3. server sends that result to everyone to update their objects (including guy who sent control input)

Authoritative servers are less responsive and rely more on interpolation and other techniques to keep things LOOKING smooth, but it allows you to interpret player actions and test whether they’re legit or not to put a stop to cheating.

I’m also creating a MP FPS in Unity (video here: http://www.youtube.com/watch?v=elYeMNLDtCk ) – I’m not aiming for such a large player count (I’m sticking to 5v5-10v10 ideally), but I’m in a similar situation where I’d almost be flattered if the game is popular enough to have cheaters (and if it does, I’ll address it then). I use a mix of authoritative and non-authoritative to keep things responsive but consistent. Movement and hit detection is non-authoritative, but all interactions with the CTF flags are authoritative (otherwise it was very easy for clients to disagree).

there is a third somewhat experimental option.

first you make the entire game deterministic (cant use float or any other command that behaves differently on different computers) so that if given the exact same set of inputs at the exact same time the game should play exactly the same on any computer.

second you send time stamped inputs for all the players to all the players so each player has the keystroke of every other player and the exact moment they pressed it.

third every time the player receives a new keystroke from another player they add it to a local history of the game, they then recalculate the state of the world based on the history of all the key presses.

this approach allows for an ultra lightweight server with minimal net traffic and eliminates most cheating excluding aim bots and wall hacks but requires more complex game code and is more CPU intensive for the client. it also means a very laggy player can degrade everyone’s game

this approach is most commonly used with RTS games but a FPS called survivarium uses this approach as well
https://survarium.com/en/news/survarium-update-034-preview

just realized i commented on a thread 6 years old fml

1 Like

Glenn Fiedler has written about this sort of thing: http://gafferongames.com/networked-physics/deterministic-lockstep/

(definitely check out his other articles too)