1
\$\begingroup\$

I'm making a game that needs to save total played time into file (using JSON) for comparing & resolving data conflicts between local and cloud. I will override outdated one.

Currently, I'm just adding Time.realtimeSinceStartup, but is that okay? What if the time is really, really big and couldn't be handled in Unity anymore? Could that eventually happen?

If so, what are some alternatives?

\$\endgroup\$
  • 1
    \$\begingroup\$ Unless someone plays around 50000 days, you'll be fine \$\endgroup\$ – Bálint Mar 28 '18 at 9:59
  • 1
    \$\begingroup\$ Do you have more than one savegame? \$\endgroup\$ – Philipp Mar 28 '18 at 10:23
  • 1
    \$\begingroup\$ How much precision do you need in the comparison? (also, you are storing json, how much precision are you storing?) Edit 1: depending on that, it could be reliable for a few months before floating point rounding errors start causing problems. Edit 2: perhaps you should ask the cloud for a timestamp, that is an alternative. Edit 3: In what case should you trust the local version anyway? I mean, that just opens a door for cheats. \$\endgroup\$ – Theraot Mar 28 '18 at 10:25
  • 1
    \$\begingroup\$ @modernator that is full precision for a double (you count the decimal digits, there should be 17). So no need to do anything. Most of those digits are not significant, because normally you do not have clocks that count in less than a nanosecond - regular system clocks update at a few milliseconds. That is the abstract of the rounding error too: The bigger the values, the less decimals you have. Eventually you start losing significant digits. After ~104 days you lose nanosecond precision, which is important for real time systems, database sync, et al. But I doubt it will be a problem for you. \$\endgroup\$ – Theraot Mar 28 '18 at 12:20
  • 1
    \$\begingroup\$ Just to be clear, 17 counting before and after the decimal separator. So, if you have 2 digits before (28), you have 15 after (849559783935548). I also want to note that his is just a shorthand, the actual precision is defined in binary digits. \$\endgroup\$ – Theraot Mar 28 '18 at 12:25
4
\$\begingroup\$

Floating point precision is unlikely to be the problem here.

Since you're not trying to coordinate simultaneous use, but just determine which of two sequential sessions came earlier/later, you'll generally be looking at differences in timestamps of minutes, not milliseconds.

Even a single precision float can keep precision to one second for about 33 million seconds, according to the precision table I worked out here, and that's a little more than a year of continuous play. Probably safe unless you're making an idle game that you expect players will keep running unattended 24/7.

You do get inaccuracies from adding floats together, especially if they're very different in magnitude, so don't increment your total playtime using deltaTime every frame — accumulate it in chunks when you save. You'll still lose time to imprecision here, but again your precision needs are so low that it's unlikely to add up to anything impactful.

So no, this doesn't appear to be unsafe from a pure precision point of view. The problems you need to solve are likely to be elsewhere.

For instance, if I load my save on two different devices A and B, then play B offline for two days before syncing it to the cloud. Then play A offline for three days before syncing it to the cloud. Now A's total time played is more than the 2 days I'd previously synched to the cloud, so the server overwrites my B save with A. Is that the desired outcome? Should your game detect and warn the player of this branch in the save history before synching?

\$\endgroup\$
  • \$\begingroup\$ Thank you for detail explanations. I'd better to think about conflict between multiple devices. \$\endgroup\$ – modernator Mar 28 '18 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.