How to sync physics in a multiplayer game?
Asked Answered
P

2

13

I try to found the best method to do this, considering a turn by turn cross-plateform game on mobile (3G bandwidth) with projectile and falling blocks.

I wonder if one device (the current player turn = server role) can run the physics and send some "key frames" data (position, orientation of blocks) to the other device, which just interpolate from the current state to the "keyframes" received. With this method I'm quite afraid about the huge amount of data to guarantee the same visual on the other player's device.

Another method should be to send the physics data (force, acceleration ...) and run physics on the other device too, but I'm afraid to never have the same result at all.

Pragmatic answered 30/11, 2011 at 10:15 Comment(4)
Wouldn't the objects have the exact same result on both devices if the objects have the same starting position and same phyisics data applied?Done
@Done only if you have a fixed tick time. This generally won't be the case if you update the physics on each graphics frame.Gill
Right Rob. I'm not sure, but problems should come considering cross-platform (different architectures) and floating point calculation, no?Pragmatic
You might want to have a look at Glenn Fiedler's excellent GDC tutorials (2011 and 2010) on networking for physics programmers. It does a much better job than I could put in an answer.Murat
G
11

My current implementation works like this:

  1. Server manages physics simulation
  2. On any major collision of any object, the object's absolute position, rotation, AND velocity/acceleration/forces are sent to each client.
  3. Client sets each object at the position along with their velocity and applies the necessary forces.
  4. Client calculates latency and advances the physics system to accommodate for the lag time by that amount.

This, for me, works quite well. I have the physics system running over dozens of sub-systems (maps).

Some key things about my implementation:

Completely ignore any object that isn't flagged as "necessary". For instance, dirt and dust particles that respond to player movement or grass and water as it responds to player movement. Basically non-essential stuff.

All of this is sent through UDP by the way. This would be horrendous on TCP.

Garrett answered 24/12, 2011 at 2:51 Comment(0)
M
6

You will want to send absolute positions and rotations.

You're right, that if you send just forces, it won't work. It's possible to make this work, but it's much harder than just sending positions. You need both devices to do their calculations the same way, so before each frame, you need to wait for the input from the other device, you need to use the same time step, scripts need to either run in the same order or be commutative, and you can only use CPU instructions guaranteed to give the same result on both machines.

that last one is one that makes it particularly problematic, because it means you can't use floating-point numbers (floats/singles, or doubles). you have to use integers, or roll your own number format, so you can't take advantage of many existing tools.

Many games use a client-server model with client-side prediction. if your game is turn based, you might be able to get away with not using client-side prediction. instead, you could have the client lag behind by some amount of time, so that you can be fairly sure that the server's input will already be there when you go to render. client-side prediction is only important if the client can make changes that the server cares about (such as moving).

Maillol answered 5/12, 2011 at 15:9 Comment(2)
By waiting for input for each frame, I take it you mean every physics frame?Rah
I mean every input frame, which could be 1-to-1 with physics frames, or not. it would be easiest to have input frames and physics frames be 1-to-1, but you could update physics twice every time you sampled the input, if you wanted to.Maillol

© 2022 - 2024 — McMap. All rights reserved.