The way of re-positioning other players in multiplayer racing game?

Started by
3 comments, last by hplus0603 2 years, 2 months ago

Hello everyone, I'm currently making multiplayer racing game using bullet physics engine.

The process of updating player position in my game is..

  1. Update and simulate client side physics engine independently, and just send key input to server.
  2. Server receive key input and update world, simulate server side physic engine, and send position to all players every one second.
  3. Client gets new position of all players. If current position of player and the new position differ a lot, correct player's position using interpolation. (interpolating speed is faster than game time)

The problem is that the other players doesn't change vehicle components. Player controlled by user keeps getting key input and changing vehicle components and apply it to physics world, so no problem.

There's no way that client knows changes of vehicle components of other players.. so it will be just stopped most of the time, and moves(interpolate position) only when packet arrives.

So how do I can update other player position? Should I interpolate slowly for other players and makes it move all the time or consider sending vehicle component through network when player pressed key?

Advertisement

Generally, when a player keeps the gas down, they will keep it down in the next frame, too. Similarly, when a player turns right, they will keep turning right next frame. You should also pack updates for many frames into a single packet – If you simulate at 240 Hz, but send packets at 60 Hz, there will be inputs for 4 simulation frames in each packet (and perhaps a few more, to cover the case when one packet may be dropped.)

“once a second” is way too infrequent. Even modem games in the 1990 sent updates 10 times a second, and common games these day send 30 times per second. 60 times a second is not entirely uncommon for action games.

You'll typically forward extrapolate the state by assuming the input stays the way it is across frames. Then, when receiving the next update from the remote players, if the input was different, rewind time for their car, and apply the new input, and simulate forward to “current time” on the viewing client. You will likely also have to interpolate the display position of the client vehicle compared to the received, new calculated position, so there's not too much sideways sliding.

Another way of interpolating forward is to use whatever code you have for game AI drivers (if you have any) – assume the player will give commands to follow the track, so when they go into a turn, start extrapolating as if they're turning into the turn, which may get you slightly closer to reality once it arrives.

Finally, if you do input synchronous simulation, that can work – most RTS games do this – but it is very sensitive to any single calculation error. Rounding mode is different on one machine because the printer driver changed it in a display hook callback? That machine will simulate differently than the rest. Thus, you'll also want to send occasional snapshots of the vehicle position/velocity/orientation/spin so others can match it up. If bandwidth is a problem, you only need to do this a few times a second, but these days, bandwidth at that level isn't a big deal – sending 60 full physics state updates per second is only about a kilobyte a second per player.

enum Bool { True, False, FileNotFound };

hplus0603 said:
Generally, when a player keeps the gas down, they will keep it down in the next frame, too. Similarly, when a player turns right, they will keep turning right next frame. You should also pack updates for many frames into a single packet – If you simulate at 240 Hz, but send packets at 60 Hz, there will be inputs for 4 simulation frames in each packet (and perhaps a few more, to cover the case when one packet may be dropped.)

Thanks for the answer. I appreciate it.

I'm not really sure but, do you mean server should send previous 5 frames of position/rotation of player 30 times per second?

That's one way of doing it, yes.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement