Time Playing

Hi all,
I am working on an hourly reward for my game, which will reward 1 gem (game currency) , and I want it to keep the timer even when the player closes the game. So for example, if the player plays 30 minutes, closes the game, and then goes on again, the timer will continue from 30 minutes.
To achieve so and test if it’s doable, I am using playerprefs and realtimeSinceStartup but I am currently having a problem with the saving part. It saves the timer value but it’s different than what it should be, and sometime it even goes “back” in time (if I saved 20 secs, and I start again the game, goes back to 15 for example).
Here the code (don’t mind the Z before PlayerPrefs, is just an encrypted playerprefs) :

public class TimePlaying : MonoBehaviour
{
    public static float timePlaying;
    public static float realtimePlaying;
    public static float totalTime;

    public void Start() //the code runs at the menu scene, when you open the game. The values are used and updated on another scene to make a button interactable/non interactable.
    {
        timePlaying = Time.realTimeSinceStartup;
        print(timePlaying);
        realTimePlaying = ZPlayerPrefs.GetFloat("timePlaying");
        totalTime = realTimePlaying + timePlaying;
        print(totalTime);
    }
    public void OnApplicationQuit()
    {
        ZPlayerPrefs.SetFloat("timePlaying", timePlaying);
    }
}

In what way is the data (that is not just in the past) different than what it should be?

Maybe set the floats regularly and call ZPlayerPrefs.Save() from time to time so data doesn’t get lost by potential problems when quitting.

That’s not the matter.
I don’t quit the game with any weird behavior that would lose the playerprefs.
Adding ZPlayerPrefs.Save() doesn’t make a difference to the weird behavior it has atm.

Now that I look at it more closely, you don’t actually increase the time anywhere, you only set timePlaying once in start and then save it when you quit. So timePlaying only represents the time that elapsed between starting the Application and Start being called.

Ok, I solved it. I wasn’t calling the OnApplicationQuit on all scenes…ahahaha, that was the problem XD
Sorry guys.
EDIT : One more thing, I was also setting the new timer as playerpref, so obviously playerpref was getting a lower base if I just started and quitted game without playing much.

That’s not it. Using → Time.realTimeSinceStartup → makes the time increases by itself, even if you chance scene. On the scenes where I need the timer it will always get updated on start. Thank you anyway :wink:

Now it works =)

public class TimePlaying : MonoBehaviour
{
    public static float timePlaying;
    public static float realtimePlaying;
    public static float totalTime;

    public void Start() //the code runs at the menu scene, when you open the game. The values are used and updated on another scene to make a button interactable/non interactable.
    {
        timePlaying = Time.realTimeSinceStartup;
        print(timePlaying);
        realTimePlaying = ZPlayerPrefs.GetFloat("timePlaying");
        totalTime = realTimePlaying + timePlaying;
        print(totalTime);
    }
    public void OnApplicationQuit()
    {
        //ZPlayerPrefs.SetFloat("timePlaying", timePlaying); //here the error
        ZPlayerPrefs.SetFloat("timePlaying", totalTime); //fixed version
    }
}

So it was an quitting problem after all!

If you’re only setting it on the start of the scene though, you might as well save it at the same time. Then quitting wouldn’t be an issue anyway.
It’s not being modified anywhere else as far as I can see anyway and you’re not losing any performance because SetFloat doesn’t directly write to disk.

[edit]
Well, now you are saving totalTime in the new edit. So it was actually what I said in my post. Not increasing/saving the correct variable. :stuck_out_tongue:

Also I’ll drop my 2 cents in here and say that you shouldn’t save only in OnApplicationQuit. I see at least 3 problems with OnApplicationQuit:

1: The app could possibly be closed without OnApplicationQuit being triggered, which would lose progress.
2: If the player switches to another app and has enough RAM to keep the game open, it’ll still count as play time. This would lead to abuse of the system as people with 4+GB RAM devices would just keep the game open in the background and farm gems while doing something else.
3: On Windows Store Apps and Windows Phone 8.1 there’s no application quit event.

I’d run a coroutine every minute, along with adding OnApplicationPause to do the same as OnApplicationQuit.

1 Like