HELP Save + LazyValue don't know how to debug it

This is the error, I’ve searched in the entire solution for every LazyValue reference to see if I was missing any .value parameter, but that’s not my case.
The problem is that I have no idea on how to debug this kind of error… :frowning:

*note that the error can be reproduced also without a save file present.
Indeed I’ve deleted the old one but the error still remain

SerializationException: End of Stream encountered before parsing was completed.
System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run () (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize (System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Runtime.Serialization.Formatters.Binary.__BinaryParser serParser, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at <695d1cc93cca45069c528c15c9fdd749>:0)
GranDucato.Saving.SavingSystem.LoadFile (System.String saveFile) (at Assets/0 == GRAN DUCATO == 0/Scripts/Saving/SavingSystem.cs:53)
GranDucato.Saving.SavingSystem.Save (System.String saveFile) (at Assets/0 == GRAN DUCATO == 0/Scripts/Saving/SavingSystem.cs:28)
GranDucato.SceneManagement.SavingWrapper.Save () (at Assets/0 == GRAN DUCATO == 0/Scripts/SceneManagement/SavingWrapper.cs:56)
GranDucato.SceneManagement.Portal+<Transition>d__13.MoveNext () (at Assets/0 == GRAN DUCATO == 0/Scripts/SceneManagement/Portal.cs:74)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <ae72fc958ab44fdbb61b9d8c36cf141e>:0)

Maybe if there’s a way to see the data that will be saved before write the file, I could check which value is null :thinking:

Got anything that is unserializable (like a Vector3)?

Oh, you mean this one?
It’s the only Vector3 that I’ve set as LazyValue.

LazyValue<Vector3>guardPosition;


        private void Awake()
        {
            fighter = GetComponent<Fighter>();
            health = GetComponent<Attributes.Health>();
            mover = GetComponent<Movement.Mover>();
            player = GameObject.FindGameObjectWithTag("Player");

            guardPosition = new LazyValue<Vector3>(GetGuardPosition);
        }

Maybe. You can set a Vector3 as a lazy value, that’s no problem. But if you try to return guardPosition in CaptureState without serializing it, that would cause your error.

Taking a look at the error again, it is talking about deserialize (check out line 53 of SavingSystem). So it does sound like you have updated the code and then tried to load an old (or non existent) save file. There is a fix at some point (can’t remember exactly when) for trying to load when no file is present.

Anyhow, I think LazyValue is a sideshow, not the real thing. Clear out your save, make sure you aren’t trying to load when the file is non-existent and see if that helps.

I’ve dig on it even more, and the issue is not about LazyValue or the Portal but in Save and SavingWarper but I notice that the portal script and also the SavingWarper get changed once the project is completed, so for now I will survive without saving and changing level.

So, Thank you anyway :slight_smile:

If you are returning a LazyValue<Vector3>.value, you will encounter the same serialization issues as if you were returning the LazyValue itself. You have to convert the LazyValue<Vector3>.value into a SerializableVector3.

public object CaptureState()
{
    return new SerializableVector3(guardPosition.value);
}
public void RestoreState(object state)
{
     SerializableVector3 serializableVector3 = (SerializableVector3)state;
     guardPosition.value = serializableVector3.ToVector();
}

And of course, you’ll need to delete the existing save file.

Fact is that I have only 1 CaptureState in the entire project at the moment and is just about the Mover.cs and it even rise the error.

 public object CaptureState()
        {
            try
            {
                return new SerializableVector3(transform.position);
            }
            catch (System.Exception)
            {
                Debug.LogWarning("Something goes wrong with saving file, try later, or delete the save file.");
                return null;
            }
        }

        public void RestoreState(object state)
        {
            SerializableVector3 position = (SerializableVector3)state;
            navMeshAgent.enabled = false;
            transform.position = position.ToVector();
            navMeshAgent.enabled = true;

        }

Anyway I just completed the Fighter To Weapon Communication but even after the refactoring still getting the error, the best way to understand what’s going wrong, I guess is to spam on console the dictionary with the value to understand what’s going wrong… maybe? :thinking:

Looking over my code I’ve used a simple dictionary to store those values. Here is the code i used in my Mover.cs script

        public object CaptureState()
        {
            Dictionary<string, object> data = new Dictionary<string, object>();
            data["position"] = new SerializableVector3(transform.position);
            data["rotation"] = new SerializableVector3(transform.eulerAngles);
            return data;
        }

        public void RestoreState(object state)
        {
            Dictionary<string, object> data = (Dictionary<string, object>)state;
            GetComponent<NavMeshAgent>().enabled = false;
            transform.position = ((SerializableVector3)data["position"]).ToVector();
            transform.eulerAngles = ((SerializableVector3) data["rotation"]).ToVector();
            GetComponent<NavMeshAgent>().enabled = true;
        }

Maybe that helps

1 Like

Thank you for it, but I still get the error :sweat_smile:
So i think it’s not even in the mover :roll_eyes:

  1. Did you implement the Save System or used the package they provide?
  2. Did your saving system ever work?
  3. What did you change since it last worked?

Honestly can’t remember, when it happens, anyway I will disable the ISaveable for each component hunting for the guilty.

And yes, it was working once upon time a go.

In that case, I highly recommend you use the provided Saving package and remove your current files. We at least know the issues is not in there and its somewhere else

If this is causing an error, then there is something else going very very wrong.
Zip up your project and upload it to https://gdev.tv/projectupload and I’ll take a look.

I catch the bug!!! \o/
Is Health! :dizzy_face:
Can you confirm that’s correct?

    public object CaptureState()
    {
        return healthPoints;
    }
            
    public void RestoreState(object state)
    {
        healthPoints.value = (float)state;

        if (healthPoints.value <= 0) Die();
    }
1 Like

There’s your bug.
CaptureState should read:

return healthPoints.value;
1 Like

YESSS!
Now we can close this thread, thank you all :grin::pray:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.