Making a Multiplayer FPS in C++ Part 8: Client-Side Prediction Revisited

I was lucky enough to go to GDC 2018, and while there I had the pleasure of sitting down with Glenn Fiedler in a really rather swanky tea place. For those not already aware, Glenn is pretty much “the netcode guy”. If you’re looking on the web for information about netcode and network models, then you’ll almost certainly read some of his articles. They contain a lot more detail than most about the actual implementation of the ideas, you can watch all the GDC videos about networking that you like, at some point it’s great to see some actual code. Even the Barnier paper from 2001 was pretty high level really - you could download the Source Engine source code, but it’ll take a while to get a foothold in a new large codebase. In 2009 when I was in my first job in the industry as a lowly intern, I was tasked with making an MMO client. I’d never even opened a socket at that point, in my googling I found Glenn’s site, I soon got pretty obsessed with netcode, and the rest is history.

The reason for meeting Glenn was to find out about his new company Network Next - which is also well worth checking out, the implications for multiplayer games are huge. The conversation turned to netcode, and he rapidly ran through various snapshot-interpolation related things that he thought I might need to know. In amongst that stuff, he showed me that I’d misunderstood something about inputs and client-side prediction.

Read More

Client-Side Prediction With Physics In Unity

TL;DR

I made a demo showing how to do client-side prediction with physics-based player movement in Unity - GitHub.

 

Introduction

Back in early 2012 I wrote a blog post about kind-of-but-not-really implementing client-side prediction of physics-based player movement in Unity. That nasty workaround that I described, is no longer necessary thanks to Physics.Simulate(). That old post is still one of the most popular posts on here, but with Unity today, that information is just sort of wrong. So here goes, the 2018 edition.

Read More

Making a Multiplayer FPS in C++ Part 5: Client-Side Prediction

In the previous part of the series, we rebuilt the game client in C++. Now we crack on with the real reason we bothered to do that - client-side prediction. Currently the "game" only really works with close to no latency (i.e. client and server running on the same machine or network). Now is the time to introduce some artificial lag, dealing with that lag is really where netcode gets interesting.

Read More

Making a Multiplayer FPS in C++ Part 4: Rebuilding The Client in C++

In the previous part of this series we had an outline of an online game with a fixed tick rate, and support for multiple clients to connect and move around. In this part we bin the horrible client made in Unity, and implement one in C++. You can browse the repository at this stage of development here.

The reason I want to rebuild the client in C++ is that for upcoming work on client-side prediction, we'll need the server and client to have a certain amount of shared code. It's possible to re-implement this shared code in C# for the client, but it would be easier to maintain if we just had one codebase written in C++. Plus I just prefer doing stuff in C++, so there.

Read More

Making a Multiplayer FPS in C++ Part 3: Multiple Players

In the previous part of this series we ended up with a basic outline of an online game with some very simple game logic, with a fixed tick rate, and support for a single connected client. In this part, we'll be adding support for multiple clients. You can see the repository as it was at this stage of development here.

The first thing we'll need is to actually keep track of the clients who send the server packets. At the moment we store their IP address and port we get from recvfrom, but now we'll need some kind of list of IP addresses and ports of the clients so they can be sent state packets en masse. For this I created an IP_Endpoint struct:

Read More

Making a Multiplayer FPS in C++ Part 2: The Main Loop

The previous part of this series was at best the "Hello, world!" stage of an online game. Now it's time to actually start actually laying the groundwork.

 

The Input Loop

Back in the day when multiplayer games were only played on a LAN, the clients would collect their user input, and send it to the server. The server would wait until it had the input from all clients, and then tick the game simulation, and send back the new game state. This is viable on a LAN because latency is so low, but it's not workable today, input lag of even a hundred milliseconds would feel sluggish, let alone two or three.

For now, I'll be doing LAN-style netcode - don't worry, it shouldn't remain like this for long, but it'll help simplify things at this early stage.

Read More

Making a Multiplayer FPS in C++ Part 1: Hello Multiplayer World

I write netcode because I love it. The problems that have to be solved in online games are particularly interesting to me - how to hide lag, how to replicate game state, how to compress data to save bandwidth, etc. I've spent most of my career working on multiplayer games of one sort or another - I built a couple of MMO clients at an indie startup, I was part of the online services team of Total War: Arena, and most recently I was on the network team for Halo Wars 2 DLC. My work has always been confined to just the client, or just services, or just some particular area. It's a necessity of modern game development that you can't do everything (or even some of everything), unless you're at a really small studio. I'd like to though, so I'm going to try to do it in some small way, and write about it here.

Read More

Client-side Prediction in Unity

If you're making a multiplayer game in Unity and your networking model includes a fully authoritative server, you might have found movement to be a bit of a stumbling block. Client-side prediction is how lag tends to be hidden, Glenn Fiedler has an awesome series of articles, this one explains client-side prediction nicely.

To summarise - clients send their input (e.g. key presses) to the server which computes their updated position in the game world, and sends it back to them. To hide the lag, the client runs the movement code locally, and records its input and position each frame. When an update is received from the server, it looks through all the recorded positions and compares it with the data received from the server. If the two are out of sync by too large a margin, it retrospectively corrects the client by moving them to the correct position, and then runs through all the stored inputs, replaying the users actions up to the present time. This "rewind and replay" system is fine under certain circumstances, but a big problem in Unity is physics.

For about two years I've been developing a Unity multiplayer FPS on and off. Naturally, players can run about, jump up and down, collide with objects, and so on. I have no way of triggering the Rigidbody component on the player to simulate a frame, so I can't rewind and replay can I? Well I can, if I roll my own basic Rigidbody class:

Read More