# SaveManager Save, load and migrate persisted Properties ```{raw} html ▶ Run in browser ``` **Tags:** `basics` `save` `load` `persistence` `property` A player disc carries its position, score and colour as ``Property(persist=True)`` values. S snapshots the whole tree to slot1 through ``SaveManager`` and L loads it back and applies it, restoring exactly the persisted state. The player class is at ``__save_version__ = 2`` and ships a ``__migrate_save__`` hook that upgrades a version-1 payload (which stored the score under an old name) on apply. Saves land in a fresh ``tempfile.mkdtemp()`` directory so this example never writes into the repository; a real game would point ``SaveManager`` at its own saves directory under the user's data dir instead. ## What it demonstrates - `Property(persist=True)`: only flagged Properties enter the snapshot. - `SaveManager(save_dir)`: `save(root, "slot1")`, `load("slot1")`, `apply(root, data)`. - Restoring live state: position, score and colour snap back on load. - `__save_version__` + `__migrate_save__(values, from_v, to_v)`: upgrading an old payload on apply (exercised by the selftest). Controls: Arrow keys - Move the player SPACE - Score points C - Cycle the player colour S - Save to slot1 L - Load slot1 and apply it ESC - Quit Run: uv run python examples/features/basics/save_load.py Headless self-check: uv run python examples/features/basics/save_load.py --test ## Source ```{literalinclude} ../../examples/features/basics/save_load.py :language: python :linenos: ```