architecture-refactor
Two Numbers, No Explanation
Retiring the claim-or-discard sign-in dialog for an always-silent account sync, moving the destructive "start fresh" action into Settings on its own, and reusing the same-device recap verbatim on a second device.
Five fixes, one revert
An architecture review turns an hour of live firefighting on the PvP presence module into an explicit state machine, then finds the same missing structure on the client side.
Persisted, but never shown
Daily Challenge players can now replay for a better score, deduped by a token that never leaves the browser. A design review caught the feature quietly failing one of its own stated goals.
Interrupted, not gone
PvP duel players get an advisory signal for a stalled opponent, built on an authentication boundary the old unauthenticated stream design never needed, and a hard line against ever letting that signal decide the game.
Rematching with the same opponent in real-time PvP
Starting another match against the same opponent previously required sharing a new room link. Token-chained authorization and a six-state UI matrix bring instant same-opponent rematches.
Deriving help text point values from the game engine
Hardcoded point strings in UI translation dictionaries drifted when fruit values changed. Deriving help copy directly from EDIBLE_POINTS enforced a single source of truth.
Collapsing the three-file translation triplet into one module
Maintaining UI translations across three separate files created silent sync friction. Moving to a single per-key module enforced compile-time translation parity.
The second time needed no spike
AI duel gets the same injectable-factory treatment the PvP store just proved out. With the pattern and the risk already settled, the ticket for this one only had to say what was smaller.
The store that had never been tested
pvpGameState.svelte.ts had never had a single unit test of its own. Turning it into an injectable factory meant answering, before touching it, whether Svelte 5 runes would even tolerate the shape.
Eight strings, one function
A five-level nested ternary picked the caption for how a PvP game ended. The only way to exercise all eight of its outcomes was rendering the whole page.