Hacker News new | past | comments | ask | show | jobs | submit login

Someone correct me if I'm wrong, but I believe this was the genesis of client-side prediction for games.

If you don't know what that is, Valve has some good documentation on it (relating to Source engine, but it's the same concept).[1]

Latency was still a problem even with CSP because we didn't yet have lag compensation on the server. So although you got an authoritative server (no cheating) and instant inputs (no round-trip wait), you could still shoot someone on the client and miss them on the server. You had to shoot ahead of them, further if your latency was worse. As far as I know, Source engine was the first to add lag compensation, which has the server rewind the other players to be where you would have seen them on the client.

Since client-side prediction can be performance intensive, and lag compensation can be difficult for anything beyond simple raycast checks, many games still don't do both. Team Fortress 2 for instance does lag compensation on basic guns but not on things like the soldier's rocket or the pyro's flamethrower. Some games simply allow the client to decide who they hit, which removes the need for either solution, but totally opens things up to cheaters without some very careful server-side validation.

[1] https://developer.valvesoftware.com/wiki/Latency_Compensatin...




Source may have been the first engine to formally support lag compensation on the server side, but something similar was already implemented previously as a mod for Quake 3 called "Unlagged". Essentially what it did was maintain a buffer of all player positions over the last X number of milliseconds and whenever a raycast check needed to be done, it looked back in that buffer based on the current ping of the player requesting the raycast.

There is still some documentation left on the internet: https://www.ra.is/unlagged/faq.html https://openarena.fandom.com/wiki/ModCompat/Unlagged


dm17 unlagged instagib. good times.


The engine for the first Halflife was a customized and modified version of Id’s engine, so originally they shared not only some principles but also code.

“GoldSrc is a game engine developed by Valve Corporation, first showcased in the 1998 first-person shooter game Half-Life. Elements of GoldSrc are based on a heavily modified version of id Software's Quake engine. “

https://en.wikipedia.org/wiki/GoldSrc


I searched the entier HN article and everyone missed a big paper, the tribe networking model: https://www.gamedevs.org/uploads/tribes-networking-model.pdf

This is one of the most influential paper for multiplayer games. ( probably #1 ). Tribe was the first game to have client side prediction and rollback, this is what most games use nowdays.


Related note: you can download and play any of the classic Tribes games from https://www.tribesuniverse.com


Here's my humble contribution to provide a clearer explanation, and a simple live demo with source code, of client-side prediction, entity interpolation, and server reconciliation: https://gabrielgambetta.com/client-server-game-architecture.... It's a relatively popular alternative source to Valve's (excellent) documents.


The Wikipedia page has a link to a thingie that says Duke Nukem 3D had clientside prediction.

https://en.wikipedia.org/wiki/Client-side_prediction


I clicked your link and at first kind of brushed it off as dubious since the only linked source is a press article, but the article is an interview with Ken Silverman himself! So that's pretty credible.

The source of the released game is available, so it should be possible to check, except that it's a huge mess (check out BUILD.C).[1]

Seems weird that no-one has actually verified this when it could be the first game ever doing CSP. The only other sites I can find mentioning it are just quoting your linked Wikipedia page.

[1] https://github.com/videogamepreservation/dukenukem3d


I have no idea how I remember this, but there's a write-up about the Age of Empires netcode (written ~96, released end-of-97): https://www.gamasutra.com/view/feature/131503/1500_archers_o...

Because of the unique challenges, they did a lot of synchronized client-side simulation (based on minimal state transfer over the net).

... and apparently encountered a lot of the issues with doing that (no random anything!!!).


This isn't the same as client side prediction though, the entire game simulation in the aoe case practically runs on every client, where the only input to the simulation are commands that are passed between all players and executed in lockstep, where the simulation essentially stops if for a given turn no command for that turn has been received.

Gives you really low bandwidth reqs (and randomness is still possible assuming you just seed things the same on all machines).

But also means you might have to wait 50-200ms (or some arbitrary sliding window depending on network conditions) until your click actually registers ingame as a move as commands are scheduled to be processed far enough in the future (some number of command turns in the future) that you at that point would have received every other players commands for that given turn and thus be able to execute all commands for all players locally for that turn, which is not ideal if you're playing a twitchy shooter, but alright if it's an RTS.


Here's the quote for those who don't want to deal with the bizarre pressreader interface:

In fact, in some ways Build had even managed to scoop Quake, according to Ken: "People may point out that Quake's networking code was better due to its drop-in networking support, but it did not support client side prediction in the beginning," he explains. "That's something I had come up with first and first implemented in the January 1996 release of Duke 3D shareware. It kind of pisses me off that the Wikipedia article on 'client side prediction' gives credit to Quakeworld due to a lack of credible citations about Duke 3D."


TIL Ken Silverman was 18 freaking years old when he started working on Build.


I feel a bit mean to all involved in linking this but at the same time it's an extremely interesting piece of history; check out GEORGE.TXT, found in a leaked alpha version of Blood (another Build engine game): https://tcrf.net/Proto:Blood/Alpha_Demo#GEORGE.TXT


Damn. Well, that _does_ sound like something a 18-year old would do!


in GAME.C

domovethings()

fakedomovethingscorrect()

fakedomovethings()

getpackets()


Wow, there it is!


Yeah probably. JC created a lot of standards for the ones to follow. And I remember reading the valve stuff the first time, it blew my mind.


The Valve docs there are very well written. It was the first time I really understood all the concepts too.

Overview of Source engine networking: https://developer.valvesoftware.com/wiki/Source_Multiplayer_...

Ways they combat latency: https://developer.valvesoftware.com/wiki/Latency_Compensatin...

Lag compensation (server): https://developer.valvesoftware.com/wiki/Lag_compensation

Prediction (client): https://developer.valvesoftware.com/wiki/Prediction


Any idea why the would not implement lag compo for projectile-based weapons? Too much processing power required?


I think the effect on other players would be pretty jarring, especially if said projectiles / explosions jolted players in the air at high velocity.

IIRC QW's client side movement prediction didn't attempt to predict the effects of, for instance, shooting a rocket at your feet/rocket jumping, which meant on high latency connections there'd often be a bit of a delay before your view caught up with where the server thought you actually were. This also applies to rockets fired by other players. Lower latency had the effect of not only making it easier to fire rockets at enemy players, it also made everything seem smoother when people fired rockets at you.

Later versions of QW created from the GPL source release have introduced lag compensation for hitscan weapons, but I'm not aware of any attempts to do so for projectiles.


lag compensating projectiles on the client decreases usability more often than you'd think.

Projectiles like rockets apply a lot of forces to the player which are not easily predictable. If you fire a rocket and client-side prediction has it leaving your vicinity without collision but the server has someone stepping into the path of the rocket so it explodes close enough that the explosion exerts force that changes your position, you're going to have a really bad misprediction on the player's position, which of course can get waaaay worse if the player launches another rocket while the first rocket's effect on player position has not been sorted out properly.


When you aim someone and click you want to hit what you see. This is a big problem with lag compo, you are in the present but you see other players in the past. In order to avoid this behavior, a common practice is to send what you see, your target, when you shoot.


Projectiles are simulated on the server


All weapons are simulated on both the server and the client in the case we're talking about here. It's just that raycast weapons are rewound on the server to compensate for the client's latency, and projectiles aren't. The server has the authority on actual hits and damage done for all weapons.


But why is it called prediction? It's not predicting the future, it's simply simulating the present! Is it because the client is "predicting" where the server thinks the player should be?


Basically yeah.

The server has the authority on where you are, to prevent you cheating by sending it bogus positions. You send inputs (not your position) and the server gives you your new position back.

Problem is of course it takes time for the inputs to go to the server, and for your new position to come back. So in a naive implementation you press to move forward, and don't actually move for a while while you wait for a return signal.

So instead, say it's tick 100 on the client and you get a position from the server marked as tick 90. Instead of moving the player to the tick 90 position, which is in the past for you, you take that and "predict" ahead (a.k.a. run the simulation) 10 more ticks to get to tick 100. Including re-running any new inputs you did during those ticks.

There are situations where the client may predict differently to what the server actually does - maybe you bumped into another player and due to latency they were in a different place for you than for the server. In that case you'll either get suddenly teleported to a different place as the server data keeps coming through, or if you're lucky the game will kind of smoothly correct you over a few frames.


> Is it because the client is "predicting" where the server thinks the player should be?

Yep


Predicting it, because it only knows the facts up to ~200 milliseconds in the past.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: