fix(ui): advance turn glow/interactivity to the player to move
`active` was `$derived(gameStore.activeBoards)`, and that getter read the non-`$state` `#game`. The $derived captured no reactive dependency, so the glowing/interactive boards froze on North's NW+NE after move 1: the next player couldn't act, clicks on their boards did nothing, and selections fired on unexpected boards — the reported "turns", "what piece is selected", and "mirrored movements" symptoms were all this one stale-derived bug. Fix: derive `active` from the reactive `view.currentPlayer`; remove the footgun `activeBoards` getter so nothing re-reads `#game` reactively. Add scripts/smoke.py: Playwright end-to-end test driving the real app through a full N->S->E->W round (engine vitest can't see Svelte reactivity wiring). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,10 @@
|
||||
const BOARD_IDS: BoardId[] = ['NW', 'NE', 'SW', 'SE'];
|
||||
|
||||
let view = $derived(gameStore.view);
|
||||
let active = $derived(gameStore.activeBoards);
|
||||
// Derive from the reactive `view`, NOT the store's #game getter: #game is
|
||||
// deliberately not a $state proxy, so a $derived reading it never recomputes
|
||||
// and the turn glow/interactivity froze on North after move 1.
|
||||
let active = $derived(PLAYER_BOARDS[view.currentPlayer]);
|
||||
|
||||
/** Ghost squares for a given board. */
|
||||
function ghostsFor(id: BoardId): Square[] {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { legalSyncedMoves, selectionHighlight, type SelectionHighlight } from '.
|
||||
import { ghosts } from '../../engine/ghosts';
|
||||
import { evaluateStatus } from '../../engine/endgame';
|
||||
import { serialize, deserialize } from '../../engine/notation';
|
||||
import { PLAYER_BOARDS } from '../../engine/boards';
|
||||
import type {
|
||||
BoardId, Player, Square, SyncMove, HistoryEntry, GhostMarker, GameStatus,
|
||||
} from '../../engine/types';
|
||||
@@ -54,11 +53,6 @@ class GameStore {
|
||||
return this.scrubPly !== null;
|
||||
}
|
||||
|
||||
/** Which boards belong to the player to move (for the turn glow). */
|
||||
get activeBoards(): [BoardId, BoardId] {
|
||||
return PLAYER_BOARDS[this.#game.currentPlayer];
|
||||
}
|
||||
|
||||
/** Grab a piece: must be the current player's turn and a live (non-scrub) view. */
|
||||
select(square: Square): void {
|
||||
if (this.isScrubbing) return;
|
||||
|
||||
Reference in New Issue
Block a user