Saving and Loading Dictionaries

Discussion and help for Easy Save 3
Post Reply
aallenfx
Posts: 4
Joined: Wed May 24, 2023 4:50 pm

Saving and Loading Dictionaries

Post by aallenfx »

Hi,

I'm having some trouble getting my Dictionary to load. I have this "recipe unlock" system that checks to see if an entry already exists on file.
It will save the data to a file, but the problem is loading it. I tried following the documentation but am getting errors:
https://docs.moodkie.com/easy-save-3/ge ... bleobjects

https://imgur.com/a/rPdLKu4
https://imgur.com/A3at0aZ

I tried

Code: Select all

recipesDictionary = ES3.Load("recipesDictionary", defaultValue);
Here's the sample code:

Code: Select all


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ES3Internal;
using ES3Types; 

public class RecipeUnlocks : MonoBehaviour
{
    // DESC: RECEIVES ALL RECIPE UNLOCKS 
    // ALSO CHECKS TO SEE IF KEY EXISTS TO BLOCK LEARN ACTION 
    public static RecipeUnlocks Instance;

    void Awake()
    {
        // INSTANCE CHECK 
        if (Instance != null)
        {
            GameObject.Destroy(Instance);
        }
        else
        {
            Instance = this;
        }
        DontDestroyOnLoad(this);

        // LOAD DATA ON START INTO LIST
        //var defaultValue = 1; 

        var defaultValue = 1; 
        ES3.Save("recipesDictionary", recipesDictionary);
        recipesDictionary = ES3.Load("recipesDictionary", defaultValue);

    }


    // DICTIONARY TO STORE UNLOCKED RECIPES
    public Dictionary<string, int> recipesDictionary = new Dictionary<string, int>();

    // DISPLAY THE LIST IN EDITOR 
    public List<string> recipesList = new List<string>();

    // ADD ITEM TO DICTIONARY/LIST
    public void UnlockRecipe(string item)
    {
        // UNLOCK RECIPE // DISPLAY ON LIST FOR EDITOR 
        recipesDictionary.Add(item, 1);
        recipesList.Add(item);

        // SAVE ENTIRE DICTIONARY TO FILE 
        ES3.Save("recipesDictionary", recipesDictionary);
        
        Debug.Log("Unlocked [" + item + "] Recipe!");
    }

    // CHECKS TO SEE IF ITEM EXISTS
    public bool CheckRecipe(string item)
    {
        // check entire dictionary for recipe
        foreach (KeyValuePair<string, int> kvp in recipesDictionary)
        {
            if (kvp.Key == item)
            {
                Debug.Log("FOUND ITEM, TRUE");
                return true;
            }
        }
        // else return false 
        Debug.Log("ITEM NOT FOUND, FALSE");
        return false;
    }
}
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving and Loading Dictionaries

Post by Joel »

Hi there,

There is an error in your code.

Code: Select all

recipesDictionary = ES3.Load("recipesDictionary", defaultValue);
The defaultValue parameter must be the same type as the data you're loading. However, your defaultValue is an int:

Code: Select all

var defaultValue = 1;
This means that you're telling Easy Save to load an int when the data is a Dictionary.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
aallenfx
Posts: 4
Joined: Wed May 24, 2023 4:50 pm

Re: Saving and Loading Dictionaries

Post by aallenfx »

Hey, thanks for responding. Can you provide an example of the proper syntax for loading a dictionary?

Some tests that didn't work:

Code: Select all

  
ES3.Save("recipesDictionary", recipesDictionary);

recipesDictionary = ES3.Load<Dictionary>(string, int);
recipesDictionary = ES3.Load("recipesDictionary", Application.persistentDataPath);
recipesDictionary = ES3.Load<Dictionary>("recipesDictionary", string);
recipesDictionary = ES3.Load<Dictionary>("recipeDictionary", "C:\Users\colos\AppData\LocalLow\DefaultCompany\GameTest"); 
Can't think of other options atm.
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving and Loading Dictionaries

Post by Joel »

Hi there,

You should specify the generic types of your Dictionary. I.e.

Code: Select all

recipesDictionary = ES3.Load<Dictionary<string,int>>("key");
Or if you're providing a defaultValue which is of the same type as your Dictionary, you don't need to provide the generic value. I.e.

Code: Select all

var defaultValue = new Dictionary<string, int>();
recipesDictionary = ES3.Load("key", defaultValue);
For more information on how generics work I recommend the C# documentation on the subject:
https://learn.microsoft.com/en-us/dotne ... s/generics

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
aallenfx
Posts: 4
Joined: Wed May 24, 2023 4:50 pm

Re: Saving and Loading Dictionaries

Post by aallenfx »

Awesome, looks like this worked for me. Thanks!

Code: Select all

 recipesDictionary = ES3.Load<Dictionary<string, int>>("recipesDictionary");
aallenfx
Posts: 4
Joined: Wed May 24, 2023 4:50 pm

Re: Saving and Loading Dictionaries

Post by aallenfx »

Ah, one last question in this regard-

How do you do a null check to see if the save file exists or not? My save file name is "recipes" (saving it as a separate entity).
This appears to work, just double checking that this is the proper method/syntax.

Reads as "If dictionary/file doesn't exist, then create a new save file placeholder" (since immediately after it does a load function which throws an error if no file exists)

Code: Select all

        
if (!ES3.KeyExists("recipesDictionary", "recipes.es3")) {
Debug.Log("File does not exist, creating new Recipe Save File!");
ES3.Save("recipesDictionary", recipesDictionary, "recipes.es3"); }
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving and Loading Dictionaries

Post by Joel »

Hi there,

That code is correct.

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