# Saving & Loading

Skill Web doesn't have an internal method for saving data, as it's not a save system. However, it does provide a way for save systems to save and load a [web](https://stylishesper.gitbook.io/skill-web/scripting/api/graph/web "mention"). Any save system that uses JSON or binary serialization should be able to save any web.

## To Savable (Saving)

You can create a savable version of a [web](https://stylishesper.gitbook.io/skill-web/scripting/api/graph/web "mention") (`SavableWeb`) with the `ToSavable` method.

```csharp
SavableWeb mySavableWeb = myWeb.ToSavable();
```

## To Web (Loading)

You can convert a `SavableWeb` back to a `Web` with the `ToWeb` method.

```csharp
Web myWeb = mySavableWeb.ToWeb();
```

## Examples

The code below is how you can save and load a web with [ESave](https://app.gitbook.com/o/vQC9VbiGJfIp0CaKhYvJ/s/korEE1oahhwAkGIn7ek0/ "mention"). ESave is my own save system—it's entirely free, and it's been tested with Skill Web. ESave is not a requirement; you can use the save system of your choice. However, the examples below will only work with ESave.

The examples below load a web from saved data and also load it in the UI.

**Notes:**

* The graph is loaded in the Start function if it exists in the saved data.
* The graph is saved when the application (or play mode) is exited.
* The code initially loads a web graph named "My Web Graph" if there was no saved web graph found. You may need to change the string to the name of your web (skill tree) if you plan on trying the code.
* Code customizations are **highly** recommended.

### With ESave Free

```csharp
using Esper.ESave;
using Esper.SkillWeb;
using Esper.SkillWeb.DataManagement;
using Esper.SkillWeb.Graph;
using Esper.SkillWeb.UI.UGUI;
using UnityEngine;

public class SkillWebSaveExample : MonoBehaviour
{
    /// <summary>
    /// The ID used to save and laod the web.
    /// </summary>
    private const string webID = "Web";

    /// <summary>
    /// The save file.
    /// </summary>
    private SaveFile saveFile;

    private void Start()
    {
        // Get the save file from the SaveFileSetup component
        saveFile = GetComponent<SaveFileSetup>().saveFile;

        // Load the data on start
        Load();
    }

    private void OnApplicationQuit()
    {
        // Save on application quit or play mode exited
        Save();
    }

    /// <summary>
    /// Saves the active Web with ESave.
    /// </summary>
    private void Save()
    {
        // Convert the loaded web to a savable version
        var savableWeb = WebViewUGUI.Active.web.ToSavable();

        // Add to save state
        saveFile.AddOrUpdateData(webID, savableWeb);

        // Officially write the data into the save file
        saveFile.Save();
    }

    /// <summary>
    /// Loads a saved Web with ESave.
    /// </summary>
    private void Load()
    {
        if (saveFile.HasData(webID))
        {
            // Get the savable web from the save file
            var savableWeb = saveFile.GetData<SavableWeb>(webID);

            // Convert to a regular web
            var web = savableWeb.ToWeb();

            // Load the web in UI
            WebViewUGUI.Active.Load(web);
        }

        // Check if a saved web exists
        if (saveFile.HasData(webID))
        {
            // Get the savable web from the save file
            var savableWeb = saveFile.GetData<SavableWeb>(webID);

            // Convert to a regular web
            var web = savableWeb.ToWeb();

            // Load the web in UI
            WebViewUGUI.Active.Load(web);
        }
        else
        {
            // Get a web
            var webGraph = SkillWeb.GetWebGraph("My Web Graph");
            var web = new Web(webGraph);

            // Load the web in UI
            WebViewUGUI.Active.Load(web);
        }
    }
}
```

### With ESave Pro

In case you're using the pro version...

```csharp
using Esper.ESave;
using Esper.SkillWeb;
using Esper.SkillWeb.DataManagement;
using Esper.SkillWeb.Graph;
using Esper.SkillWeb.UI.UGUI;
using UnityEngine;

public class SkillWebSaveExample : MonoBehaviour
{
    /// <summary>
    /// The ID used to save and laod the web.
    /// </summary>
    private const string webID = "Web";

    /// <summary>
    /// The save state.
    /// </summary>
    private SaveState saveState;

    private void Start()
    {
        // Initialize ESave (if not already done)
        ESave.Initialize();

        if (!ESave.HasSave(0))
        {
            // Create a save if it doesn't exist
            ESave.CreateSave(0).OnComplete(saveState =>
            {
                this.saveState = saveState;

                // Load the web
                LoadWeb();
            });
        }
        else
        {
            // Load the save if it exists
            ESave.Load(0).OnComplete(saveState =>
            {
                this.saveState = saveState;

                // Load the web
                LoadWeb();
            });
        }
    }

    private void OnApplicationQuit()
    {
        // Save on application quit or play mode exited
        SaveWeb();
        
        // Recommended to terminate ESave when its no longer being used
        ESave.Terminate();
    }

    /// <summary>
    /// Saves the active Web with ESave.
    /// </summary>
    public void SaveWeb()
    {
        if (saveState == null)
        {
            return;
        }

        // Convert the loaded web to a savable version
        var savableWeb = WebViewUGUI.Active.web.ToSavable();

        // Add to save state
        saveState.AddData(webID, savableWeb).OnComplete(success =>
        {
            // Save the state
            ESave.Save(saveState);
        });
    }

    /// <summary>
    /// Loads a saved Web with ESave.
    /// </summary>
    public void LoadWeb()
    {
        if (saveState == null)
        {
            return;
        }

        // Check if a saved web exists
        if (saveState.HasData(webID))
        {
            // Load the saved web
            saveState.GetData<SavableWeb>(webID).OnComplete(savedWeb =>
            {
                // Convert to a regular web
                var web = savedWeb.ToWeb();

                // Load the web in UI
                WebViewUGUI.Active.Load(web);
            });
        }
        else
        {
            // Get a web
            var webGraph = SkillWeb.GetWebGraph("My Web Graph");
            var web = new Web(webGraph);

            // Load the web in UI
            WebViewUGUI.Active.Load(web);
        }
    }
}
```
