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

Making a Multiplayer FPS in C++ Part 7: The Vulkan Projection Matrix, and Other Graphics Things

In the previous part of the series I mostly did some miscellaneous cleanup. This part unfortunately has no netcode whatsoever - it’s all about graphics (browse code here, it’s not pretty).

“You’re Not A Graphics Programmer, Stupid”

I’m no graphics guy, but I’m hoping I can still make an acceptable renderer. I’m trying to take a from-scratch approach with this thing, and graphics will be no exception. This means I need to derive the most basic building blocks like projection and transformation matrices, armed only with my B grade in A-Level maths from more than a decade ago. Though you don’t ever really need to do this sort of thing these days, it’s still (in my view) an interesting and worthwhile exercise.

The Coordinate System

Firstly I need to pick a coordinate system. For some reason, I always liked positive X-axis right, positive Y-axis up, and positive Z-axis forwards. I really have no idea why, but I found this tweet which nicely sums up the different coordinate systems and which engines/programs use which:

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