From 2f222fe42c3372a3a2ad9dd22b7b781d3b3f1669 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 4 Apr 2026 10:15:54 -0700 Subject: [PATCH] Fix save editor showing wrong name for orphaned save slots Players.gsi could fall out of sync with save files during cloud sync because the saveSlotWritten event only tracked the slot file and History.gsi for incremental upload, not Players.gsi. This caused slots without a matching Players.gsi entry to display the first player's name due to a fallback to index 0. - Track Players.gsi in saveSlotWritten handler for incremental uploads - Remove broken fallback to player index 0 in name resolution - Hide save slots with no Players.gsi entry from the save editor UI --- src/core/cloud-sync.js | 1 + src/core/savegame/index.js | 18 ++++-------------- src/lib/SaveEditorPage.svelte | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/core/cloud-sync.js b/src/core/cloud-sync.js index 7c0e452..e11f3fc 100644 --- a/src/core/cloud-sync.js +++ b/src/core/cloud-sync.js @@ -100,6 +100,7 @@ export async function initCloudSync() { window.addEventListener('opfs-save-slot-written', (e) => { trackWrite(getSaveFileName(e.detail.slot)); trackWrite(HISTORY_FILE); + trackWrite(PLAYERS_FILE); }); window.addEventListener('opfs-save-state-changed', () => { diff --git a/src/core/savegame/index.js b/src/core/savegame/index.js index 2651a1a..db69714 100644 --- a/src/core/savegame/index.js +++ b/src/core/savegame/index.js @@ -126,14 +126,8 @@ export async function listSaveSlots() { // The playerId in the save file corresponds to an index in Players.gsi // Actually, we need to match by looking at order - player names are stored // in order of most recently played, so we just use the index - if (playersCache && playersCache.players.length > 0) { - // Find player by matching the slot with Players.gsi order - // For now, just use the first player if available - // In reality, we'd need to match by player_id - const playerIndex = i < playersCache.players.length ? i : 0; - if (playersCache.players[playerIndex]) { - slot.playerName = playersCache.players[playerIndex].name; - } + if (playersCache && i < playersCache.players.length && playersCache.players[i]) { + slot.playerName = playersCache.players[i].name; } } } catch (e) { @@ -168,12 +162,8 @@ export async function loadSaveSlot(slotNumber) { const players = await loadPlayers(); let playerName = null; - if (players && players.players.length > 0) { - // Use slot index as a simple mapping - const playerIndex = slotNumber < players.players.length ? slotNumber : 0; - if (players.players[playerIndex]) { - playerName = players.players[playerIndex].name; - } + if (players && slotNumber < players.players.length && players.players[slotNumber]) { + playerName = players.players[slotNumber].name; } return { diff --git a/src/lib/SaveEditorPage.svelte b/src/lib/SaveEditorPage.svelte index 04170e1..5a359ae 100644 --- a/src/lib/SaveEditorPage.svelte +++ b/src/lib/SaveEditorPage.svelte @@ -311,7 +311,7 @@ { id: Actor.LAURA, name: ActorNames[Actor.LAURA] } ]; - $: existingSlots = slots.filter(s => s.exists); + $: existingSlots = slots.filter(s => s.exists && s.playerName); $: currentSlot = slots.find(s => s.slotNumber === selectedSlot); // Update local state when currentSlot changes