Advertisement

In depth articles about fast paced multiplayer network architecture

Started by June 26, 2016 10:13 PM
8 comments, last by Iron-Warrior 8 years, 4 months ago
Hi there,
I've been working on a multiplayer game for awhile now that is essentially (as far as coding goes) a first person shooter, using Unity. This is the first multiplayer project I've worked on and have been learning as I go. So far I have a prototype up and running, but it's written using Unity's High-Level API (using custom code, as opposed to their built in components) and overall is very limited. Here's a video of it.
After digging into Unity's HLAPI over and over I've come to the conclusion that it's simply not worth the hassle, and am planning to rewrite my netcode using their low-level api (which basically just handles connections and raw data transfer). So essentially I'll be writing it almost from scratch, from an architecture point of view.
Much like any FPS, it will be client-server architecture, with an authoritative server and prediction on the clients. Because my gameplay revolves around being able to precisely target enemies with a projectile (the sword boomerang), I've been predicting the boomerang's logic in addition to the players' (since I know in lots of games, projectiles are not predicted as there isn't much precision required to throw a grenade or fire a rocket). Finally, all non-player (non-predicted) entities on the client will be interpolated between authoritative positions sent from the server.
Obviously this is lots of complicated stuff! (To me, at least). My primary sources to get this far have been Valve's great multiplayer networking articles, and Gabriel Gambetta's superb high-level overview of fast-paced multiplayer games. What I feel that I'm missing out on right now is a resource that explains how to practically write code that performs all the above tasks. Once you start adding in interpolation, reconciliation, different kinds of prediction (dead reckoning and so on)...it starts to get pretty wild. Does anyone have any comprehensive articles or books that discuss implenting multiplayer games? I suppose if not, this thread can be the start of a discussion!
I'm not aware of any such comprehensive resources, unfortunately. Mainly, because all of the different solutions put together, make for the better part of a game engine, so where all the pieces exist together, they will make up an engine (Source or Unreal or whatever.)
And, the few resources that exist for game engines, typically do not put networking as their main illustration, because networking is only used by a subset of games, AND it's pretty complex (as you are finding!)

The meta-advice I can give is to separate concerns between different pieces of code. In Object Oriented code, this should be trying to achieve the "single responsibility principle." In a more functional approach, keeping each function shorter/smaller, and composing functions to achieve the end goal, would achieve the same results.
enum Bool { True, False, FileNotFound };
Advertisement

I'm not aware of any such comprehensive resources, unfortunately. Mainly, because all of the different solutions put together, make for the better part of a game engine, so where all the pieces exist together, they will make up an engine (Source or Unreal or whatever.)
And, the few resources that exist for game engines, typically do not put networking as their main illustration, because networking is only used by a subset of games, AND it's pretty complex (as you are finding!)

The meta-advice I can give is to separate concerns between different pieces of code. In Object Oriented code, this should be trying to achieve the "single responsibility principle." In a more functional approach, keeping each function shorter/smaller, and composing functions to achieve the end goal, would achieve the same results.

Yeah, networking for sure is something that you can't really build to be as general as graphics or collision (which most engines make their staple). For graphics if you want to make a completely different look it usually comes down to shaders (in the code portion at least) whereas networking there's lockstep vs predicted vs rollback and others...so I guess I shouldn't be too disappointed!

For your second paragraph, Good advice! When I look at other engines like Source they seem to always have command line tools to disable entity interpolation, prediction and so on, so in theory it seems all those components are just layers over the core logic of the world. I've rebuilt my game 4 times now (although bear in mind I had zero networking experience at the start), and I've written some stuff down describing how I want to do it this time, which I think I'll post here to see if anyone else is interested in the topic.

I previously tried to find the same thing, then I realised that the task is simply too big - or game specific - that it's simply not there, at least not yet. Some tutorials exists in youtube for making MOGs, but I don't even bother seeking those out as they are not really worth of your time. I think a lot of people decides that it's time to make tutorial named "How to make MOG" once they know how to pass values between client/server using simple "x/y" values or inputs - which is fine. But what they doesn't say is the fact that it doesn't work anywhere else than localhost because problems caused by latency is not solved.

Nevertheless, I have been lately reading articles from: ithare.com and gafferongames.com.

Hence, you can find more articles (around 40 - 50) from digital libraries like ACM and IEEE if you use keywords like "multiplayer online game architecture" etc. However, most of these articles needs to be purchased and you can find more in-depth knowledge using resources already listed above.

-

Have a look at my collection of links at http://www.gamedevpensieve.com/network. One of them might give you some insight :).

@spinningcubes | Blog: Spinningcubes.com | Gamedev notes: GameDev Pensieve | Spinningcubes on Youtube

I previously tried to find the same thing, then I realised that the task is simply too big - or game specific - that it's simply not there, at least not yet. Some tutorials exists in youtube for making MOGs, but I don't even bother seeking those out as they are not really worth of your time. I think a lot of people decides that it's time to make tutorial named "How to make MOG" once they know how to pass values between client/server using simple "x/y" values or inputs - which is fine. But what they doesn't say is the fact that it doesn't work anywhere else than localhost because problems caused by latency is not solved.

Nevertheless, I have been lately reading articles from: ithare.com and gafferongames.com.

Hence, you can find more articles (around 40 - 50) from digital libraries like ACM and IEEE if you use keywords like "multiplayer online game architecture" etc. However, most of these articles needs to be purchased and you can find more in-depth knowledge using resources already listed above.

Great links! For anyone reading this in the future, start at the beginning of the ithare stuff and go through it. It seems dense and low leveled but already is really useful. Only skimmed the gaffer stuff, and while it's less structured looks well written.

Have a look at my collection of links at http://www.gamedevpensieve.com/network. One of them might give you some insight :).

Lots of good variety here, especially in topics that aren't common to see discussed.

Given that it doesn't seem likely there will pop up a tutorial titled "How to create a sword boomerang game in 5 easy steps," I'm going to start working on create a robust system for my above specs, and I'll post some high level designs here when I've got them. In theory, it should mostly come down to sending data to be synced and handling certain state changes as events (if a player enters the jump state, play appropriate animations). Then for all the smoothing and prediction and whatnot should all be done as a layer on top of this.

Advertisement

This might be a useful video which talks in detail about the techniques they use for rocket-like projectiles in Overwatch (which are much harder to do well than bullet-like projectiles):

That video is pretty good at explaining the challenges that a physics network game faces.
It doesn't really talk about the solutions at an implementation level, though.
If you haven't analyzed network games and the role of latency in physical simulation, it'll do a good job of introducing the challenges.
The mechanisms they describe are better described for programmers in the Gaffer articles ("zen of network physics".)
The additional illustration of how they choose to assemble the pieces (which weapons use which method) is a good illustration of how physics engines, network engines, and game design all interrelate to make a good game!
enum Bool { True, False, FileNotFound };

The mechanisms they describe are better described for programmers in the Gaffer articles ("zen of network physics".)

Mr Gaffer is making an open-source library to act as a framework for building realtime game network protocols (and a new company to provide consulting on the topic), which isn't released yet, but you can get early access to it by backing him on Patreon.

Yeah, the Overwatch video is great, was good to see that some of the things I was doing (predicted projectiles) were on the right course.

As we finally arrived at the weekend, I managed to sit down and write out a rough draft of how the networking should work. I outlined the server and client loops, as well as the base NetworkObject class that all networked objects would inherit from.

Server tick (fixed):
- Load in any received inputs
- Run Step(tick) on every object in the game world
- Broadcast new state info to all clients
Client update (variable):
- Read any incoming data and apply it to objects
- Reconcile predicted objects, smooth non-predicted
- Run Step(deltaTime) for all objects, caching inputs
- If time > lastSendTime + sendInterval, send all cached inputs to the server.
Object types:
NetworkObject (everything)
- Has series of variables that totally define it's state in the game world, from Transform (position, rotatation) to object specific states (flying, falling, exploding, whatever).
- Should probably have an additional variable keeping track of how long it has been in a specific state (since some states last n seconds, like reloading a gun)
- All state information must be smoothable
- Object must be TOTALLY defined by state information; no other data about object is ever sent
- Broadcasts all this information to clients each tick (when necessary)
-> Server only objects
- Objects that are not owned by any client players. Barrels, land mines, dropped weapons...smoothed on clients
-> Client objects
- Owned by a specific player. These objects are predicted locally and reconciled with server data
- On non-owner clients, these are treated like any other server object and smoothed (not predicted).
Smoothing types:
-> Interpolation: Cache previous n ticks of data, then interpolate between them
-> Extrapolation (dead reckoning): Run the object's Step(deltaTime) method. When server data comes in, rewind the object and replay previous frames (this is basically prediction?)
Main things I see needing to be addressed:
- Making a NetworkObject class that can have any amount of member variables serialized over the network (though obviously a limit number of types. Float, int, Vector3 and rotation data mainly).
- Managing all of the state data and not destroying it when interpolating, extrapolating, predicting...and making sure not to replay certain things when reconciling (sounds, effects) so things don't happen twice.
- Making sure this all works fine when the server and client are on the same machine (host).

- Will need to keep track of the server's tick number on the client to be able to accurately reconcile objects

I'm sure I'll discover that some of this won't work quite so simply once I start implementing it, but I think it's a good star to steer my ship towards.

This topic is closed to new replies.

Advertisement