Save On Destroy

Discussion and help for Easy Save 3
Post Reply
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Save On Destroy

Post by Notso »

I started using this for the few objects I have in the scene, works great.
I just thought of an issue and not sure how to solve it then....

This script writes directly to the save file that it was destroyed. But what if the player saves, then picks up the item and plays for another 10 minutes then quits without saving. (other than setting a save on quitting or scene change) Is there a way to keep a list of what was destroyed first THEN on a save game write those changes and clear a list?

Code: Select all

public string guid = System.Guid.NewGuid().ToString();
    void Start () 
    {
            Invoke(nameof(DestroyMe), .3f);
    }

    public void DestroyMe()
    {
     //   Debug.Log("I am destroying it");
     if (ES3.FileExists("SaveFile.notso") && ES3.KeyExists(guid))
     {
         if (ES3.KeyExists(guid))
         {
             Destroy(this.gameObject);
         }
     }

    }
    
    void OnDestroy()
    {
        if (gameObject.scene.isLoaded && !NotsoSave.isApplicationQuitting)
        {
            Debug.Log("I have just destroyed  : " + guid);
            ES3.Save<bool>(guid, true);
        }
    }
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Save On Destroy

Post by Joel »

Hi there,

If you don't want to immediately commit save data to a save file then you would use caching:
https://docs.moodkie.com/easy-save-3/es ... rformance/

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Save On Destroy

Post by Notso »

Trying to make sense of that.
Is this the same as changing the Runtime Settings to cache (in the easysave window)?
So even though the file says es3.save it is actually putting it in cache?
Then on a separate file I can save es3.storecachedfile() ?
Does it only create 1 cache (like a savefile) and when I say Void Save (or in this case Void SaveCache) it will write the memory file as an actual file.

So like this. Runtime is set to CACHE

On my savedestroyed script:

Code: Select all

void OnDestroy()
    {
        if (gameObject.scene.isLoaded && !NotsoSave.isApplicationQuitting)
        {
            Debug.Log("I have just destroyed  : " + guid);
            ES3.Save<bool>(guid, true);
        }
    }
This will save to cache now (or do I still need var settings somewhere?)
like this

Code: Select all

 ES3.Save<bool>(guid, true, settings);
Now to save this I can, on my NotsoSave script inside my savegame function just put

Code: Select all

ES3.StoreCachedFile();
And this will write that cache to into the same savefile as the rest of the objects?

The load will work the same since it reads from the file and I do not need the cache for that.

Since the destroyed saves each guid as a separate line wouldn't saving each GUID key need to be typed in to be saved from cache?
Like this example

Code: Select all

ES3.Save("myInt", 123,  settings);
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Save On Destroy

Post by Joel »

Hi there,

The cache stores data in RAM rather than permanent storage. Calling ES3.StoreCachedFile() will store that file in RAM into permanent storage. Calling ES3.CacheFile() will take a file in permanent storage and put it into the cache.
Now to save this I can, on my NotsoSave script inside my savegame function just put
That is correct.
The load will work the same since it reads from the file and I do not need the cache for that.
That is not correct. If you've set the default location to Cache then it will also be trying to load from the Cache.

Generally the workflow for using the cache is as follows (though this might vary from project to project):
  1. When your game starts, use ES3.CacheFile() to load your file(s) in permanent storage into the Cache.
  2. Call ES3.Save and ES3.Load as you normally would.
  3. When you want to commit the save data to a permanent file, call ES3.StoreCachedFile().
All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Save On Destroy

Post by Notso »

I set the default to be cache.
On new game all data is deleted.
Now I can keep my save and load methods as is correct?
It will save all data to the cache when they hit save game?
Then when ready I call ES3.StoreCachedFile() that will write it to an actual save file?

Then when they hit Load Game (Continue from the main menu) I then call ES3.CacheFile(), once that is complete I can then just use my load method?

In the savedestroyed script where it says ES3.Save<bool>(guid, true); actually sends it to the cache?

So example workflow:

I hit F5 to save
Which fires this:

Code: Select all

public void Save()
    {
    //PlayerInfo
                ES3.Save("PlayerTransform", player.transform);
                ES3.Save("Scriptables", scriptables);
                ES3.Save("Infected", charManager.isInfected);
                ES3.Save("GameStates", ApplicationManager.instance._gameStateDictionary);
                ES3.Save("prefabInstances", prefabInstances);
                
                ES3.StoreCachedFile()
       }
    
In the continue method load scene method I can then

Code: Select all

void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
   {
       Debug.Log(scene.name + "  Level Loaded  " + mode + " mode");
      
       if (ApplicationManager.instance.loadGame)
       {
           Debug.Log("I am Loading Cache");
           ES3.CacheFile();
           Invoke(nameof(Load), .1f);
       }
   }
Then

Code: Select all

public void Load()
    {
        Debug.Log("STARTING LOAD FROM NOTSOSAVE CACHE");
        //PlayerInfo
        if (ES3.KeyExists("PlayerTransform")) ES3.LoadInto("PlayerTransform", player.transform);
        if (ES3.KeyExists("Scriptables")) ES3.LoadInto("Scriptables", scriptables);
        if (ES3.KeyExists("Infected")) charManager.isInfected = ES3.Load("Infected", charManager.isInfected);
        }
        
This seems to work? At least I was able to save and load in same play, however this line no longer works in the main menu on start...
if (ES3.FileExists("SaveFile.notso"))
I assume it is trying to find the cache? how can I check for a save file on start then?
If I comment out that line and just turn on the continue it loads my game fine. If I remove the cache settings, this IF statement works.
I just need a way to tell if there is a file to turn on the continue button or leave it off.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Save On Destroy

Post by Joel »

Hi there,

ES3.FileExists will be looking for the file in the cache if your default location is set to cache. So if you haven't called ES3.CacheFile, the file won't be in the cache at that point.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Save On Destroy

Post by Notso »

That's what I figured, however can I cache the savefile even though there are no references yet?
Write the load when the gamescene is finished, but precache the save file? Like in my bootstrapper scene (that loads my DND and other things required)
How would i say to check if the harddrive file exists to load it into cache?
Just a check in case of a first run where there will not be any save file at all.
Or how do I delete the harddrive file if it will always look in cache?
Also did my code above look OK like it should not cause me any real issues (regarding the save/load)?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Save On Destroy

Post by Joel »

Hi there,

I'm not sure I fully understand what you're saying. However, if you want to check whether a file exists on the hard disk you works provide an ES3Settings object with the location set to ES3.Location.File to the File exists method. The same if you wanted to delete the file.

I couldn't see anything else obviously wrong with your code.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Notso
Posts: 51
Joined: Sat May 08, 2021 6:53 pm

Re: Save On Destroy

Post by Notso »

Thanks.
Still testing but I think I got it to work as needed.
You know I will let you know if not! haha.

So in this example, the first IF will delete the local file and the 2nd IF will delete the cache file...correct?

Code: Select all

var settings = new ES3Settings(ES3.Location.File);
            if (ES3.FileExists("SaveFile.notso", settings))
            {
                ES3.DeleteFile("SaveFile.notso", settings);
            }
            if (ES3.FileExists("SaveFile.notso"))
            {
                ES3.DeleteFile("SaveFile.notso");
            }
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Save On Destroy

Post by Joel »

That's correct, though you don't actually need the ES3.FileExists calls because ES3.DeleteFile won't throw an error if the file doesn't exist (because it doesn't matter if the file doesn't exist because it's being deleted anyway).

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