I’m using Havok on both the client and server, and colyseus for communication. I’m also running a nullengine on the server with an exact replica of the client’s environment, and client’s mesh. The steps on the client are as follows:
When the player clicks any of the WASD keyboard keys, the physics movement is done on the client locally, and the same keys are sent to the server to perform the same physics movement. The code between the client and server for movement are identical. Fairly quickly, the server player and client player become desynced because the server player moves slower than the client. I’ve attempted to manually step through physics on the server side at a set rate, tried using the time between server updates as the delta for client movement. Can’t seem to get them to ever match. Anyone have any ideas?
Are you accounting for the latency between client and server? If not, the server player should be behind the client player, because the client can act on player inputs immediately whereas those inputs take time (latency) to reach the server.
Perhaps you are looking for Client-Side Prediction (to compare a server state with a past client state), and here are some great articles:
I think the problem is more that the server state never reaches the client state, because under the exact same conditions (same keyboard inputs, velocities, etc) the server player moves slower than the client player (and therefore does not ever reach the client’s position). I can hold the W key for 5 seconds, say, and the client and server player positions will be like 5 meters apart.
The only way I can get the server and client to match is by using a different client player speed than server player speed lol. Essentially if I set the client speed to be 1/100th of the server’s speed, then the positions will match.
I calculate the speed on both client and server like this:
// Get time delta
const delta = parseInt(this._game.gamescene.deltaTime / 1000;
// Calculate velocity based on the horizontal direction only
let velocity = direction.scale((input.speedMod ? this.speed * 1.5 : this.speed) * delta);
the gamescene.deltaTime that I am using is the time between server updates (I think this is correct).
Similarly on the server, I use the same code for speed calculation, but the deltaTime is the dt/1000 that I have specified based on the updateRate:
I believe you should try to make your physics simulation as deterministic as possible on the client and server. Try simulating at the same frequency with the same timestep on both the client and server.
Are there any examples that have successfully synchronized the client and server havok physics? And I don’t mean sending the player position from the client to the server after applying client sided physics. I can get the client and server to synchronize if I manually set the transformNode position (obviously). It’s the fact that setting identical linear velocities and forces give far different results.