0
Answered

When are saved variables set to initial state again?

Stefan Scholl 2 years ago updated by Lazlo Bonin (Lead Developer) 1 year ago 10

An app on iPad had saved state (settings, highscore) that was lost after installing a new version.

Isn't Bolt using PlayerPrefs? Shouldn't all data remain?

(Bolt 1.2.3)

Bolt Version:
Unity Version:
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):
Pending Review

Hi Stefan,

They are indeed saved to player prefs. What do you mean by "new version"? New version of Bolt, or of your built game, or of Unity?

Forget the "new version". The root to the problem is something else: Bolt isn't saving the Saved variables.

I had some data in the Saved variables and then quit the app on my iPad. After starting it again the data was gone. Seems that Bolt 1.2.3 isn't saving the Saved variables.

Installing a new version is quitting the running app, too.

If I see this correctly (Bolt 1.2.3) it's only saving inside OnApplicationQuit(). 

VariablesSaver.cs has OnApplicationQuit() which calls SavedVariables.OnExitPlayMode() -> SaveDeclarations(merged) -> PlayerPrefs.Save()

https://docs.unity3d.com/ScriptReference/PlayerPrefs.Save.html says: Note: There is no need to call this function manually inside OnApplicationQuit().

And before that: By default Unity writes preferences to disk during OnApplicationQuit(). In cases when the game crashes or otherwise prematuraly exits, you might want to write the PlayerPrefs at sensible 'checkpoints' in your game. 

I see, is there some well known hooks where the player prefs should be saved for iOS, other than OnApplicationQuit?

Or perhaps I should expose a "Save Variables" unit to let you do it manually whenever you feel is necessary?

If I understand the documentation correctly, it would be enough to store it in PlayerPrefs and the call to PlayerPrefs.Save() is optional to avoid data loss on crashes.

In SavedVariables.cs (Bolt 1.2.3) PlayerPrefs.SetString() is only called once. Directly before PlayerPrefs.Save() is called. Could it be that PlayerPrefs isn't usable in OnApplicationQuit() because Unity took already care of it at this point?

The solution would be to let Unity handle the saved variables alone and call PlayerPrefs.SetString() a bit earlier. Every time a variable is set would be ideal. And according to the documentation only a call to Save() has a big performance hit.

Exposing "Save Variable" would be the equivalent to the Save() from PlayerPrefs and would be more or less optional.

In the meantime I'll rewrite my code to use PlayerPrefs directly. No problem.


{I'm no expert in Unity or reading the documentation. A few weeks ago I thought LoadScene() is synchronous (because there exists a LoadSceneAsync()) and wanted to access objects from the loaded scene directly after the call. Too much time passed before I read the documentation on it a bit more thorough.}

It would be good to expose a "Save variables" or "Load variables" for one to make a manual saved or loaded.

The issue here isn't that PlayerPrefs.Save is failing because Unity calls it automatically in OnApplicationQuit. Worst case, it would be called twice; but I call it manually, because I have to be absolutely sure that the saved variables are saved to the prefs (SetString) before the prefs are saved to the disk, and Unity's documentation is ambiguous about that.

SetString in this case isn't an expensive operation, but serializing the variables to a string is. Calling that every time a saved variable is set would significantly slow down execution, so it has to be avoided.

The issue I think you're seeing is that OnApplicationQuit isn't actually called very often on iOS. For example, switching app or minimizing will actually call OnApplicationPause, as indicated by the Unity documentation. I'll make sure this event also saves the player prefs in the future.

+3
Answered

This will be implemented in the next version.

Hello, how is the current state. Are the commands "Save variables" and "Load variables" already inserted?

Bolt v.1.4.6 contains a Save Variables unit!

Load variables is always done on start automatically.