No-CodePersist data straight from the inspector, no scripting.

Variables & components

PersistentVariables

SO

A persistent asset holding a named, typed set of variables authored in the inspector. It derives from PersistentScriptableObject, so the full load / save API is available on the asset. Explained in No-Code.

Read & write values
T Get<T>(string name, T fallback = default)Read a variable, or the fallback when missing or an incompatible type.
bool TryGet<T>(string name, out T value)Read, returning false when missing or incompatible.
void Set<T>(string name, T value)Write, creating it when absent. Writing an equal value-type/string is a no-op that does not re-raise OnChanged. Throws ArgumentException (null/empty name, or null untyped value), NotSupportedException (no registered variable type for T), InvalidOperationException (exists with an incompatible type/shape).
bool TrySet<T>(string name, T value)Write, returning false instead of throwing.
void NotifyChanged(string name)Tell the asset a variable changed, so it saves and its binders and listeners react. Needed only when you mutate a value in place instead of assigning it: an AnimationCurve whose keys you edited, a Gradient you recolored. Assigning through Set or a reference already flags itself, and a name that holds no variable does nothing.
Lists
VariableList<T> GetList<T>(string name)The live list behind a list variable (created empty when absent). Throws ArgumentException (null/empty name), NotSupportedException (no registered type), InvalidOperationException (name exists with a different shape/type).
bool TryGetList<T>(string name, out VariableList<T> list)The list when it already exists, false when it is missing or holds another type. Unlike GetList, it never creates one.
Maps
VariableMap<TKey, TValue> GetMap<TKey, TValue>(string name)The live map behind a map variable (created empty when absent). Throws ArgumentException (null/empty name), NotSupportedException (no registered type), InvalidOperationException (name exists with a different shape/type).
bool TryGetMap<TKey, TValue>(string name, out VariableMap<TKey, TValue> map)The map when it already exists, false when it is missing or holds other types. Unlike GetMap, it never creates one.
Schema & identity
int Count { get; }How many variables the asset holds.
IReadOnlyList<string> Names { get; }Every variable name, in definition order. A fresh copy each time, so adding or removing a variable while you walk it is safe.
string GlobalIdentifier { get; }The asset's stable global id, which is what GlobalPersistedData.Find matches on.
bool Has(string name) / Type TypeOf(string name) / bool IsList(string) / IsMap(string)Presence, value type, and shape of a variable.
string ValueAsText(string name)A variable's current value as text, whatever its type: what a label shows and what a slot summary records. An empty string when there is no such variable, and it never throws. A one-way view for display: read a value back with Get<T>.
string NameOf(string id) / IdOf(string name)Map between a variable's display name and its stable id (IdOf returns null for a variable created at runtime through Set, which has no stable id).
bool Remove(string name) / void RemoveAll()Remove one variable, or all of them.
bool ResetVariable(string name) / bool ResetVariable(params string[] names)Reset one variable, or several, to their authored default. False when there is no authored baseline yet (it is captured on the first scope-in), and for several, when any name given was not reset. A variable created at runtime has no authored default, so it is removed.
Events
event Action<string> OnChangedA variable changed (its name is passed).
event Action OnReloadedThe backing store was rebuilt (after a load/reset): re-fetch any cached list or map.

A reference field points at one variable inside a PersistentVariables asset: drag a variable from its inspector onto the field, or pick it from the dropdown. Each stores the asset plus the variable's stable id, so renaming the variable never breaks the link, and each carries the same identity members (Variables, Id, Name, IsSet, Exists, Reset) listed under VariableRef.

VariableRef

struct

Points at a variable of any type or shape: you name the type at each call. Use a typed reference below when the field should only ever accept one type.

PersistentVariables Variables { get; }The asset this points into.
string Id { get; } / string Name { get; }The variable's stable id, and its current display name (resolved from the id, falling back to the last known name).
bool IsSet { get; } / bool Exists { get; }Whether an asset + variable are assigned; whether that variable currently exists (the typed refs also require the matching type / shape).
bool Reset()Reset the variable to its authored default; false when no asset is assigned, no such variable exists, or no authored baseline has been captured yet.
Type Type { get; }What one entry of the variable holds: a value's type, a list's element type, or the KeyValuePair<,> a map's entries are. Null when it does not exist or its type is not registered.
T Get<T>(T fallback = default) / bool TryGet<T>(out T)Read as T (fallback / false when missing or a different type).
void Set<T>(T) / bool TrySet<T>(T)Write, creating it when absent (TrySet returns false instead of throwing). A no-op while the reference is not fully assigned, as every other member here is; otherwise Set throws like PersistentVariables.Set.
VariableList<T> GetList<T>()The live list (created empty when absent), or null when the variable is not a list of T.
VariableMap<TKey, TValue> GetMap<TKey, TValue>()The live map (created empty when absent), or null when the variable is not a map of those types.

VariableValueRef<T>

struct

Points at a single value of T: Get and Set need no type argument, and the inspector only offers variables of that type. Also carries the identity members of VariableRef.

T Value { get; set; }Shorthand for Get() / Set(value) with the default fallback.
T Get(T fallback = default) / bool TryGet(out T)Read (fallback / false when missing or stored as a different type).
void Set(T) / bool TrySet(T)Write, creating it when absent (TrySet returns false instead of throwing). A no-op while the reference is not fully assigned, as every other member here is; otherwise Set throws like PersistentVariables.Set.
Type Type { get; }The variable's actual stored type (may differ from T if the asset was edited since), or null when missing / unsupported.

VariableListRef<T>

struct

Points at a list of T, read and edited live through List. Also carries the identity members of VariableRef.

VariableList<T> List { get; } / bool TryGetList(out VariableList<T>)The live list, created empty when absent, or null / false when not a list of T.
Type Type { get; }The variable's actual stored element type (may differ from T if the asset was edited since), or null when missing / unsupported.

VariableMapRef<TKey, TValue>

struct

Points at a map, read and edited live through Map. Also carries the identity members of VariableRef.

VariableMap<TKey, TValue> Map { get; } / bool TryGetMap(out VariableMap<TKey, TValue>)The live dictionary, created empty when absent, or null / false when not a map of those types.
Type KeyType { get; } / Type ValueType { get; }The key and value types the variable really holds. They are TKey and TValue unless the variable was changed in the asset after this reference was set up, and null when it does not exist or is not a map.

VariableComponent

abstractMB

Base of the three components below: it holds the variable each one points at, and keeps the component registered with its asset while it is enabled.

VariableRef Variable { get; }The variable this component works on, assigned in the inspector.
protected virtual void OnEnable() / OnDisable()Registration. Call base when you override either, or the component stops following its variable.

VariableBinder

MB

Keeps a variable and a member of another component in sync, in either direction, through an optional value converter when the two types differ.

Inspector: DirectionWhich way values flow, as a BindingDirection.

VariableListener

MB

Raises UnityEvents when a variable changes, so a scene can react with no script.

Inspector: On Changed · On Changed Bool · On Changed Int · On Changed Float · On Changed StringRaised on every change. On Changed carries no argument; the typed ones carry the new value.
Inspector: On Became True · On Became FalseThe edges of a bool.
Inspector: On Equals · Equals ValueRaised when the variable reaches Equals Value.
StringEvent / FloatEvent / IntEvent / BoolEventThe nested UnityEvent<T> types those typed events use.

VariableSetter

MB

Changes a variable from a UnityEvent, so a button or a trigger can write one with no script.

void Apply()Run the configured Operation on the variable.
void SetBool(bool) / SetInt(int) / SetFloat(float) / SetString(string)Write a value straight from a UnityEvent argument.
void Toggle() / Increment() / Add(float amount) / ResetVariable()Flip a bool, add one, add an amount, or put the variable back to its authored default.
Inspector: OperandThe value Set and Add use.

VariableSetter.Operation

enum

What VariableSetter.Apply does to the variable.

Set / Toggle / Increment / Add / ResetWrite the operand, flip a bool, add one, add the operand, or restore the authored default.

BindingDirection

enum

Which way a VariableBinder moves values.

Auto / TwoWay / VariableToTarget / TargetToVariableAuto picks two-way when the bound member can be written, and variable to target otherwise.

VariableList<T>

class

The live list behind a list variable. Editing it raises OnChanged on the owning PersistentVariables and marks the asset dirty, so the change persists. Do not cache it across a load or reset: a reload rebuilds the backing store and a kept reference goes stale, so fetch it again (on OnReloaded, for instance).

Standard IList<T> membersIndexer, Add, Insert, Remove, RemoveAt, Clear, Count, IndexOf, Contains, enumeration, etc.

VariableMap<TKey, TValue>

class

The live dictionary behind a map variable. Editing it raises OnChanged on the owning PersistentVariables and marks the asset dirty, so the change persists. Do not cache it across a load or reset: a reload rebuilds the backing store and a kept reference goes stale, so fetch it again (on OnReloaded, for instance).

Standard IDictionary<TKey, TValue> membersIndexer, Keys, Values, Remove, Clear, Count, ContainsKey, TryGetValue, enumeration, etc.
void Add(TKey key, TValue value)Add a pair. Throws ArgumentException when the key is already present.

Extending

VariableTypeCodec

abstractclassextending

The string round trip that makes a type storable as a variable. Prefer the typed VariableTypeCodec<T>. Worked example: Custom variable types.

abstract string Format(object) / abstract object Parse(string)Write a value as text and read it back.

VariableTypeCodec<T>

abstractclassextending

The codec to implement for your own type. Pair it with [VariableType(type, id)] and it registers itself.

protected abstract string Write(T) / protected abstract T Read(string)The round trip for T. An empty string passed to Read means the default value, and neither may throw on unexpected text.

VariableTypes

static

The registry of the types a variable can hold, and of the stable ids their values are saved under.

void Register(Type, string id, VariableTypeCodec)Add or replace a type by hand. [VariableType] codecs register themselves. Throws ArgumentNullException / ArgumentException on a null or empty argument, NotSupportedException for a collection type (register the element type instead).
bool TryGetCodec(Type, out VariableTypeCodec) / TryGetCodec(string id, out VariableTypeCodec) / TryGetId(Type, out string) / TryGetType(string id, out Type)Look up between the registered types, their save ids and their codecs.
IEnumerable<KeyValuePair<string, Type>> All { get; }Every registered id and its type. Unregistered enums and asset types are left out.
string EnumId(Type enumType)The id an unregistered enum's values are stored under, made on demand. It embeds the enum's full type name, so register an explicit codec for an enum you may later rename.
string AssetId(Type assetType)The on-demand id of an asset type, the token references to its assets are stored under. The value saved is the asset's id from the AssetRegistry, so only registered assets can be saved. As with an enum, the id embeds the type's full name, so the asset type of a shipped variable should be considered fixed.

ValueConverter

abstractclassextending

Turns one type into another so a VariableBinder can drive a member of a different type. Prefer the typed ValueConverter<TFrom, TTo>.

Type From / To { get; }The two ends of the conversion.
object Convert(object)Convert one value.

ValueConverter<TFrom, TTo>

abstractclassextending

The converter to implement. It is discovered automatically; register two, one each way, for a two-way binding.

protected abstract TTo Convert(TFrom value)Convert one value.

ValueConverters

static

The converter registry, plus the built-in number, enum and to-string rules.

void Register(ValueConverter)Add a converter. Throws ArgumentNullException on a null converter.
bool CanConvert(Type, Type) / TryConvert(object, Type, out object) / TryConvert(object, Type, CultureInfo, out object)Ask whether a conversion exists, and run it.

Input & localization

InputBindingPersistence

static

Makes an InputBinding persistable through a variable. Needs the Input System package.

bool ApplyTo(this InputBinding stored, InputAction action, int bindingIndex = 0)Apply a stored binding override onto an action.
bool ApplyBinding(this PersistentVariables, string name, InputAction, int = 0) / CaptureBinding(this PersistentVariables, string, InputAction, int = 0)Apply an action's stored binding, or capture its current one into the variable.
InputActionRebindingExtensions.RebindingOperation RebindAndStore(this PersistentVariables, string name, InputAction, int bindingIndex = 0, Action onComplete = null, Action onCancel = null)Start an interactive rebind and capture the new binding when it completes. You own the returned operation: keep it and call its Cancel in OnDisable or OnDestroy, or the completion callback can run after the object is gone.

LocalePersistence

static

Makes the chosen locale persistable through a variable. Needs the Localization package, and localization initialized first (await LocalizationSettings.InitializationOperation), or every call answers false.

bool ApplyLocale(this PersistentVariables, string name) / CaptureLocale(this PersistentVariables, string name)Apply the stored locale as the active one, or capture the active one into the variable.
bool SelectLocale(this PersistentVariables, string name, LocaleIdentifier locale)Set a chosen locale and store it.

Persistence components

PersistenceComponent

MBabstract2.0

Base for the no-code persistence components (the control and the listener). It holds which objects the component works on, so a button that saves one object and a panel that reacts to it cannot drift apart. See the guide's persistence components.

PersistenceTargetMode TargetMode { get; }Which objects this component works on.
PersistentScriptableObject Target { get; }The object this component works on, or null in AllObjects mode.
bool IsGlobal { get; }Whether this component works on every persistent asset rather than one.
protected PersistenceManager ResolveManager()The manager of Target, or null with a loud error when nothing is assigned. Never throws. An unassigned target is never read as "all objects": it is reported instead, so a forgotten field cannot turn a one-object button into a save-everything button.
protected void ReportOnce(string message) / ReportMissingTarget()Report an error, or that this component has nothing to act on, once however often the component is triggered.
Enums
PersistenceTargetModeOneObject: the one object assigned on the component. AllObjects: every persistent asset currently in scope.

PersistenceOperationControl

MB2.0

Everything a button can do to saved data, as methods a UnityEvent can call: saving, loading and clearing, choosing the slot, and the slot housekeeping a save menu needs. Nothing here needs a script. Set Target Mode to One Object to act on one object, or to All Objects for the global operations.

In play mode every method here is safe to call at any time: an operation that cannot run right now is refused and reported through the usual results and logs, never thrown at the caller. Every method except KeepLocalSave and KeepRemoteSave throws InvalidOperationException in the editor only when called outside play mode.
Save, load, clear
void Save() / Load()Save now; load now, replacing what the object currently holds with what was saved.
void Clear()Erase the saved data, leaving the object holding what it has until the next load.
Conflicts
void KeepLocalSave() / KeepRemoteSave()Answer a save conflict by keeping the save made on this device, or the one made elsewhere, discarding the other. In All Objects mode every object waiting on one is answered together, which is how a player is asked once.
Slots
void SetSlot(string slot)Switch to slot: the current slot is saved on the way out and the new one is loaded on the way in. In All Objects mode this sets the global slot, so every slotted object moves together.
void NewSlot()Start a new game: switch to a slot nothing has been saved to yet, so the object begins on its authored values.
void LoadLatest()Continue: switch to the most recently saved slot. Does nothing when nothing has been saved yet.
void DeleteSlot(string slot)Delete a slot's saved data outright.
void CopySlot(string fromSlot, string toSlot) / RenameSlot(string fromSlot, string toSlot)Copy one slot's saved data onto another, overwriting it; or move it there, leaving the first empty.
void SaveToRing()Write the current data into the quick save ring, without leaving the slot the game is playing on.
Inspector
Slot RegistryThe slot registry backing NewSlot, LoadLatest and SaveToRing. Only needed for those; leave it empty otherwise.
New Slot PrefixWhat a new game's slot name starts with; NewSlot appends the first free number, so the first new game lands on save 1.
Ring Prefix / Ring CountWhat every quick save slot's name starts with (give it something no ordinary slot uses, so the ring stays separate from the player's own saves), and how many to keep before the oldest is overwritten.

PersistenceOperationListener

MB2.0

Everything that happens to saved data, as UnityEvents: a save or load starting and finishing, whether it worked, readiness, the shutdown drain, and the slot events a save menu refreshes on. Wire a panel or a message to them without a script. Set Target Mode to One Object to follow one object, or to All Objects to follow every one of them.

Nothing here throws: a handler that does is reported and the component carries on, though the handlers wired below it on the same event are skipped. An operation refused before it ran (nothing to do, or another one in flight) raises no failure event.
Inspector events (the component's whole surface, wired in the inspector)
On Before Load / On LoadedA load is starting; a load succeeded. A first run with nothing saved still fires On Before Load but not On Loaded, and a save that could not be read fires On Load Failed.
MessageEvent On Load FailedA load failed, carrying the result's message so the reason wires straight into a text field.
On Before Save / On Saved · MessageEvent On Save FailedThe same three for saving.
On Before Clear / On Cleared · MessageEvent On Clear FailedThe same three for clearing.
On ReadyThe data became safe to read and save. Fires on enable too when it already is, so a panel opened later is not left waiting.
On Not ReadyThe data stopped being safe to read (a clear, a slot change, leaving scope). Fires on enable too when it already is not, so a panel opened later does not show the ready state over unready data.
FlagEvent On Busy ChangedTrue while an operation is running, false when it finishes: a loading spinner binds straight to this.
SlotEvent On Slot Updated / On Slot Deleted / On Slot CopiedA slot was saved to, deleted, or copied onto, carrying its name (the destination slot for a copy). A rename raises the copy event with the new name, then the delete event with the old one. In One Object mode only this object's own slot changes are reported, so a menu bound to one save does not refresh on every other object's saves.
On Drain Started / On Drain CompletedThe game is quitting and unsaved changes are being written, then that wait is over. Show a "saving, do not close" message on the first. Raised whatever the target mode: unlike the slot events, the drain is not filtered per object, and a menu wants it either way.
Nested event types
MessageEvent : UnityEvent<string>Carries a message, so a failure reason reaches a text field with no glue.
SlotEvent : UnityEvent<string>Carries a slot name.
FlagEvent : UnityEvent<bool>Carries whether the thing it reports is now true.

PersistenceConflictListener

MB2.0

Puts a save conflict into your own UI: when a load finds that this device and another one both saved the same object without seeing each other's changes, it shows your panel, fills in both saves, and answers the conflict from your panel's buttons. Your UI takes a pad, and its look, from your own EventSystem and styling. GameObject > Persistent Asset > Conflict Prompt (uGUI) builds a panel with this component already wired. It watches every manager.

A manager asks only when its policy is Ask, and this component in the scene, enabled, is what makes it wait for an answer. Answers are ignored for half a second after a question goes on screen, so a button press meant for the screen before it cannot discard a save. Nothing here throws.
Properties and methods
bool IsAskingWhether a conflict is waiting to be answered, so your panel is on screen. Gate your own input on it.
void KeepLocal() / KeepRemote()Keep the save made on this device, or the one made elsewhere. Wire each to a button. Does nothing when no question is on screen or it went up less than half a second ago.
Inspector
Answer Every ObjectAnswer every object waiting on a conflict with the one choice, rather than asking again per object. On by default.
Newest TagMarks whichever of the two was saved last, in its summary.
Preview FieldsValues read from both saves and added to each summary, each a label and the field to read (nested with dots), so the player compares "Chapter 5" with "Chapter 3" rather than two dates.
FlagEvent On Asking ChangedTrue when a question goes on screen, false once no conflict is waiting: bind your panel's SetActive to it.
MessageEvent On Local Summary / On Remote SummaryEach save as lines of text: when it was written, how long ago, whether it is the most recent, then the preview fields. Both keep the same number of lines, so two text fields side by side line up.
On Local Newest / On Remote NewestA question went on screen and that side is the more recent. Select its button here, so a pad starts on it.

PersistenceDrainListener

MB2.0

Puts the wait at quit into your own UI: while a save is still in flight as the game closes, it shows your "saving your progress" panel, and can offer a button abandoning the wait. GameObject > Persistent Asset > Drain Display (uGUI) builds a panel with this component already wired.

The panel appears only once the wait outlasts half a second, and a panel enabled while the wait is already running shows it too. ForceQuit() is ignored for half a second after the button is offered. Nothing here throws.
Properties and methods
bool AllowForceQuit { get; set; }Whether the button abandoning the wait is offered at all.
void ForceQuit()Abandon the wait and let the game close, losing whatever had not been written yet. Wire it to the button. Does nothing unless the button is offered and has been for half a second.
Inspector
Allow Force QuitOffer the button once the wait has lasted Force Quit Delay. Off by default.
Force Quit DelayHow long the wait must last before the button is offered, in seconds. 10 by default.
FlagEvent On Showing ChangedTrue once the wait has lasted half a second, false when it is over: bind your panel's SetActive to it.
FlagEvent On Force Quit OfferedTrue once the button is offered, false when the wait is over: bind the button's SetActive to it.
On Force Quit ReadyThe button was just offered. Select it here, so a pad lands on it.

Save menu

PersistentVariablesSlotRegistry

SO2.0

Lists the saved slots of one PersistentVariables asset, with a summary of the variables you pick, so a save menu can show every slot and what is in it without loading any of them. Everything is set in the inspector: point it at the variables asset, tick the variables to record, and optionally have it capture a thumbnail on every save. Create > Persistent Asset > Variables Slot Registry. It is a PersistentSlotRegistry<PersistentVariables, VariablesSlotInfo>, so Entries, TryGet, TryGetLatest, LatestSlot, SavedSlots, NextRingSlot and NextFreeSlot come from the base.

It saves itself and stays out of slots (it is the thing that lists them), so give it its own persistence manager rather than sharing the one its variables use.
PersistentVariables Variables { get; }The variables asset whose slots this lists.
Inspector
VariablesThe variables asset whose slots this lists. A project with several of them gives each its own registry, so leaving this empty records none.
Captured VariablesThe variables to record into every slot's summary, by name: a menu row then shows them without loading the slot. Leave empty to record only the slot name and its save time.
Capture Thumbnail / Capture FromCapture a preview image on every save, from the camera carrying the tag you pick (which leaves out any UI drawn over it), or from the whole screen when no tag is set. The capture is asynchronous, so the entry is recorded at once and the preview lands on it when the capture finishes.
Thumbnail Max Size / Thumbnail FormatLongest side of the stored thumbnail in pixels, 256 by default (zero keeps the full size, which makes the registry's own save much larger), and its ScreenshotFormat, Jpg by default.

VariablesSlotInfo

struct2.0

What a PersistentVariablesSlotRegistry records for one slot: the value each captured variable held when that slot was last saved, as text.

IReadOnlyList<string> Names { get; }The captured variables, in the order the registry lists them.
string Value(string name, string fallback = "")What name held when this slot was saved, or the fallback when it was not captured. Text rather than the variable's own type, because this is what a menu row displays.

SlotList

MB2.0

Turns a PersistentVariablesSlotRegistry into an actual menu: it instantiates one row per saved slot under a parent and hands each row its slot, so a save menu is inspector work. Put the row prefab's own wiring on SlotListRow, which the binder fills in. The list rebuilds itself whenever a slot is saved, deleted or copied, and again when the registry's own manager finishes loading, so a menu opened before the player has ever saved fills in as soon as the registry arrives. Nothing has to be refreshed by hand.

IReadOnlyList<SlotListRow> Rows { get; }The rows currently shown, in the order the registry lists them. A read with a slot change pending runs that rebuild now rather than waiting for the frame, so it instantiates and destroys rows and raises On Rebuilt.
void Rebuild()Rebuild the list from the registry now. Called on enable, on every slot change, and when the registry's manager finishes a load. Never throws: a missing registry or row prefab is reported once and leaves the list empty.
Inspector
Registry / Row PrefabThe registry listing the slots to show, and the row to instantiate once per saved slot (it should carry a Slot List Row component).
Row ParentWhat the rows are parented to. Leave empty to use this object.
On RebuiltRaised after the list is rebuilt, for anything that has to react to the count changing (an empty-state message, a layout rebuild).

SlotListRow

MB2.0

One row of a SlotList's list: it receives the slot it stands for and raises what the row's own widgets bind to, so a row is built from labels, an image and buttons with no script. Everything the row shows arrives through its events when the list is built. Its buttons then act on Slot, which a persistence operation control on the same row can be handed through its slot methods.

string Slot { get; }The slot this row stands for, once the list has built it.
Inspector: Screenshot PlaceholderWhat On Screenshot goes back to once this row has shown a thumbnail and the slot it now stands for has none. A row that never showed one keeps the image it was authored with.
void Bind(SlotEntry<VariablesSlotInfo> entry)Fill this row in from the entry. The list binder calls it; a row rarely needs to. Never throws.
void Activate()Press this row, raising On Activated with the slot it stands for. Wire the row's own button to it. It does nothing until the list has bound the row to a slot. Never throws.
Inspector events
TextEvent On Slot / On Saved TimeThe slot's name, for the row's title; and when it was last saved, formatted with Saved Time Format.
SpriteEvent On ScreenshotThe slot's thumbnail, or Screenshot Placeholder once this row has shown one and the slot it now stands for has none. A row that never showed a thumbnail keeps the image it was authored with.
TextEvent On ActivatedRaised with this row's slot when Activate runs. Wire a button on the row to Activate, and this event to a persistence operation control's SetSlot, and the row loads the slot it stands for.
Inspector
Saved Time FormatHow the saved time is written, in .NET date format (g is the short date and time in the player's own culture). An unusable format falls back to the invariant culture's own general format.
Variable LabelsA captured variable to show, by name, plus where to show it. Add one per label the row has.
Nested types
TextEvent : UnityEvent<string>Carries one of the row's texts: its slot name, its saved time, or a captured variable's value.
SpriteEvent : UnityEvent<Sprite>Carries the row's preview image, or the placeholder when the slot it stands for has none.
VariableLabel · string name, TextEvent onValueOne captured variable shown by this row: the name it is spelled with on the registry, and where its value goes.

Attributes

Attributes

attr
[VariableType(Type type, string id)]
Type Type { get; }, string Id { get; }
Register a No-Code variable codec for a type, saved under a stable id (see value converters).