Nano Banana Pro
Agent skill for nano-banana-pro
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Sign in to like and favorite skills
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Always read the CHANGELOG.md for context Always look at tasks/todo.md for next steps
##Rules
docker compose not docker-compose (modern Docker command)Use the tasks/todo.md file as the source of truth. Work on it in order, asking if we are ready to move on.
Commit after finishing task sections
Once we build is succesful
git add . and git commit and pushnpm run dev:full - Start both WebSocket server and Next.js dev server (recommended for full development)npm run dev - Next.js development server only (Turbopack enabled)npm run server - Y.js WebSocket server onlynpm run build - Build Next.js applicationnpm run lint - Run ESLintnpm run lint - ESLint for code qualityThis is a multiplayer board game application ("Seasonal Board Game") built with Next.js 15 and real-time collaboration using Y.js WebSockets.
Frontend (Next.js App)
Backend (Separate Server)
/server/ directoryserver/y-websocket-server.js needs implementation)Board Structure
State Management (
/src/store/gameStore.ts)
Game Components (
/src/components/game/)
GameBoard.tsx - Main SVG board renderingGameControls.tsx, PlayerInfo.tsx, ResourcePanel.tsx - UI controlsMultiplayerControls.tsx - Real-time collaboration featuresCompleted:
Needs Implementation:
/src/app/page.tsx) still shows default Next.js starter/server/y-websocket-server.js) is empty/src/components/ui/Tailwind CSS: Custom game-themed colors (Mountain #8B7355, Pasture #90EE90, Forest #228B22, Riverland #4682B4) with seasonal animations
Shadcn/ui: Configured with "new-york" style, TypeScript enabled, path aliases set up
Y.js Integration: WebSocket provider configured for real-time multiplayer at
ws://localhost:1234
npm run dev:full for full development experience with both serversProblem: When Client A updates Yjs, Client B receives the update and triggers Zustand set(), which fires store subscription and calls syncToYjs(), potentially overwriting A's fresh data with B's stale copy.
Solution Pattern (implemented in
gameStore.ts:552-578):
isUpdatingFromYjs flag to prevent recursive updates
isUpdatingFromYjs = true BEFORE calling set() in observersyncToYjs to avoid sending updates while receiving themFiles Modified:
apps/frontend/src/store/gameStore.ts (lines 145-166, 241-284, 552-578, 1039-1044)Prevention: Always implement this pattern when adding new Yjs synchronization to prevent data corruption in multiplayer scenarios.
Problem: Player 2 was not being asked for energy tax on their first turn because boolean
false values were being incorrectly overridden by local fallback values in multiplayer synchronization.
Root Cause: Using logical OR (
||) instead of nullish coalescing (??) for boolean state fields:
// WRONG - false values fallback to local state energyTaxPaid: yjsState.energyTaxPaid || get().energyTaxPaid // CORRECT - only null/undefined values fallback energyTaxPaid: yjsState.energyTaxPaid ?? get().energyTaxPaid
Solution: Use nullish coalescing (
??) for boolean and numeric fields in Yjs observer (line 594).
Files Modified:
apps/frontend/src/store/gameStore.ts (line 594)Prevention: Always use
?? instead of || for boolean and numeric state synchronization in multiplayer games.
Problem: Local UI changes (like energy tax payment) were not immediately reflecting on the current player's screen but were visible on other players' screens. UI updates would only appear after a phase change or other state update.
Root Cause: Double synchronization to Yjs was creating race conditions:
Solution: Remove all manual
gameStateMap.set() calls from action methods and rely solely on the store subscription for Yjs synchronization.
Files Modified:
apps/frontend/src/store/gameStore.ts (lines 786-800, 816-825, 835-842)Methods Fixed:
updateFromEngineState - removed manual energy tax syncupdateBoardRotations - removed manual board/player syncupdateDiceState - removed manual dice state syncPrevention: Never manually sync to Yjs in action methods - let the store subscription handle all Yjs synchronization to avoid race conditions.