brackets-curlyJSON Serialization

For saving more advanced data structures, you can serialize them to JSON and store them in the Save system.

CSL can serialize certain data structures into JSON for you. This is most useful when you want to save a “bundle” of related fields (like player progress, upgrades, unlocks, etc) without managing lots of separate save keys.

Under the hood, this uses the Save system's JSON APIs:

  • Save.set_json(player, key, value)

  • Save.try_get_json(player, key, out) -> bool

circle-info

JSON save/load is per-player (it takes a player). Game-wide save currently supports strings + ints only.

What gets saved?

Only fields marked with @ao_serialize are included in the JSON.

Player_Progress :: class {
    version: s64 @ao_serialize;

    xp: s64 @ao_serialize;
    level: s64 @ao_serialize;

    unlocked_skins: [..]string @ao_serialize;
}

Saving JSON

Save the whole structure under one key:

Loading JSON (with defaults)

Save.try_get_json returns false if the key is missing or the saved JSON can't be parsed into your current structure.

circle-exclamation

Versioning & migrations

If you expect your JSON schema to change, include a version field in the structure and migrate after load.

Best practices for staying compatible:

  • Prefer adding new fields (old JSON often still parses; fill in defaults after load)

  • Avoid renaming/removing fields (can cause parse failures)

  • If you need a hard break, consider saving under a new key (e.g. "progress_v2") and keeping a fallback loader

Migration Example:

When to use JSON vs simple keys

  • Use simple keys (Save.set_int, Save.set_string, etc) for a handful of values you read/write often.

  • Use JSON when you want to store a cohesive structure (progress, loadouts, unlocks) and keep your save logic centralized.

Last updated