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
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.
Save.try_get_json returns false if the key is missing or the JSON string is malformed. If the key exists but the structure has changed (new fields added, old fields removed), it returns true with missing fields zero-filled.
If you rename/remove serialized fields, old JSON may fail to parse and you'll drop into your defaults path. Plan migrations early (see below).
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.
Standalone JSON API
You can also serialize/deserialize JSON independently of the Save system (e.g. for logging, networking, or custom storage):