Skip to content

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 by AMemoryPalace::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:

  1. Trigger a save — interact with the memory palace flow that calls SaveKnowledge() (see Memory palace).
  2. Find save files — on Windows, editor and PIE writes go under Saved/SaveGames/ in the repo (platform path varies on other targets).
  3. Wipe for a clean test — close PIE, delete the relevant .sav files in Saved/SaveGames/, then PIE again. Without this, old discovery state can mask regressions.
  4. 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_Demo/PlayerRuneKnowledge.h
  • Source/Rephrased_Demo/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.
  • USaveGame content goes to platform-specific user save directories. On Windows that's Saved/SaveGames/; on console targets it's the platform vault. Don't write game state outside USaveGame — 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.