Hi everyone,
i'm having troubles syncing character movement(with charactercontrollers). i've read a lot of articles about how rewind/replay works for multiplayer games, and i think i basically understand the concept, but i run into a problem that i havent been able to solve for quite a while. My system works like that at the moment:
-) client sends movement input (e.g. timestamp: 100)
-) server stores the input + timestamp (100) in an array, and adds a "margin-value"(50) to the timestamp.
-) when the server-network time goes PAST the stored timestamp+margin value (150) the server accepts the received input and processes movement.
basically this works, yet, i do have a big problem: due to the fact that the player doesnt send inputs at a fixed timestep, the server never reaches the stored timestamp EXACTLY, but goes always past it, and therefore processes different inputs different long. those are just small values in the beginning, but they add up and become noticable quite fast.
any ideas/input/help on this would be REALLY awesome - i've been stuck on this for quite a while, and just can't manage to get it working!
PS: i try to avoid constant state-sync to reduce bandwidth. also i need the server to really "simulate" the inputs because of collisions, cheating, etc...
hopefully one of you network-gurus knows an answer .
cheers and thanks!
🎉 Celebrating 25 Years of GameDev.net! 🎉
Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!
Movement Multiplayer Sync (Rewind/Replay) (Authorotative)
Your simulation should be a fixed time step, and you should count "steps" instead of "seconds" or "milliseconds" or whatever.
The easiest way to turn a variable-rate game loop into a fixed-rate game loop is to accumulate a measure of how much time has passed, and call the simulate function more than once if more time has passed than a step.
Check out the canonical game loop: http://www.mindcontrol.org/~hplus/graphics/game_loop.html
If you both simulate and render in the same function, you'll need to disentangle that through some refactoring.
Thanks a lot for your answers.
What physics engine are you using? Unity, Unreal, and other game engines use non-deterministic physics engines like PhysX, which cannot run a lock-step simulation for various implementation reasons.
Thanks for the reply, maybe it didnt came out clear enough from my last post.
Maybe i should mention here, that i am using the Unity Engine.
i'm using the unity engine with the character controller component. actually the character controller is quite deterministic, since you move it not by applying forces, but by giving him a vector to move to. yet, when collisions occur, a desync happens SOMETIMES - especially with spherical collisions.
Thanks for the reply, maybe it didnt came out clear enough from my last post.
Maybe i should mention here, that i am using the Unity Engine.
i'm using the unity engine with the character controller component. actually the character controller is quite deterministic, since you move it not by applying forces, but by giving him a vector to move to. yet, when collisions occur, a desync happens SOMETIMES - especially with spherical collisions.
Unity's physics is neither deterministic nor repeatable, and they never claim that it is.
Of course, neither are the physics engines of most other big engines. You'll have the same problem on UE4, on C4, and the rest.
Unity (and also UE4) does not directly support a rewind/replay mechanic. If you want that you'll need to implement it. People have done it, it can be done, but it is not supported out of the box.
As part of that, you won't be able to use the simulator's physics engine and character controllers in the way they were designed. You'll have to override their behavior from time to time, forcefully setting items into positions the engine wouldn't normally do, forcefully setting physics values to something other than their defaults, occasionally teleporting items to their right space, and otherwise not using the default values.
You'll have to override their behavior from time to time, forcefully setting items into positions the engine wouldn't normally do, forcefully setting physics values to something other than their defaults, occasionally teleporting items to their right space, and otherwise not using the default values.
unfortunatly, thats what i thought. as for the approach i'm using right now:
When the Client changes his Input:
-) Client sends Input to Server
-) Client starts recording how often this input is executed (so called „ticks“?)
When the Client then changes his Input again, he sends the tick-count of the last input along with the new input.
What happens on the Server-Side in the meanwhile is, that the server replays the input delayed (based on the client-ping) and stores the „ticks“ he already processed for the input as well. When the client now sends a new update that includes the maximum „ticks“ of the last input, the server keeps executing the last input until the tick-count on the server reached the just received tick-count of the client.
do you think that this approach in general could work and be stable enough? or do you see some possible upcoming problems with it?
by following your advice and periodically correcting either the client or the server-position slightly, im quite convinced that i can sync the characters nicely... i'm just not sure if thats how it "should" be done, or if i'm missing something that could cause severe problems in the future?