Trouble saving a custom datatype

Discussion and help for Easy Save 3
Post Reply
caleidon
Posts: 16
Joined: Mon Dec 28, 2020 3:02 pm

Trouble saving a custom datatype

Post by caleidon »

In my game, I am saving a class Map which has a

Code: Select all

 HashSet<Region> Regions
A Region has the following information:

Code: Select all

- RegionID (int)
- RegionPositions (HashSet<Vector3Int)
- RegionRect (Rect)
I can save, load and use this without any problems. The problem occurs when a Region needs to save one more piece of information. I need every region to store a reference to all the regions that are is neighbors, and I do this here:

Code: Select all

- HashSet<Region> Neighbors
When I include that field to be saved through the ES3 "Types" tab, and try to save, the whole editor and game freeze and nothing happens. I have to kill unity with the task manager to get back in. So it seems a Region cannot save Regions.

Saving a Region's neighbors inside of itself is crucial for me, and I would like to do it this way for simplicity. What is the issue here and how can I fix this?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Trouble saving a custom datatype

Post by Joel »

Hi there,

This is likely because you have a cyclic reference (i.e. a region which at some point refers to itself). As it will be saved by value, it will constantly save.

Unity's recommendation regarding this is to create a list of all of your Regions to act as a database of your regions. Then instead of saving your neighbours as a HashSet<Region>, save a HashSet<int> where the int represents the position of the Region in the Region list.

You can modify the ES3UserType_Region.cs file to do this, which will be located in Easy Save 3/Types.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
caleidon
Posts: 16
Joined: Mon Dec 28, 2020 3:02 pm

Re: Trouble saving a custom datatype

Post by caleidon »

A region can never save itself as it's own neighbor, so that wouldn't be the issue.

However, I did not know the regions are saved by value. Isn't it possible then to save the original HashSet<Region> by value, but when storing their neighbors, they can just store a reference to them?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Trouble saving a custom datatype

Post by Joel »

A region can never save itself as it's own neighbor, so that wouldn't be the issue.
That's correct, but the cyclic reference doesn't need to be direct.

For example, let's say that we have Region A and Region B, which are neighbours.
  1. We save Region A, which then saves it's neighbour list.
  2. In the neighbour list is Region B, so we save region B.
  3. Region A is in Region B's neighbour list, so Region A gets saved again.
  4. Region B is in Region A's neighbour list, so this gets saved again.
  5. This is a cyclic reference and will happen infinitely
Isn't it possible then to save the original HashSet<Region> by value, but when storing their neighbors, they can just store a reference to them?
This is what my solution does. The index in the list acts as a reference ID.

Alternatively if your Region class is a UnityEngine.Object (i.e. MonoBehaviour or ScriptableObject), Easy Save will automatically store it by reference using its own reference manager. This is because only UnityEngine.Object types can be automatically stored by reference.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
caleidon
Posts: 16
Joined: Mon Dec 28, 2020 3:02 pm

Re: Trouble saving a custom datatype

Post by caleidon »

The regions can get added and removed at any time, any of them.

If I have regions:

Region0 at index 0
Region1 at index 1
Region2 at index 2
Region3 at index 3

and lets say some of them area each others neighbors. For an example: Region1 gets assigned a neighbor at index 2 (which is region 2).

If I then delete Region0, all the indexes shift backwards.

Then Region1 is still pointing at index 2, which is now Region3, completely messing up my system. How would I overcome this?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Trouble saving a custom datatype

Post by Joel »

Hi there,

I'm afraid I can only help with the saving and loading side of things, not how you uniquely identify things in your project. However, you might want to find another way of uniquely identifying your regions. For example, using a GUID.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
caleidon
Posts: 16
Joined: Mon Dec 28, 2020 3:02 pm

Re: Trouble saving a custom datatype

Post by caleidon »

I have resolved some of the issues by implementing GUIDs as Region's IDs.

However, upon loading a HashSet<Guid> and Debug.Logging them, it just says 00000000-0000-0000-0000-000000000000, like they've all been wiped out.

Does ES3 not support GUID saving/loading? Am I doing something wrong?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Trouble saving a custom datatype

Post by Joel »

Hi there,

It looks like you're trying to save the GUID object (which is the object used to generate the GUID) rather than using the GUID value itself. The easiest way to do this is to use it's ToString() method.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply