0
\$\begingroup\$

I'm struggling with how to handle a particular situation in a prediction/reconciliation server model.

  1. At t=0, Player A is firing. Player B is moving into A's line of fire
  2. At t=1, Player B moves into A's line of fire and gets hurt, reducing health from 100 to 50
  3. At t=2, the server receives input from player B for t=1. That input confirms that player B moved into the line of fire, so the server responds with a packet for t=1 indicating that the player's health is now 50
  4. Player B receives this packet, and noting that health dropped, flashes the screen red.
  5. The server receives input from Player A for t=1, indicating that A stopped firing. The server rolls back to t=1, re-simulates, and realizes player B did not get hit.
  6. The next state sent to B indicates health=100.

How do I handle the fact that client B showed a red screen flash based on information received from the server, and then later found that they were not in fact hurt?

This sounds a bit like the situation of e.g. Source Games favoring the shooter. However, in this case, even player A did not think they hit player B on their own screen.

Can the server not send a state for t=1 until it has inputs from every player for that frame? That seems like it would cause a single latent player to slow down the experience for everyone else.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

That seems like it would cause a single latent player to slow down the experience for everyone else.

That's correct, it would, which is why you shouldn't do that.

In this case, I'd err on the side of showing feedback as soon as possible (if I might have an instant to save myself from death and get away with a graze, I'd like to know it!) and don't worry about harmless contradictions.

If I see my screen flash red, then a moment later I'd back to full health, yes, that's weird, but it's a nice surprise! And it's much better than all input/feedback from other players taking on extra latency, leading to more bad surprises (like "hey, you're already dead because you started taking damage 5 frames ago and I just got around to telling you).

This type of minor contradiction is common in shooters, where you'll often see a blood splat on a wall from a headshot that it turns out didn't really connect, and the character model keeps sprinting away unharmed on the next update. It's weird, but the more important signifier is "the enemy is still up and running" and players will attend to that over a little over-eager feedback.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks! What if, at step 3, the player's health had instead been reduced to 0 rather than 50? It would be pretty jarring for the client to show the local player dying, then coming back to life. I can ask as a separate question if that's too big for a comment. \$\endgroup\$
    – rcorre
    Dec 12, 2022 at 12:11
  • \$\begingroup\$ I'd recommend separating your "took damage" event from "confirmed local player kill" event. Let the player keep playing as a negative-health zombie for a moment, knowing that any game-affecting actions they take in that brief window will be cancelled/rewound by the server if it turns out they're really dead. Almost every time, this will be followed up by a confirmed kill signal a server tick later, and the player sees themself die "immediately" with the damage feedback from the previous tick blending the transition. But on rare occasions, the death cue never comes and they just keep playing. \$\endgroup\$
    – DMGregory
    Dec 12, 2022 at 13:17
  • \$\begingroup\$ That makes sense, thanks again! \$\endgroup\$
    – rcorre
    Dec 12, 2022 at 16:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .