Warning, wall of text below
some terms are used interchangeably here. P2P assumes non-lockstep p2p. The issues with lockstep are those of scalability and necessity of determinism of game logic.
We’ve covered quite a complex topic without going into a lot of details. A number of the suggested solutions here only address one part of the issue, whilst introducing new problems that compromise their effectiveness.
Clients need to be dumb for as long as we cannot guarantee the following to be true:
- All data that the server / clients handle originated from the code written by the developers, on the machines represented by the connection.
- All data is sent as soon as it is generated.
At the present time, we cannot make such assumptions when writing networked games. The passage below is written with the assumption that you consider network security to be of concern.
The issues you describe are that of latency. Latency will always be a problem for games that require realtime parallel simulations. The issues addressed by different network models only hide the latency where it can be hidden with rare user-observation, sometimes by introducing latency that looks deliberately a part of the game mechanics.
Let’s first consider the Descent model. All data relating to player state is generated on the client representing that player. This means that the client is the authority on the actions of the player which may involve other players. There are a large number of means to manipulate the state of the player to give them an advantage over other players:
- Write simple application to determine valid hit vectors to target other players, and send attack information to the other members of the simulation.
- Disable physics collisions for the player model and negate the impact of terrain geometry upon the movements of the player.
- Remove limitations such as ammunition count, weapon unlocks, weapon range, visible obstructions like smoke, upon actions of the player.
There are so many other means of cheating but many are described by the above bullet points. All of these modifications are possible because the client’s total authority on anything relating to the state of the player. To be fair, the clients wouldn’t even be cheating, because how can you cheat if you’re just playing by your own rules?
Now, Talon. This is a common tradeoff for security issues, because it reduces the set of possible state modifications to that of player location, delta location and delta of that (i.e position, velocity, acceleration). It is possible to relatively carefully prevent absurd movements like flying and speed modifications, but other more precise forms of cheating are difficult to detect without knowing the inputs used to produce the movement. If the player’s movement options are extensive, this accuracy of detection falls.
Before we look at the solution most commonly used, let’s identify one of the issues with these models. Giving the client the authority over their state in order to avoid waiting RTT for move confirmation does not reduce the influence of latency from other players. This means that players will still see other players at different positions depending upon the latency from the source to the target. Methods such as extrapolation can only somewhat alleviate this. If two players are looking at one another, and they each move forwards at the same time, they both will see the other player in the past, idle. In a dodging example, by the time you fire a missile at another player, they may well have already moved.
In p2p networking, this is difficult to resolve, because player’s cannot accept the concept that the game state is not running in realtime, in parallel. These conflicts represent fundamental issues with the influence of latency upon games, and so the designer has to introduce a means of simply saying, tough. Now, in server-hosted games, it’s easier to resolve. The server manages resolution of such actions, and whilst it still doesn’t remove the problems caused by latency, the server can produce more consistent consequences when conflicts arise. Getting “shot around a corner” is still a pain in the ass, but it’s something players can deal with, much more so than being shot from the other side of the map by invisible players, and leading by latency varying per player. With a client server design, the latency issues are consistently resolved according to the single latency to/from the server, and you have a single, referenceable game state.
Game networking is relatively young as programming is considered, as even is the internet. In fairness to Descent, it was published in 1994-1995 before QuakeWorld, the game which changed game networking. The original Quake used a client server design, but didn’t consider the issues that plagued most people’s internet connections. Quake was predominantly resigned to LAN games, because it required consistent, low latency connections for consistent and enjoyable game play. Given that broadband was a very novel concept for the majority of internet users at the time, this wasn’t possible over remote networks.
QuakeWorld introduced the concept of prediction. It removed the cleanliness of a pure client server model, whereby only the server has any knowledge of the game state, and clients send inputs and render graphics. Prediction is implemented in different means for different use cases, but typically it requires that the client simulate the game as though it were the authority on its own state. It sends the results to the server, which then performs the same calculations, and compares the two states. This way, the entire client state is derived from the server simulation, apart from the raw inputs themselves, but the client is able to move without waiting for the reply from the server. If there are differences between the server and the client state, such as a players moving in the path of other players on the server, the server has to correct the client to account for this change. Hence, it replies with a correction which sets the state of the player. However, this state represents the client’s state at time T (now) - round trip time. So, rather than directly setting the existing state to the corrected state, which would always introduce jarring transformations, the clients resimulate by applying the successive moves to the state that was received and producing a new state for time T. This will still result in visual discrepancies in the case of collisions, but the client will receive the colliding player state at the time of receiving the correction anyway, so it becomes apparent that it would have in fact collided. This correction is unavoidable, and would otherwise manifest itself in the inconsistency of two player’s simulations, i.e other players would keep running into you and keep trying to move until the data from that client reflects the fact that they see you.
As soon as you start considering writing sanity checks for client state, the entire simulation becomes more and more bloated with unnecessary code. Whenever you add a new feature, the first question needs to be “How could a client abuse this feature?”. For P2P, the clients start looking more and more like servers, except that they have to communicate the results of these sanity checks with the other clients. And what happens if one client is cooperating with another to benefit one another by providing false sanity check results? For server designs, your server starts looking more and more like an authoritative server. Except, now you’re writing multiple implementations of features rather than a single reproducible one. You start adding more and more checks which would be provided by default using an authoritative server model.
To be clear there are two parts to this discussion. We’ve just discussed the security aspect, there’s also lag compensation, which is what you’re more interested in. This isn’t a result of how clients send data, but how the server handles it. Typically, lag compensation is easier done with authoritative servers given that they have a greater notion of state at any given time.
With Talon vs Descent, Assuming descent is pre-quakeworld, and therefore pre lag compensation, Descent favours low ping players whilst Talon is more balanced. Descent demands that you be able to determine the offset of your shooting, your lead, due to latency before you fire, which inevitably means missing several shots for more lagged players. With lag compensation, Talon rewards accuracy of shooting as one might expect in a shooting game, but introduces the possibility for players to be “shot around corners”. This is still possible without lag compensation if hit detection is done client side anyway. However, it still rewards low ping connections with winning a firefight because they see the other player first. Lag compensation addresses accuracy, not responsiveness.
Valve spends quite a lengthy paragraph explaining why they thought Lag Compensation was a worthwhile investment for Half Life here.