save-load is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. Save and load game state: user:// paths, JSON progress vs ConfigFile settings, versioned saves, autosave.
When your agent uses it
- Persisting progress, settings, high scores, checkpoints, or save slots
- Deciding between JSON and ConfigFile for a save or settings file
- Making saves survive game updates with a schema version and migration
Install
summer setup installs every skill for your agent. To add only this one:
claude-code for your agent, such as codex or cursor. See Skills for every option.
The skill
Trigger phrases: “save progress”, “settings menu should remember”, “high scores”, “checkpoints”, “save slots”, “JSON or ConfigFile?”, “saves broke after the update”. Save what the player would be angry to lose, and nothing else. Persist DATA (numbers, ids, flags), never live nodes or scene references.Where saves go
Alwaysuser:// - a writable per-user dir (res:// is read-only in an export).
user://save_0.json- progressuser://settings.cfg- options
res://; it fails in the shipped game.
JSON vs ConfigFile
Default to JSON for game progress, ConfigFile for settings.
Save schema (version it from day one)
A top-levelversion field is the difference between “old saves still load after
an update” and “everyone loses their progress on patch day”.
var_to_str() and restore with str_to_var() -
JSON has no native Vector2/3.
Write and read
Migration (do not skip)
When the schema changes, bumpSAVE_VERSION and upgrade old saves instead of
rejecting them.
Settings with ConfigFile
get_value so a missing key never crashes.
Autosave hooks
- Save on meaningful checkpoints (level end, area transition, shop close), not every frame. Disk writes stutter.
- Save on quit via
_notification:
get_tree().set_auto_accept_quit(false) so you control the quit.
Traps
- Storing a node/
PackedScene/callable in the save = unserializable or huge. Store ids and rebuild. - Writing to
res://- read-only in exports; silently fails or errors. - No
versionfield - the first schema change wipes every player’s save. JSON.parse_stringreturnsnullon bad input; type-check before using it.- Floats round-trip fine; ints may load back as floats from JSON - cast on read
(
int(data["gold"])).
Applying it in Summer Engine
- The save code is a script, usually an autoload (
res://scripts/autoloads/save_manager.gd): create it withsummer_write_file(path=..., content=..., create_only=true), then register it withsummer_project_setting(key="autoload/SaveManager", value="*res://scripts/autoloads/save_manager.gd")(the leading*makes it a singleton). Check it withsummer_get_script_errors. user://is the per-user data dir, outside the project, so do not expectsummer_read_file(a project-file reader) to show a save file. Prove a round trip from inside the game instead: aRunVerificationprobe (seeplaytesting-a-feature) that callssave_game(), changes a value, callsload_game(), andreport()s the restored value.
From a shell
No Summer MCP tools in this session? Run each one as a command; whensummer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.
Related skills
make-game: Orchestrate ‘make me a game’: brainstorm, plan, scaffold, mechanics, art, audio, polish, verify, ship.gdscript-patterns: GDScript conventions: type hints, signals, exports, onready, lifecycle methods, node paths, naming.ui-basics: Build UI: HUDs, menus, health bars, dialogue boxes, Control trees, anchors, containers and themes.
Source:
library/skills/save-load/SKILL.md, rendered from summer-engine@4.3.0 on npm.
