summer-world-saves 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. Keep a persistent Summer World between restarts: checkpoint saves, restore before join, the final save.
When your agent uses it
- Building a persistent World, shared base, farm or realm in a Summer game that must survive server restarts
- Saving and restoring World state with commit_save, load_save, finish_restore, save_requested or finish_snapshot
- Deciding whether progress belongs in a World save or in player data
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
Preview.
- Verified in Local Play: restore of a new World, commit and receipt.
- Not verified: restoring after a real restart. Local Play keeps saves in memory only, so only hosted play proves it.
- Persistent Worlds need hosting support for your game. Check that it is available before you promise it to players.
Overview
Most Summer Worlds are match-scoped: the match ends and its state is gone. A persistent World is a place players come back to, such as a shared base, a farm or a realm. Its authority can stop for maintenance, a crash or a move. A new authority then restores the World from its last save.
The engine never serializes nodes for you. The game decides what one save
holds. It must be one consistent cut: if an item moves from a chest into
an inventory, both sides go in the same save.
This skill extends the Courtyard game from
multiplayer-state: its
match_doc (the coins still on the ground, and the scoreboard) becomes the
World’s saved state.
Steps
1. Declare a persistent World
Inworld.json, change these fields and keep everything else:
recovery_point_seconds(1 to 3600) is the most play you accept losing in a crash. Commit at least that often.snapshot_schemas: exactly one name for your save format in this release. There are no migrations.drain_seconds: 60 to 300.- A save holds at most 16 MiB.
2. Restore before anyone joins
Restore runs right afterSummer.initialize, before waiting for
binding_ready. Players are admitted only after finish_restore succeeds,
so restore is part of becoming ready. Add to authority/main.gd:
_ready(), between Summer.initialize and the binding_ready wait:
match State group after the restore, so it starts
from the restored document.
3. Checkpoint while playing
Mark the World dirty wherever saved state changes. Here that is aftermatch_group.reset(...) in _collect:
- One save at a time.
commit_savetakes the revision you expect to replace, so two overlapping saves would conflict. - Capture once, retry exactly.
- On retryable
world_save_unavailable, resend the same expected revision,save_id, schema, bytes and sequence. - A lost reply may hide a commit that already succeeded.
- On retryable
- The sequence only grows. It continues from the restored save’s
state_sequence, sosave_ids never repeat across restarts. - Stop on non-retryable codes.
world_save_conflict,world_save_corrupt,world_save_incompatible,world_restore_requiredandruntime_fencedmean this authority must not keep writing.
4. Answer the final save request
Before Summer stops, restarts or moves the World, it emitssave_requested
with a deadline. Commit a fresh cut, then acknowledge it with that receipt:
- During the final save, scene processing and timers are frozen; only save operations complete. Never
awaita timer or a frame in this path. - A crash delivers no request, so periodic checkpoints are still required.
- For a planned shutdown,
saves.shutdown_notice_changedgives advance notice; anullnotice means it was cancelled. Use it to warn players (“Server restarts in 5 minutes”) and to finish events that are in progress.
5. Bring players back to the same World
A player returns to a persistent World by its id:Summer.get_world().world_id after the first join, and keep
it, for example in the player’s public player data. A sleeping World wakes
and restores before the player is admitted.
Never call saves.complete() to “save and stop”. It ends the World
permanently.
6. Test in Local Play
Local Play runs a persistent World with an in-memory save store:- Every run starts with no save, so
has_save()is false. - Commits succeed and return receipts.
- Nothing survives the run.
print("WORLD_RESTORED has_save=", saved.has_save()),
and one after each successful commit. Then check:
- the restore marker appears before any player joins;
- a checkpoint commits after state changes;
- there are no
world_save_*errors.
Checklist
-
world.jsondeclareslifetime: persistentand acheckpointpersistence block with one schema. - The authority restores before awaiting
binding_ready, and a failed load stops it. - Checkpoints run at least every
recovery_point_secondswhile the World changes. - Only one
commit_saveis in flight; retries reuse all five arguments. -
save_requestedcommits a fresh cut, then callsfinish_snapshotwith that receipt, without awaiting timers. - Player progress lives in player data, not in the World save.
Common mistakes
See also
summer-player-data— progress that follows a playermultiplayer-state— the shared document this skill savesmultiplayer-project—world.jsonand the authority scenemultiplayer-testing— Local Play runs and markers
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
multiplayer: Start here for Summer multiplayer: how authority, clients, Worlds and Sessions fit, and what comes next.multiplayer-project: Set up a Summer multiplayer project: entry scenes, World and queue files, joining, a first Local Play.multiplayer-state: Authority-owned state in Summer multiplayer: shared and private State groups, Commands, Events.summer-player-data: Save a player’s progress so it follows them to every match: authority load and commit, autosave, safe retries.summer-match-results: End a Summer match: report each player’s win, loss or draw, show results on clients, then close the World.
Source:
library/skills/summer-world-saves/SKILL.md, rendered from summer-engine@4.3.0 on npm.
