> For the complete documentation index, see [llms.txt](https://docs.fullscreen.no/info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fullscreen.no/info/standalone-assets/runtime-studio/api/save-and-load.md).

# Save & Load

Runtime Studio provides a full runtime-safe save system for scenes, terrain, and imported assets. It supports `.rtstudio` packages, JSON fallback, and raw GZip data.

***

### Core Concept

Runtime Studio saves everything into a single `SceneSaveFile`:

* Scene objects and transforms
* Components and their values
* Imported runtime assets
* Custom component state (via adapters)
* Asset references (via resolvers)

***

### Basic Save

```cs
using Fullscreen.RuntimeStudio.Runtime.Persistence;

public sealed class SaveExample
{
    private readonly SceneSaveManager m_SaveManager = new();

    public byte[] Save()
    {
        return m_SaveManager.ExportPackageBytes();
    }
}
```

***

### Basic Load

```cs
public void Load(byte[] data)
{
    m_SaveManager.ImportPackageBytes(data);
}
```

***

### File Import and Export

```cs
RuntimeStudioFileTransfer.TryExport(
    bytes,
    RuntimeStudioPackage.DefaultFileName,
    out var location,
    out var message
);
```

```cs
RuntimeStudioFileTransfer.TryImport(
    out var bytes,
    out var location,
    out var message
);
```

***

### Package Format

* Extension: `.rtstudio`
* Header: `RTSTUDIO1\n`
* Payload: GZip compressed JSON

Supported inputs:

* `.rtstudio`
* raw JSON
* raw GZip JSON

***

### Save Lifecycle

Save and load follow this order:

1. Prepare scene for save
2. Capture component state
3. Serialize scene data
4. Export assets and references
5. Write package

Load:

1. Read package
2. Restore scene objects
3. Restore components
4. Restore terrain
5. Rebind asset references
6. Run runtime integrations

***

### Component State Adapters

Use adapters when reflection is not enough.

```cs
using Fullscreen.RuntimeStudio.Runtime.Persistence;
using Fullscreen.RuntimeStudio.Runtime.Persistence.ComponentState;
using UnityEngine;

public sealed class HealthStateAdapter :
    IComponentStateAdapter
{
    public Type ComponentType =>
        typeof(Health);

    public SerializedNode CaptureState(Component component)
    {
        var health = component as Health;
        if (health == null) return null;

        var node = SerializedNodeUtility.Object(typeof(Health));

        SerializedNodeUtility.AddField(
            node,
            "current",
            SerializedNodeUtility.Float(health.Current)
        );

        SerializedNodeUtility.AddField(
            node,
            "max",
            SerializedNodeUtility.Float(health.Max)
        );

        SerializedNodeUtility.AddField(
            node,
            "invincible",
            SerializedNodeUtility.Bool(health.Invincible)
        );

        return node;
    }

    public void RestoreState(Component component, SerializedNode data)
    {
        var health = component as Health;
        if (health == null || data == null) return;

        health.Current = SerializedNodeUtility.GetFloat(
            data,
            "current",
            health.Current
        );

        health.Max = SerializedNodeUtility.GetFloat(
            data,
            "max",
            health.Max
        );

        health.Invincible = SerializedNodeUtility.GetBool(
            data,
            "invincible",
            health.Invincible
        );
    }
}
```

Adapters override default save behavior.

***

### Runtime Integration Hooks

{% code overflow="wrap" %}

```cs
public override void PrepareForSceneRestore() { }

public override void RebindRestoredObject(GameObject go) { }
```

{% endcode %}
