Documentation index for AI agents (llms.txt) A Markdown version of every page is available: request the page's source under /docs/, follow the "alternate" link in this page's head, or start from /llms.txt.
Visual Script logo Scripting API

Custom serializers#

A Serializer converts the save snapshot to text and back. Visual Script includes Unity JSON; a custom subclass adds another format to Save settings.

The interface#

Derive from SerializerBase and implement the round trip. This outline omits the format-specific conversion:

[Title("My Serializer")]
[Serializable]
public class SerializerMyFormat : SerializerBase
{
    public override string Serialize(object value) { /* … */ }
    public override object Deserialize(string data, Type type) { /* … */ }
}

The save system passes the expected Type to Deserialize, because the data may not carry enough information to reconstruct it.

When to write one#

Use a custom serializer when the stored format needs to satisfy one of these requirements:

Reason Use when
Size A compact format meaningfully reduces large saves.
Interoperability An external tool or server needs to read the data.
Polymorphism You need type handling Unity's serializer doesn't offer.
Migration Reading an older format written by a previous system.

Use the built-in serializer unless the project has a specific format requirement. Changing formats affects every existing save.

Changing the serializer invalidates existing saves

A serializer can't read an existing save unless it supports that save's format. Switching formats without a migration path makes existing saves unreadable, including those used for testing.

If you must switch after shipping, keep the old serializer available and detect which format a save is in before choosing one.

Requirements#

The format must support the values the save system stores:

  • Unity types — vectors, quaternions, colors, and the framework's own structs.
  • Polymorphic data — Memories and variable values are stored through base-class references, so the concrete type must survive the round trip.
  • Nested objects and arrays, several levels deep.
  • Null values, both in fields and array entries.

Check polymorphic data before choosing a library. A serializer that writes only {"x":1,"y":2} for a base-class reference loses the concrete type, so loading can produce the wrong type or no object.

Determinism#

Prefer a serializer that produces the same output for the same input. This makes it easier to compare two snapshots during debugging because changes in the text reflect changes in saved state.

When dictionary-key order varies between writes, comparisons can show differences even when the saved values haven't changed.

Testing#

Round-trip the representative and failure cases:

  • An empty save.
  • A save containing every memory type.
  • A save containing every variable value type.
  • Nulls in arrays and object fields.
  • Deeply nested data.
  • Text with quotes, newlines, and non-ASCII characters.
  • A save written by a previous version of your game.

The previous-version case detects format changes before they invalidate shipped saves.

Interaction with encryption#

Serialization happens first, then encryption. Your serializer always sees plain data and never needs to know whether encryption is enabled.

Where to go next#

Visual Script logoVisual Script © Catsoft Works 2026. All rights reserved.