#Save/Load system parsing issue

1 messages · Page 1 of 1 (latest)

ember lantern
#

Think it was about time I made this a thread

clear crane
#

What is the current code?

#

Data loss varies

ember lantern
# clear crane Data loss varies

which part are you interested in?

here is the load:

    public static SaveData Load()
    {
        string fullPath = Application.persistentDataPath + directory + fileName;

        if(File.Exists(fullPath))
        {
            string json = File.ReadAllText(fullPath);
            SaveData data = JsonConvert.DeserializeObject<SaveData>(json);
            List<UniqueID> uniqueIDs = Object.FindObjectsByType<UniqueID>(FindObjectsSortMode.None).ToList();

            foreach(var kvp in data.idToSaveableItems)
                uniqueIDs.Find(x => x.ID.Equals(kvp.Key)).GetComponent<ISaveable>().LoadData(kvp.Value);

            OnLoadGame?.Invoke(data);
        }
        else
        {
            Debug.Log("File doesn't exist");
        }

        return null;
    }
clear crane
#

And the Save data object?

ember lantern
#
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SaveData
{
    public SerializableDictionary<string, Data> idToSaveableItems = new SerializableDictionary<string, Data>();

    public SaveData()
    {
        UnityEngine.Object.FindObjectsByType(typeof(GameObject), FindObjectsSortMode.None)
        .ToList()
        .Where(x => ((GameObject)x).GetComponent<ISaveable>() != null)
        .ToList()
        .ForEach(saveable =>
        {

            string id = ((GameObject)saveable).GetComponent<UniqueID>().ID;
            idToSaveableItems.Add(id, ((GameObject)saveable).GetComponent<ISaveable>().GetData());
        });
    }
}
#

whoops forget abt the bottom part im not using that anymore

clear crane
#

What sata is missing? The json seems to have two entries and so does data after deserializing?

#

Sorry, I'm on a phone right now so it's hard to read

ember lantern
#

well the data is there in the file: {"idToSaveableItems":{"08c14717-39a1-4a49-86e4-0d8e4641ded8":{"value":66789},"93f53778-351b-44de-b203-5f8ee2e3f5f4":{"value":1423}}}

but when it converts it to the SaveData object the value is not accessible. Or maybe I am doing something wrong. Here's how I am trying to get it

    public void LoadData(Data dataContainer)
    {
        print("Loading! " + gameObject.name + ": " + value);
        value = ((CoinData)dataContainer).value;
        print("Loaded! " + gameObject.name + ": " + value);
    }
#

which obviously the error is with the cast

ember lantern
#

you can see there is 2 Data objects but they don't have values

#

im beginning to think this isnt possible

clear crane
#

Would the behaviour change if you changed the idToSaveableItems field to a property?

#

I have never seen this error befor, nor have I seen this class in general

#

That being SerializableDictionary

#

If the point is the ability to serialize a Dictionary, then note that newtonsoft can serialize Dictionaries without the need of special classes. Maybe just using a Dictionary works here

#

I assume you have this because JSONUtility might work with it, one of the many requirements to serialize in general

ember lantern
#

Wasn’t aware of that. Im running errands right now but when I am home I will try just using a regular dictionary as well as making it a property

#

I will report back with the results 🙏

#

And just to clarify should the casting work with this setup? Assuming it does retrieve the data

winter mulch
#

A little late and I have to run, but what I was looking into last night was the TypeNameHandling option, specifically the Auto or All values. These serialize the the fully qualified type name along with the data, so it's possible to both serialize and deserialize your classes without explicit typing or casting!

(Edit: though, if you heed the remarks and write validation for the types prior to deserialization to prevent users from modifying the JSON to instantiate whatever type, you may still end up with the deserialization logic having some sort of explicit knowledge of the types)

The more I've thought about it, the more I think explicit typing makes sense... but serializing the type is an interesting possibility that could be fun to play with. Especially if users potentially doing weird stuff with the JSON files isn't a concern 👍

ember lantern
# winter mulch A little late and I have to run, but what I was looking into last night was [the...

This was the answer, I added the JsonSerializerSettings with the TypeNameHandling to Auto and it worked immediately after adding that. very cool that it works like that. I am going to continue experimenting, as I don't love the fact that the type names are editable... ill probably convert it to binary as well, but i would still prefer a way to make this happen without serializing the types. Although the more I think about it I am not sure how you could know the derived classes without serializing it...

However another thought is that if they can edit the json to begin with then you have already lost

cc @clear crane

ember lantern
#

Just FYI when trying to serialize structs Newtonsoft has some issues, after I applied the ReferenceLoopHandling = ReferenceLoopHandling.Ignore property all is well again

here are the blocks.

Save:

string json = JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    TypeNameHandling = TypeNameHandling.Auto,
});

Load:

SaveData data = JsonConvert.DeserializeObject<SaveData>(json, new JsonSerializerSettings
{
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    TypeNameHandling = TypeNameHandling.Auto,
});

If you were curious! Thanks for the help, both of you!

clear crane
#

Unity types are very poorly written for serializers that are not JSONUtility. It is fixable but they never did

#

You can work around it by having a custom profile for these types instead. It would be a better fix than ignoring loops like that. There are examples online

ember lantern