Deterministic behavior when multiplayers joining / leaving

Deterministic behavior when multiplayers joining / leaving

So I am trying to make a game that relies heavily on physics. It is a multiplayer game, with a server, and players can join/leave the game at any time. To ensure everything is deterministic, everytime someone joins the game, I have to get every player on the server to recreate the physics world again, so that everybody is starting from the same point again, because as far as I am aware, even if you create a snapshot of a running world, a world created and run from that snapshot will not be deterministically the same as the already running world. Is there any way around this? Is there any way to give some sort of snapshot of an already running world to someone and have them run it deterministically?

5 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

Short answer: no

There are so many factors that go into determinism (not just contact points, but ordering of bodies and a whole bunch of other stuff that doesn't serialize) that the only way to be sure two simulations will run exactly the same is to construct them with the exact same initial conditions on each machine.
This means (as you've mentioned) destroying everybody's world and reconstructing them all with the same snapshot.

Typically the solution for multiplayer like this, where players can drop in and out at will, is to run all the gameplay physics on the server and send the results to the clients as keyframes.
Non-essential stuff like debris can then be done on the client side.

Cormac

Thanks for the info.

If you haven't already, check out the Physics Manual, Chapter 4 Optimizing the Simulation, Section 2.5 Maintaining Determinism.

Also, here's the official line from our knowledge base:

There are two key types of state (apart from initial setup info) needed to reproduce a simulation in a fully deterministic way:

  1. Object motion state (e.g. position, rotation, linear and angular velocity)
  2. Internal collision data (cached contact points, contact manifolds, collision agents)

At
present we can allow the saving and restoring of the first type of
state. However, this is not enough to guarantee absolutely deterministic
results because Havok simulations currently use this internal (cached)
data to help with speedy and stable resolution.

It is
possible to recreate the state by starting from a known state without
any of this cached data (e.g. the start of the simulation) and stepping
in exactly the same way.

Note
that Havok is not deterministic across platforms, nor is it guaranteed
deterministic across PCs with different processor types, nor can we
guarantee determinism between debug and release builds. This is mainly
due to floating point accuracy differences.

On
Intel/AMD PCs Havok does not use any processor specific extensions.
Several clients have informed us that this implies that the code will
run identically on all processors butthis has yet to be fullytested
and confirmed by Havok.

So you may in theory run into problems even when restarting all clients from the same snapshot - if they have different processors. It's possible to ensure that all the clients' floating point operations are the exact same by making sure to stick to the IEEE754 standard [by calling _controlfp].

You'd also have to be careful when using certain functions like sin and cos, as they may give different results for different implementations or compilations of maths libraries.

It seems the simplest way to be really sure everybody's on the same page is to have one authoritative simulation running on the server, and send out the keyframes.
Of course, for a large world that requires sending a lot of physics state over the network, rather than just the player inputs.

Either way, it's nontrivial.

Cormac

Recreating the world to ensure determinism is doable, and the solution that I've gone with for now. The main reason for this is that the game relies rather heavily on physics interactions and there would be a lot of bandwidth from sending every object around all the time. In terms of processors being the same, I guess I'll just do my best to ensure there are not any tricks there- if it works fine on Intel / AMD, I'm fine with that, I'm only building for windows anyway.As a side note, is it possible (or would it maybe be possible in the future) to clear the cached internal data without recreating the world? That would be quicker than recreating the entire world and give an easy way to send a deterministic snapshot. Maybe something to consider in the future.

Faça login para deixar um comentário.