Lesson 212: Steam Cloud Save Slot Label Receipt After Branch Promotion (2026)

Direct answer: After you promote playtest → fest_public, file save_slot_label_receipt_v1.json and a per-surface save_slot_label_map on BUILD_RECEIPT so UI slot numbers, on-disk filenames, and Steam Cloud remote names stay aligned for each build_label. This is the first H1 2026 player trust milestone—continuing from Lesson 211 Q4 capstone (scope/URL isolation) into save integrity before telemetry and crash correlation lessons.

Lesson hero for Steam Cloud save slot label receipt after branch promotion

Why this matters now (July 2026 branch + Cloud week)

July 2026 micro-studios merge playtest depots into fest_public the same week many teams enable Steam Cloud mid-cycle. Two failures stack:

  1. Slot label drift — Menu still says Slot 1 while code writes save_slot_b after a refactor (save-slot case study).
  2. Cloud remote wins — Stale playtest remote overwrites newer fest local (Steam Cloud overwrite help).

Wednesday smoke catches boot paths; it rarely runs a three-slot save → quit → load matrix on installed Steam builds. Playtest isolation separates depots—this lesson adds label maps per surface so isolation receipts from Lesson 211 do not green-light wrong persistence keys. For Godot path roots per branch, pair playtest save isolation preflight and queued Lesson 238.

Beginner path (40-minute first pass)

Step Action Success check
1 List UI labels vs disk keys for each slot No orphan UI label
2 Export save_slot_label_map per build_label JSON committed
3 Run save/load on installed fest build Slot 2 round-trip OK
4 Match Steamworks Cloud filenames to map Names identical
5 File save_slot_label_receipt_v1.json All S1–S6 pass
6 Add BUILD_RECEIPT columns Row visible in Thursday review

Time: ~40 minutes with an existing three-slot menu; 55 minutes first Cloud enable + promotion week.

Developer path (gates S1–S6)

Gate Check Fail when
S1 save_slot_label_map exists per surface Missing playtest or fest_public row
S2 UI label → persistence key bijection Two UI labels → one key
S3 build_label bump updates map hash Map stale after merge
S4 Installed Steam round-trip matrix Any slot loads empty/wrong chapter
S5 Steam Cloud file list matches map Remote name ≠ local basename
S6 save_slot_label_receipt_v1.json promotion_allowed: false

Per-surface save_slot_label_map

Maintain one map file per surface (not one global file that silently mixes playtest and fest):

{
  "schema": "save_slot_label_map_v1",
  "build_label": "fest-demo-2026-10-rc1",
  "surface": "fest_public",
  "slots": [
    { "ui_label": "Slot 1", "persistence_key": "save_slot_a", "cloud_filename": "save_slot_a.sav" },
    { "ui_label": "Slot 2", "persistence_key": "save_slot_b", "cloud_filename": "save_slot_b.sav" },
    { "ui_label": "Slot 3", "persistence_key": "quicksave", "cloud_filename": "quicksave.sav" }
  ],
  "map_hash": "sha256:…"
}

Pin playtest separately:

{
  "schema": "save_slot_label_map_v1",
  "build_label": "playtest-2026-07-rc1",
  "surface": "playtest_invite",
  "slots": [
    { "ui_label": "Slot 1", "persistence_key": "pt_slot_1", "cloud_filename": "pt_slot_1.sav" }
  ]
}

Rule: Never reuse fest_public persistence keys on playtest surfaces—even if filenames look similar.

Promotion-day round-trip matrix (S4)

Run on two Windows accounts when Cloud is enabled:

Slot Save action Quit Relaunch Expected
1 New game → floor 3 Yes Load Slot 1 Floor 3
2 New game → floor 7 Yes Load Slot 2 Floor 7
3 Quick save at boss Yes Load Slot 3 Boss state

Record screen capture + log line save_label=Slot 2 key=save_slot_b build_label=….

Steam Cloud crosswalk (S5)

Steamworks field Must equal
Cloud filename cloud_filename in map
save_schema_version Bumped when key renames
Conflict policy Documented in FAQ

If Cloud was enabled mid-cycle, follow Cloud overwrite help before S6—label maps alone do not fix stale remotes.

save_slot_label_receipt_v1.json

{
  "schema": "save_slot_label_receipt_v1",
  "build_label": "fest-demo-2026-10-rc1",
  "surfaces": {
    "playtest_invite": {
      "map_path": "release-evidence/saves/PLAYTEST_SAVE_SLOT_LABEL_MAP.json",
      "round_trip_pass": true
    },
    "fest_public": {
      "map_path": "release-evidence/saves/FEST_SAVE_SLOT_LABEL_MAP.json",
      "round_trip_pass": true
    }
  },
  "steam_cloud": {
    "enabled": true,
    "file_list_matches_map": true,
    "schema_version": 2,
    "conflict_policy": "local_first_on_schema_bump"
  },
  "paired_receipts": {
    "playtest_surface_isolation": "release-evidence/playtest/PLAYTEST_SURFACE_ISOLATION_RECEIPT.json",
    "playtest_isolation": "release-evidence/playtest/PLAYTEST_ISOLATION_RECEIPT.json"
  },
  "gates": {
    "S1_maps_per_surface": "pass",
    "S2_bijection": "pass",
    "S3_map_hash_after_promotion": "pass",
    "S4_installed_round_trip": "pass",
    "S5_cloud_filename_parity": "pass",
    "S6_receipt": "pass"
  },
  "promotion_allowed": true
}

Pin under release-evidence/saves/SAVE_SLOT_LABEL_RECEIPT.json.

BUILD_RECEIPT columns (H1 arc start)

Column Source
save_slot_label_receipt This lesson
save_slot_label_map_fest Fest map path + hash
save_slot_label_map_playtest Playtest map path + hash
steam_cloud_sync_receipt Optional; required if Cloud on
build_label VERSION spine
playtest_surface_isolation_receipt Lesson 211 when playtest active

Thursday row review — add Saves section: map hash + round-trip pass/fail.

Engine notes (same symptom, different keys)

Engine Persistence lane Map field
Godot user://save_slot_a.save persistence_key = basename
Unity Application.persistentDataPath Full relative path in map
GameMaker ini section + filename Section name in map
GDevelop Storage key string Exact key in map
Ren'Py persistent fields Field name in map

Cross-link engine helps when round-trip fails after map looks correct: GameMaker save path, GDevelop path, Construct NW.js.

Proof table (promotion week)

Surface build_label Slot 2 round-trip Cloud list match Promote?
playtest_invite playtest-2026-07-rc1 pass n/a (local-only OK) soak
fest_public fest-demo-2026-10-rc1 pass pass after S6

Key takeaways

  1. Branch promotion without a map diff recreates “Slot 1 empty” threads—not gameplay bugs.
  2. One map per surface—playtest keys must not alias fest keys on the same App ID.
  3. Installed Steam matrix beats editor-only QA for save trust.
  4. Cloud filenames are part of the label map—not an afterthought.
  5. save_slot_label_receipt_v1.json is the H1 arc entry receipt—telemetry and crashes build on this row next.
  6. Pair narrative recovery with save-slot case study—this lesson is the course implementation.
  7. 20-free save/cloud resource bookmarks tools; receipts prove you used them.
  8. Lesson 211 surface isolation does not replace slot maps—run both before fest traffic.

Prerequisites

Common mistakes

  • Updating UI strings without persistence key migration.
  • One global map mixing playtest + fest rows.
  • Testing saves only in editor dist folder.
  • Enabling Cloud without Steamworks file list update.
  • Skipping map hash bump on build_label promotion.

Troubleshooting

Symptom Lane
Slot 1 empty after patch S2 bijection + case study
Progress reset after Cloud on Cloud overwrite help
Wrong chapter on fest only Depot label mismatch help
Playtest save on fest URL Lesson 211 surface receipt

Mini exercise (55 minutes)

  1. Intentionally rename Slot 2 UI label without key change—confirm S2 fails.
  2. Fix map; pass round-trip on installed build.
  3. Add Cloud filename column; run two-account sync.
  4. File receipt JSON; add BUILD_RECEIPT row.
  5. Link receipt path in Thursday review template.

Continuity — H1 2026 arc (212–217)

Lesson Receipt focus
212 (this) Save slot labels + Cloud crosswalk
213 Privacy-safe telemetry session
214 Crash symbolicate + build_label
215 Refund signal dashboard
216 AI dialogue patch moderation
217 H1 capstone

Prior arcs complete: July H2 200–205, Q4 206–211.

Next: Lesson 213 — privacy-safe telemetry session receipt.

FAQ

Does this replace save_slot_recovery_receipt from the case study?
No—recovery receipt documents post-incident proof. This lesson’s receipt is pre-promotion gate for the next merge.

Local-only fest demo?
Set steam_cloud.enabled: false in receipt; S5 = n/a but S4 matrix still required.

Same App ID for playtest and fest?
Yes—maps must differ by surface and persistence_key, not by hoping players use different machines.

Unity Addressables saves?
Map the logical slot to the serialized file or PlayerPrefs key actually written—document in persistence_key.


Pin slot labels on BUILD_RECEIPT before the next branch promotion—players forgive rough combat; they rarely forgive “lost” saves.