Advertisement

Other entity snapshot interpolation jitter issue (visual)

Started by August 31, 2024 11:43 AM
3 comments, last by hplus0603 3 months, 1 week ago

I am using proper snapshot interpolation to interpolate other entities such as players. I am also using CSP (with interpolation) for the local player's movement.

Right now interpolation is calculated using Time.deltatime for both. Snapshot interpolation works as expected; I have logged positions and viewed other player movement when locally just staying still. This seems like a visual issue only.

The issue is that when both players (local & non-local) move at the same time sideways, you can see the other player sort of jitter (video attached).

Is this a common issue? I have already tried debugging this for a long time so I am hoping someone could shed some light onto this.

ForeverCoder1526 said:
The issue is that when both players (local & non-local) move at the same time sideways, you can see the other player sort of jitter (video attached).

Architecture choices make a big difference here.

If both clients are communicating with a server, the star architecture means that the server gets each client's data, sorts out what happened when, then transmits the ‘true state of the world’ data back to each client. Each client then interpolates based on that. The true state of the world can shift depending on implementation, such as if the server has a mechanism to rewind and re-simulate, as some designs do. Every view gets the same types of correction being applied to them.

If one of the players is serving as a host then it will do its own processing for itself and need to take action to sort out what happened when. The host will have a different view from other players, with the host always having the true state of the world shown, but the other players will have some amount of correction being applied to them. This gives the host an advantage in several ways, in addition to causing differences between the host experience and everyone else's experience.

Be careful also that you're including in the state information the fact that they're in motion, with the expectation that something in motion is presumed to continue in motion. Often a source of state-update jitter is that items move to the position of last update and presume they're stopped there, so they get a stair-step effect ias they move from one update position to another update position instead of locally simulating as though the motion is continuous.

Advertisement

Hmm it looks like are multiple issues here.

1) when server is creating the world snapshot, it occasionally saves the same player position twice in a row, resulting in serialized player position being like (X, X, X+1, X+1) for subsequent ticks, but that seems to be fixed now since I adjusted when player inputs are processed.

2) for some odd reason, some frames the snapshot interpolation code moves the other entity (or player) a lot more than than the local player is moved (+ camera), and some frames the local player (+ camera) is moved a lot more than the interpolated entity. this makes it visually look like the other entity is moving quickly forwards and back (=visual jittering), when it should move close to the same speed.

Ideally my goal for #2 is to fully remove the jittering when the local and remote players move to the same direction with the same velocity. I did some benchmarking and it seems like this jittering happens randomly and only 30% of the time currently.

You need to snapshot position and velocity, and forward that. When playing back, you need to simulate using that same position and velocity. This will let you put entities in the “right” place no matter what the rendering frame rate is.

The draw-back is that you will render entities in positions that they aren't quite in, especially when there's fast turning involved, OR you need to delay the other entity until you've received snapshot X+1 before you even start showing snapshot X.

Some code that shows one of these approaches is available at https://mindcontrol.org/~hplus/epic

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement