Making a save system in a ScriptableObject using JsonUtility. Are references to prefabs and other ScriptableObjects reliable?

Here is an example save system:

using System.IO;
using UnityEngine;

[CreateAssetMenu(fileName = "GameSave", menuName = "ScriptableObjects/GameSave", order = 1)]
public class ExampleSaveSystem : ScriptableObject
{
    public float someFloat;
    public GameObject prefabReference;
    public ScriptableObject scriptableObjectReference;
    
    private string GetPath()
    {
        return Application.persistentDataPath + "/" + name + ".json";
    }

    public void SaveToFile()
    {
        File.WriteAllText(GetPath(), JsonUtility.ToJson(this, true));
    }

    public void LoadFromFile()
    {
        if (!File.Exists(GetPath()))
        {
            SaveToFile();
            return;
        }
        JsonUtility.FromJsonOverwrite(File.ReadAllText(GetPath()), this);
    }
}

A prefab or ScriptableObject reference will be serialized by its instanceid. Is this a reliable way to store a reference long term? I have tested it in a build and it did work, but I’m worried that eventually the instanceids will change.

No, it’s not reliable. The instance ID is a generated ID at runtime. Assets might get the same id as the game loads, but even that’s not guaranteed. During one session it would be reliable. However closing and restarting the game it’s not guaranteed. Every loaded object that is derived from UnityEngine.Object gets an instance ID when it’s created. Since the order might depend in which order you load your scene or in which order you instantiate other objects you can’t trust it, especially long term. When you change something in your game (adding / removing assets) and build a new game the IDs probably change