fix(player): keep origin save bound and surface save slots in v2 EmulatorJS#3831
Merged
Conversation
…atorJS Decouple save-file and savestate selection in the v2 player so they are no longer mutually exclusive. When a compatible savestate exists, the config screen still opens on the States tab, but the origin save now stays bound instead of being nulled. This keeps "Save & Quit" updating that save file in place (PUT) rather than spawning a new slot-less save (POST) that named-slot sync clients never see. Surface the save slot as a chip wherever a save renders (config-screen list, resume preview, and the in-game save picker), guarded so states and slot-less web saves show nothing. Adds the `play.slot` key across all locales and wires `slot` into the story fixtures. v1 (frozen) is left untouched; the change is v2-only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Greptile SummaryThis PR keeps saves bound while loading states and displays named save slots in the v2 player. The main changes are:
Confidence Score: 4/5Automatic dual selection can overwrite an unrelated named-slot save.
frontend/src/v2/views/Player/EmulatorJS.vue Important Files Changed
Reviews (1): Last reviewed commit: "fix(player): keep origin save bound and ..." | Re-trigger Greptile |
Only auto-bind a default save as the "Save & Quit" write-back target when the choice is unambiguous (a single save, or no compatible state armed). With multiple saves and a state armed, loading the state injects a different SRAM timeline, so binding an arbitrary user_saves[0] let Save & Quit PUT over a named slot the user never selected. In that case leave the save unbound and require an explicit slot pick. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Two related fixes to the v2 EmulatorJS player, both driven by the fact that the web player writes save files without a slot and could silently orphan a named-slot save.
1. Decouple save-file and savestate selection (behavior fix)
Previously, selecting (or auto-selecting) a savestate force-deselected the save file, and vice versa. When any compatible savestate existed, the config screen defaulted to the States tab and nulled the save. The consequence: "Save & Quit" then
POSTed a brand-new slot-less save file instead ofPUTting back to the named-slot save the session started from, so device-sync clients filtering by a named slot never saw that session's progress.Now save and state are independent. The visible tab still defaults to States when a compatible state exists (quick-resume preserved), but the origin save stays bound to
saveRef, so "Save & Quit" updates it in place. Both:saveand:stateare passed to the engine, which already supports loading save-then-state, so no v1 engine change was required.2. Surface the save slot (visibility)
Added a brand-toned slot chip (
SLOT · <name>) wherever a save renders:AssetList(pre-game save list + GameDetails "Save data" subtab)AssetPreview(the "resume from save" preview)AssetCard(the in-gameSelectSaveDialogpicker)Guarded with
'slot' in asset && asset.slot, so states (no slot column) and slot-less web saves render nothing. Adds theplay.slotkey across all 18 locales and wiresslotinto the story fixtures.v1 (frozen) is left untouched; the change is v2-only.
Checklist
Verification:
vue-tsctypecheck clean; i18n parity + sorted checks pass; StorybookcomposeStoriestests 363 passed;trunk fmt+trunk checkon all changed files clean. Not verified in a live emulator session (requires a real ROM + running backend).Screenshots (if applicable)
Slot chips are visible in the AssetList / AssetCard / AssetPreview Storybook stories (fixtures now include a mix of named-slot and slot-less saves).
AI assistance disclosure
This change was implemented with AI assistance (Claude Code). The AI investigated the save/state wiring, wrote the code, translations, and story fixtures, and ran the verification steps above. All changes were directed and reviewed by the author.
🤖 Generated with Claude Code