Playerprefs loading null pointer issue

I am saving my data to playerprefs. Saving works perfect, never any issues. Issues come up when loading the data. If at any point when I’m loading all my data, if I encounter a null pointer exception, then my method for loading my data stops and only part of the data is loaded. When the real issue happens is if this null pointer issue occurs and then default data is saved the player will lose some of their progress, if not all of it.

Example:

Load stats - Complete
Load player position - Complete
Load equipment - failed null pointer
Load inventory - never called
Load quests completed - never called
ect…

From this point we loaded into the game with an empty inventory and no quests completed. Then the game auto saves, we lost pretty much everything in this case…

So my question is how do I create a fail safe save system? Can I do try catch for each section that is loaded? Even in that case if something fails we might still load the game with partial data, in that case we wouldn’t want to save. We could create multiple previous save states but this is tedious for the player to manage if there are issues.

I just need a solution to where if one thing fails to load that it doesn’t cause everything to fail. So if one piece of equipment fails it doesn’t effect the other equipment. Or if an inventory item fails to load that it doesn’t cause the entire inventory to not load or the other methods to load.

First thing is to just fix the nullrefs. They really aren’t something you want around.

The answer is always the same… ALWAYS!

How to fix a NullReferenceException error

https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

Three steps to success:

  • Identify what is null ← any other action taken before this step is WASTED TIME
  • Identify why it is null
  • Fix that

Second thing, as to this:

Alternating between two savedata blobs (call them A and B) as you work can help you from writing a corrupt one. If you detect corruption, you switch back to the other one.

But seriously, fix the nullrefs. There’s just no reason to live with that!!!

More reading about Load/Save steps:

https://discussions.unity.com/t/799896/4

An excellent discussion of loading/saving in Unity3D by Xarbrough:

https://discussions.unity.com/t/870022/6

Loading/Saving ScriptableObjects by a proxy identifier such as name:

https://discussions.unity.com/t/892140/8

When loading, you can never re-create a MonoBehaviour or ScriptableObject instance directly from JSON. The reason is they are hybrid C# and native engine objects, and when the JSON package calls new to make one, it cannot make the native engine portion of the object.

Instead you must first create the MonoBehaviour using AddComponent() on a GameObject instance, or use ScriptableObject.CreateInstance() to make your SO, then use the appropriate JSON “populate object” call to fill in its public fields.

If you want to use PlayerPrefs to save your game, it’s always better to use a JSON-based wrapper such as this one I forked from a fellow named Brett M Johnson on github:

Do not use the binary formatter/serializer: it is insecure, it cannot be made secure, and it makes debugging very difficult, plus it actually will NOT prevent people from modifying your save data on their computers.

1 Like

I’m tempted to say “by not using PlayerPrefs” but in this case, I don’t think where or how the data is stored matters. What matters is what you do with that data.

Simply put: there should not be a null reference loading data that you saved, more so if the data version hasn’t changed.

You should analyze why you get that nullref and fix that. And of course put your data save & load code under unit tests so that none of these issues ever occur a second time.

1 Like

Lot of good tips, I am fixing the null errors but there could always be a small edge case where this occurs. Don’t want my players to spend hundreds of hours to lose it to something preventable. I will do my best to create a corrupted check system and allow player to revert to good save states.

No, that’s actually not a thing. That just means you haven’t found how your code is getting a nullref. Nullrefs are an extremely well-understood phenomena with simple non-time-sensitive data loading / processing.

If you are interoperating with anything (hardware, external data) and can reasonably EXPECT a nullref in a particular specific circumstance, then you engineer a try/catch block to catch just that nullref and deal with it appropriately.

Do not use Pokemon try/catch to try and spackle over missing engineering features!

Where I’m coming from is if something is missed during testing and there’s a null pointer that exists that I am not aware of that only occurs a very small chance of the time. Then someone could lose all thier data.

Given PlayerPrefs is one of those old Unity systems, I wouldn’t be surprised if it had a situation where it silently failed, like a lot of other Unity API’s like JsonUtlity and AssetDatabase. Perhaps you’ve tried to write too much into a particular registry entry and it just went “nope”.

But it could just be another bog-standard null-ref that needs to be fixed. Save/load systems need to be air-tight.

In any case, I would use more reliable means of saving/loading, such as serialising out data with serialisation tools. PlayerPrefs is not meant to be used for general saving and loading.

1 Like