Persistence API
Runtime Studio saves scenes, terrain, imported assets, component state, and resolved asset references in a single SceneSaveFile. It supports .rtstudio packages, JSON fallback, and raw GZip data.
Save and load a package
using Fullscreen.RuntimeStudio.Runtime.Persistence;
public sealed class SaveExample
{
private readonly SceneSaveManager m_SaveManager = new();
public byte[] Save()
{
return m_SaveManager.ExportPackageBytes();
}
public void Load(byte[] data)
{
m_SaveManager.ImportPackageBytes(data);
}
}Use RuntimeStudioFileTransfer.TryExport and RuntimeStudioFileTransfer.TryImport when the project needs the normal file picker workflow.
The .rtstudio package uses the RTSTUDIO1 header and a GZip-compressed JSON payload. Runtime Studio can also read raw JSON and raw GZip JSON.
Save lifecycle
Save runs in this order:
- Prepare the scene for saving.
- Capture component state.
- Serialize scene data.
- Export assets and references.
- Write the package.
Load reads the package, restores scene objects and components, restores terrain, rebinds asset references, then runs registered runtime integrations.
Component state adapters
Use IComponentStateAdapter when reflection is not enough. This is useful for version-safe data, partial saves, ID-based references, and runtime-only fields that must not be saved.
using System;
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));
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);
}
}Adapters override the default save behaviour. Register them from an editor module with AddDefaultComponentStateAdapter.
Runtime integration hooks
Use a RuntimeIntegration when a component needs work after a scene is restored or an object is placed.
using UnityEngine;
public sealed class MyIntegration : RuntimeIntegration
{
public override void PrepareForSceneRestore()
{
}
public override void RebindRestoredObject(GameObject gameObject)
{
}
}These hooks are the right place to rebuild references, restore runtime-only state, and prepare content for edit isolation.
Undo and redo
Built-in inspector fields record undo automatically. Custom tools must record scene mutations, hierarchy changes, and component additions or removals.
RuntimeStudioUndo.RecordAction(
"Add Health",
() => gameObject.AddComponent<MyHealth>());
using (RuntimeStudioUndo.Begin("Move Objects"))
{
foreach (var item in objects)
{
item.transform.position += offset;
}
}RuntimeStudioUndo.Run is a short form for one action. Nested scopes are merged. Do not use undo for UI-only changes.