Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

The importance of perfect synchronization

Discussion in 'Game Design' started by jtsmith1287, Aug 24, 2016.

  1. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    I want to get some feedback on some networking stuff. This isn't a technical question, but will likely need to technical discussion. For context, this is all referring to real-time action oriented games.

    To start off, sycning the player object as close to perfect as possible is very important, everyone knows that. But after that it seems like there's some hard falloff for how much people care is synced. The less the character is affected the more the client is allowed to handle the logic/physics, until eventually you get to objects that aren't synced at all.

    So where would you guys say this line is drawn? I know it's rather abstract, so let me give an example, and the reason I'm curious about this.

    I'm working on a 3D space shooter (I'm pissed at No Man's Sky), and I have asteroids randomly scattered throughout the scene. When my brother and I first connected he exclaimed, "You're flying through an asteroid!". Well, I wasn't on my end and I realized, duh, the client randomizes the asteroids. I need to sync that. But, those asteroids also rotate on their own. There's no physics on them since I don't want people shoving asteroids into space stations or whatever, so I figured I'd make them huge, and positionally-static.

    So, do I sync every single asteroid's rotation, or do I just start all clients at the exact same position with the exact same rotational parameters and let the client do the rest? Will CPU latency and what-have-you and long periods of time, will these asteroid's positions get really out of sync and how much are the player's going to care?

    I'm expecting to run into a lot of these kinds of issues (I've never done a multiplayer game before, can you tell?). Thoughts?

    Thanks!
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, the BIC (Big Important Concept) I'd like to share with you here is error accumulation, aka drift.

    I'll assume in your example that asteroids are odd-shaped, potato-looking things (as they are in real life... and fun fact, some movie asteroids were actual potatoes!). So if the rotation is significantly off between the clients, this will lead to obvious problems. But if the rotation is only a little off, nobody will notice.

    So, in cases like this, you need to look at how your rotation is done, and ask: will this get more off over time? In other words, can errors accumulate (build up more and more) until eventually they're quite significant? Or will the error stay small, no matter how long it runs?

    In theory, if you rotato your potato by multiplying a rotation rate by Time.deltaTime, there ought to be no error. Even if your clients are running and different frame rates, Time.deltaTime takes that into account. But in practice, you can't be sure that Time.deltaTime will always be exactly right. The frame time it reports may differ from the actual, wall-clock amount of frame time by a little bit. And if you're relying on that to turn your asteroid, frame after frame after frame, those little errors add up. Eventually my potato could be 90° out of phase with yours.

    Now consider a different approach. Instead of rotating by adding a small rotation to the current orientation on each frame, based on the delta time, we're going to just set the orientation of the potato based on the wall clock. Something like this:

    Code (CSharp):
    1. transform.rotation = spinPerSec * wallClockTime;
    where spinPerSec is the amount (and direction) of rotation to do per second, and wallClockTime is some measure of the actual time that we can depend on. Now, even if we let this run for 100 years, there is no error to accumulate — as long as wallClockTime is the same on both machines, then the rotation will be the same.

    "But wait!" I hear you cry. "You've just moved the problem! How can you be sure wallClockTime is the same?"

    But that's a much easier problem, because all computers have clocks in them that are darn accurate. They might not have the right time, but whatever time they have, they will keep with relatively little drift. Over the course of a typical game, you can probably assume there is no drift. But you can also exchange some checks and balances to account for any difference in drift between the master clock and the client clocks; and doing this for one thing (the official time) is much easier than for a zillion things (every vegetable in your game).