The pieces

PersistentSceneState

SO

Holds the saved state of the scene objects that point at it. An ordinary persistent ScriptableObject, so it takes any Persistence Manager, any serializer, slots, encryption and migration with no extra work. Create > Persistent Asset > Scene State. A state several scenes use wants Always Global on its manager, like any persistent object that has to outlive the scene that referenced it.

void CaptureAll()Pull every live object's current state into the records. Runs on the manager's OnBeforeSave, so you rarely call it.
void RestoreAll()Push the records back onto every live object and recreate the spawns of every loaded scene. Runs after every load, import, slot change, clear and snapshot restore, and takes away the objects the records say are gone.
void RecordDestroyed(PersistentSceneObject sceneObject)Record that an object is gone, so it stays gone across loads. Destroying one during play already does this, so call it only for an object you took out of play without destroying it, a pooled spawn returned to its pool for one.

PersistentSceneObject

MBsealed

Marks a scene object as persistent. Add it, tick the components to save. On a prefab it also carries the prefab's registry id, which is what lets a runtime instance be recreated; you keep calling plain Instantiate.

The inspector tags each component with what ticking it saves
fieldsIts serialized fields, written by your project's own serializer, with no interface and no attribute.
codecThrough a component codec, which is how a Unity component with no serializable fields is saved.
enabled onlyIt has no state to save, but whether it is enabled is saved, which is what a disarmed trap needs.
nothingTicking the row writes nothing: the component has no state and no enabled flag, or its enabled flag is all it has and Save Active & Enabled is off.
PersistentSceneState SceneState { get; }The scene state its data is stored in.
string Id { get; }Its stable, scene-scoped id.
string PrefabId { get; }The registry id of the prefab behind this object, empty when it came from none. A prefab instance authored into a scene carries one too, so it does not mark a runtime spawn.
bool SaveActiveAndEnabled { get; }Whether the active state and the components' enabled flags are saved.
bool IsSaved(Component component)Whether that component is ticked to be saved.

SceneRef

struct

A saveable reference to a scene object, for a persistent asset that has to remember one. Unity cannot serialize a scene reference into a project asset at all, so this stores the id and resolves it against what is loaded. Explained in Scene Objects.

SceneRef(PersistentSceneObject sceneObject)Point it at an object, or at nothing.
bool TryResolve<T>(out T value) where T : classFind it as a GameObject, a component, or any interface one implements. False when that scene is not loaded.
bool IsSet { get; }Whether an object was assigned. Resolving it also needs that object's scene loaded.
string Id { get; }The referenced object's persistent id, null or empty when this points at nothing.
bool Equals(SceneRef other) / == / != / int GetHashCode()Value equality on the id and the scene it names, so two references to the same object compare equal and one can be a dictionary key. IEquatable<SceneRef>.

Codecs

SceneComponentCodec

abstractextending

Teaches the module how to save a component whose state a serializer cannot see. It maps the component to and from a plain state class with real fields, which your own serializer writes: a codec never serializes anything itself. Inherit the typed SceneComponentCodec<TComponent, TState>, which handles the casts: it takes where TComponent : Component and where TState : class, new(), seals ComponentType, StateType and CreateState, and re-declares the six above typed. Capture(TComponent) and Restore(TComponent, TState) are abstract; CanCapture(TComponent), BeforeRestore(TComponent), AfterRestore(TComponent, TState) and FinishRestore(TComponent, TState) are virtual with a working default. Worked example: Custom component codecs.

Type ComponentType / StateType { get; }What it handles and what it maps to. The state type must be a class, since it is populated in place.
bool CanCapture(Component component)Whether the component can be read right now. False captures nothing for it and keeps what the save already holds, which is the answer for one on an object the game switched off.
object CreateState()A fresh, empty instance of StateType, which the loader fills before Restore. The typed base seals it: a state type must be a class with a public parameterless constructor, or the codec is refused at registration.
object Capture(Component component)Read the component into a fresh state object, or null to save nothing.
void BeforeRestore(Component component)Phase 1: make writes safe, applying no saved values. Runs before any of the object's codecs restores, and only for the ticked components whose payload read back: a codec that captured nothing gets no bracket.
void Restore(Component component, object state)Phase 2: write your own payload. No codec touches a sibling here, so order within the phase is irrelevant.
void AfterRestore(Component component, object state)Phase 3: resync what the other writes invalidated, such as warping an agent to the restored position. The enabled flag is written back for you, so a codec never puts it back itself.
void FinishRestore(Component component, object state)Phase 4, in Play mode only: start what has to run on the component as the load leaves it, such as resuming a video. Runs once every object of the load has its saved enabled flags and active state, so test isActiveAndEnabled: an object the load switched on only to restore it is off again here.

SceneComponentCodecs

static

The codec registry. A codec you register replaces the built-in one for that exact type, so you never have to wait for this package to fix or extend one.

void Register(SceneComponentCodec codec)Register yours, replacing any for the same exact type.
bool Has(Type componentType)Whether any codec applies.
SceneComponentCodec For(Type componentType)The codec that applies: an exact registration first, then the nearest base type's, so a subclass is not skipped.