Best practice for keeping track of a variable in real-time?

I first posted this question in the iOS forum, but didn’t get much feedback, so I wanted to try here.

I’ve got a game that wants the player to come back all the time. So there’s a health bar that is always decreasing, say, by 1 point per hour. How would I go about keeping track of time, in real time?

So say the game is turned off overnight, in the morning, they will have 10 less health, or if they leave it for a week they’ll be dead.

any idea’s on how to do this in a stable fashion?

  • sanity checking.

This should help you. Haven’t tested, but it looks good.

http://forum.unity3d.com/threads/19117-Date-Time-check

Just as a side note, there’s a cheat people use on Tiny Tower to progress faster by changing the date back and forward, so you may want to check for this to prevent cheating in your game :slight_smile:

Sorry, been away for a few days, thanks for your answers guys.

By the way, freakin love tiny tower, mine is about 45 stories tall now. And I’m not worried about cheating, they’d only kill their character faster. Although you’re right, I will have to sanity check that it doesn’t freak out if they change the clock BACKWARDS…

So, umm, next vital question along this line, when and how do I query the time?

During gameplay I would query it in update(), but how do I know when the player has switched to another app and back again, or had a phone call, or lost power to the device? is there an awake() method or similar?

I’m assuming I would store a copy of the “current time” in the player prefs, but how would I keep that data always up to date, like, if the phone loses power, especially if the app isn’t currently running. Would I need to be writing the time to the playerPrefs constantly? That seems rather wasteful.

This is what I meant by “best practices”.

I’m a little confused and apprehensive about moving forward without some advice or direction.

Thanks guys

What are the realistic risks, and how much data are you prepared to loose?

For example, if for a worst case scenario (someone pulled the plug) your only willing to loose 15 seconds of data… then your saving the time 1/450th of times you would if you where doing it on the fixed update (@30fps).

Hi guys, I’ve found time to put my solution together, and it’s working perfectly!

So, I’m posting the code here for two reasons,

  1. PLEASE critique my code, this is the first time I’ve done a coroutine of any kind. Have I done it well?
  2. Feel free to use it if you’ve got a similar situation.
private GameObject statusText;

private int epochTime;
private int deltaTime;

void Start () {
	statusText = GameObject.Find("statusText");
	StartCoroutine ("saveTimer");
}

IEnumerator saveTimer () {
	while (true) {
		//I'm converting time to epoch, since it's shorter and easier to work with
		epochTime = (int) ((System.DateTime.Now.Ticks - 621355968000000000) / 10000000);
		deltaTime = epochTime - PlayerPrefs.GetInt("epochTime");
		if (deltaTime < 5) {
			statusText.guiText.text = "Game is running normally";
		} else {
			statusText.guiText.text = "Game was \"dead\" for " + deltaTime.ToString() + " seconds";
		}
		PlayerPrefs.SetInt ("epochTime", epochTime);

		yield return new WaitForSeconds(1);
	}
}

A different approach would be to just store the DateTime of ‘birth’ of the player and calculate the health as currentDateTime - birthDateTime. That removes the need for reading/writing to playerprefs every second or any problems about the game not running in the background as its always using absolute values.

If the player can gain health then you simply increase the ‘birth’ time to compensate, the benefit again being you’ll only write to playerprefs when they gain health and not every second like in the coroutine.