Save / Load¶
Partial today. The only persisted state is rune discovery + palace slot assignments via UPlayerRuneKnowledge. Full level-state save (puzzle progress, runeable object positions, current sentences) is not implemented.
What works today¶
UPlayerRuneKnowledge is a USaveGame covered in detail in Memory palace. Persists:
DiscoveredRunes— what the player has encountered.RuneToSlotMap— palace slot assignments.bHasVisitedPalace,bHasUsedWorldOrb— narrative gates.
Triggered:
SaveKnowledge()is called explicitly when the palace assigns new runes. No autosave timer.LoadKnowledge()is called byAMemoryPalace::GetPlayerKnowledge()lazily on demand.ResetKnowledge()zeroes everything for new game / debug.
Single save slot (UPlayerRuneKnowledge::SaveSlotName is a single string).
Dev workflow (PIE and local saves)¶
When testing discovery or palace persistence:
- Trigger a save — interact with the memory palace flow that calls
SaveKnowledge()(see Memory palace). - Find save files — on Windows, editor and PIE writes go under
Saved/SaveGames/in the repo (platform path varies on other targets). - Wipe for a clean test — close PIE, delete the relevant
.savfiles inSaved/SaveGames/, then PIE again. Without this, old discovery state can mask regressions. - Debug keys — see Debug toggles for in-game test shortcuts.
Full level-state save is not implemented; wiping saves only affects player rune knowledge and palace assignments today.
What does not work today¶
The TDD's "Save / Load" section describes the full target shape. Below is the gap between the spec and the code:
| Spec | Status |
|---|---|
| Player rune knowledge | shipped |
| Palace slot assignments | shipped |
| Per-level puzzle state (which calculators have been solved) | not implemented |
Per-runeable object current noun (so a TREE IS ROCK survives reload) |
not implemented |
| Active sentences and their effects | not implemented |
| Player position and camera state | not implemented |
| Save slot picker / multiple slots | not implemented |
| Cloud save | out of scope |
If the player saves mid-puzzle and reloads, the puzzle resets to its level-default state. Discovery is the only thing that follows them.
Why this is the right scope today¶
The demo target is short enough that puzzle-level persistence isn't required. A reload begins the current level fresh. Discovery has to persist because the memory palace is the long-term progression bar.
When level-state save lands (post-Gate-3 per the TDD), the shape will look like:
UCLASS()
class URephraseLevelSave : public USaveGame
{
UPROPERTY(SaveGame) FName LevelName;
UPROPERTY(SaveGame) TArray<FRuneableSnapshot> RuneableSnapshots;
UPROPERTY(SaveGame) TArray<FCalculatorSnapshot> CalculatorSnapshots;
UPROPERTY(SaveGame) FTransform PlayerTransform;
UPROPERTY(SaveGame) FName PlayerCurrentZone;
};
Where FRuneableSnapshot carries (actor name, current noun, custom physics state) and FCalculatorSnapshot carries (actor name, slot contents by index, last modified time). Tracked under Plan/DevelopmentPlan.
Source files¶
Source/Rephrased/PlayerRuneKnowledge.hSource/Rephrased/MemoryPalace.h(the save/load consumer today)
Known constraints¶
UPROPERTY(SaveGame)is the marker every persistable field needs. Future save classes must remember it — fields without it serialize as defaults on reload.USaveGamecontent goes to platform-specific user save directories. On Windows that'sSaved/SaveGames/; on console targets it's the platform vault. Don't write game state outsideUSaveGame— it won't survive certification.- No save versioning today. When the schema changes, old saves break. Add a version int to the save class before shipping.
Change history¶
- 2026-05-23 — Gabriel Li — PIE save location and wipe procedure for local testing.
- 2026-05-08 — Gabriel Li — Added baseline change history section for weekly wiki maintenance.