0
\$\begingroup\$

So, I am currently working on an RTS-like multiplayer game. Units are not controllable by players (they attack-move to a location automatically).

I decided not to go full lockstep but instead do a state-based / prediction hybrid. The game is fully simulated on the client with a state packet for every unit distributed only once per second (Position, health etc.). I've read that this is quite a common method of doing things these days but i'm having major issues with it. One clear problem is with health syncing. Damage is dealt locally on every client machine and corrected via the state packet. This results in issues similar to this:

  • Projectile hits a unit on a client machine, taking him from 100 health down to 50.
  • Client only then receives a state packet from the server saying he is on 100 health which spikes it back up.

Of course he will receive another corrective packet later on taking him back down to 50 but this causes really bad visual spikes. This issue gets even worse if you consider the impact of ability damage and such.

Have I completely misunderstood what is required to create a client-predicted game or do I just need to treat every variable on a case-by-case basis? (I.E. Put in silly hacks to make the health not look bad).

\$\endgroup\$
1
\$\begingroup\$

Client prediction can be implemented by having:

  • A known state: unit statistics and timestamp for when this state applies
  • Events: actions which modify the known state. They also have a timestamp so we can order them

You client works by receiving states from the server, and then predicting the current state by applying the events that come after the state's timestamp.

Let's have an example moving through time:

T0: Initially
  Known state (100HP @ T0)
  Predicted events: []
  Predicted state: (100HP @ T0)

T1: Client simulation preditcs a hit for 35dmg
  Known state (100HP @ T0)
  Predicted events: [35dmg @ T1]
  Predicted state: (65HP @ T1)

T2: Client simulation preditcs a hit for 10dmg
  Known state (100HP @ T0)
  Predicted events: [35dmg @ T1, 10dmg @ T2]
  Predicted state: (55HP @ T2)

T3: Client recieves a new state from the server, 65HP at T1
  Known state (65HP @ T1)
  Predicted events: [10dmg @ T2] // Here we removed events that happened at or before T1
  Predicted state: (55HP @ T3)

T4: Client recieves a new state from the server, 55HP at T2
  Known state (55HP @ T2)
  Predicted events: [] // Here we removed events that happened at or before T2
  Predicted state: (55HP @ T4)

I know it's a bit vague, but I hope it can help you retool your predictions.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.