Help with GetGroundState During Reconciliation (Client-Server) #1137
-
Hi I'm working on a client-server setup using jolt physics, I'm implementing client prediction and server reconciliation, but I have the following problem: On the client we have a character->GetGroundState() == JPH::CharacterVirtual::EGroundState::OnGround is not true. After a very short amount of time, an authorative state comes in from the server and we first do: client_physics_character->SetPosition(authoriative_position);
client_physics_character->SetLinearVelocity(authoriative_velocity); and want to re-apply the input-snapshot that caused the player to jump, but the thing is: character->GetGroundState() == JPH::CharacterVirtual::EGroundState::OnGround Still evaluates to false because of our client predicted jump, and so no jump occurs (a jump only occurs if that condition is true). Since more input snapshots were captured since the first jump input snapshot, then we go on to re-apply the next input snapshot on the authorative server position/vel and the jump does happen on the next input snapshot (space is still pressed) and this is bad because the jump occurs on a different input-snapshot as compared to what happened on the predicted state causing jitter in-game. During reconciliation we apply any input-snapshots that occurred on the client on top of the authorative state, between each input-snapshot application we do the following: character->SetLinearVelocity(convert_vec3_from_glm_to_jolt(updated_velocity)); and character->ExtendedUpdate( ... ) are made in that order. What I tried The source code for client_physics_character->SetPosition(authoriative_position);
client_physics_character->SetLinearVelocity(authoriative_velocity);
character->ExtendedUpdate(0.01, ...); Which seems to fix the ground problem, but introduces the new problem that the authorative position and velocity are simulated a bit before we start the reconciliation which leads to jitter in-game. Are there any other better ways to simply update the ground state of a character virtual without having to do an update? I also thought that maybe using I also found that inside // Determine ground state
if (num_supported > 0)
{
// We made contact with something that supports us
mGroundState = EGroundState::OnGround;
} So I'm curious to know if doing something a call to |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
I think Doing The simplest thing to do would be to not replicate input, but the results of the input. If the server detected that the player was able to jump then send a 'jump' bit instead of a 'space bar pressed' bit. That way it doesn't matter what the ground state is on the client. |
Beta Was this translation helpful? Give feedback.
I think
RefreshContacts
should mostly fix this issue as it runs collision detection again and updates the ground state, however it is not 100% the same thing as callingExtendedUpdate
as this can also detect contacts that you touch during the update (but don't end up touching at the end of the step).Doing
SaveState
at every time step and rolling back to that state usingRestoreState
is the official way of doing things, but it does require that the state of all physics bodies is also rolled back (e.g. if a body that you were touching has been removed since the lastSaveState
call thenRestoreState
will not be safe).The simplest thing to do would be to not replicate input, but the results…