* Fix hand card rotation direction Cards now fan outward correctly instead of curling inward * Update StateRenderer to require MatchScene type for type safety - Change constructor parameter from Phaser.Scene to MatchScene - Update scene property type to MatchScene - Add import for MatchScene type - Update JSDoc example to reflect type-safe constructor * Defer Board creation to StateRenderer for correct rules config - Make board property nullable (Board | null instead of Board?) - Remove Board and createBoard imports (now handled by StateRenderer) - Update setupBoard() to skip Board creation - Add setBoard() method for StateRenderer to call - Update clearBoard() to use null instead of undefined - Add JSDoc explaining why Board creation is deferred * Create Board in StateRenderer with correct layout options - Add Board and createBoard imports - Add board property to StateRenderer - Create Board in render() on first call with correct rules_config - Add debug logging for Board creation and zone creation - Update clear() to destroy Board when clearing - Board now created after we have rules_config from first state * Add fatal error handling with toast notification and auto-redirect - Add 'fatal-error' event to GameBridgeEvents type - Import and initialize useToast in GamePage - Listen for 'fatal-error' event from Phaser - Show error toast that persists until redirect - Show full-screen fatal error overlay with countdown - Auto-redirect to /play after 3 seconds - Update StateRenderer to emit 'fatal-error' when Board creation fails * Gate debug logging with DEV flag - Add DEBUG_RENDERER constant gated by import.meta.env.DEV - Update all console.log statements in StateRenderer to only log in development - Keep console.error and console.warn as they are (always show errors) - Debug logs now only appear during development, not in production * Fix code audit issues - add missing imports and improve error UX Critical fixes: - Add missing gameBridge import to StateRenderer (fixes runtime error in fatal error handler) - Add missing Board type import to MatchScene (fixes TypeScript compilation error) UX improvements: - Replace fatal error auto-redirect with manual 'Return to Menu' button - Add toast notification when resignation fails - Give users unlimited time to read fatal errors before returning Addresses issues found in frontend code audit: - errors.missing-import (StateRenderer.ts:166) - errors.missing-type-import (MatchScene.ts:84) - errors.catch-only-console (GamePage.vue:145) - architecture.missing-fatal-error-handling (GamePage.vue:261) * Add CONTRIBUTING policy and fix pre-existing lint/test errors - Add CONTRIBUTING.md with strict policy: never use --no-verify without approval - Add comprehensive testing documentation (TESTING.md, VISUAL-TEST-GUIDE.md) - Add test-prize-fix.md quick test checklist and verify-fix.sh script Lint fixes (enables pre-commit hooks): - Remove unused imports in 9 files - Fix unused variables (underscore convention) - Replace 'as any' type assertions with proper VisibleGameState types - Add missing CARD_WIDTH_MEDIUM import in layout.spec.ts - All ESLint errors now resolved (only acceptable warnings remain) Test fixes (all 1000 tests now passing): - Fix layout.spec.ts: Add missing CARD_WIDTH_MEDIUM import - Fix PlayPage.spec.ts: Update test to use actual hardcoded UUIDs - Fix useAuth.spec.ts: Mock API profile fetch in initialization tests - Fix PhaserGame.spec.ts: Add scenes export to mock and update createGame call expectations This ensures pre-commit hooks work properly going forward and prevents bypassing TypeScript/lint checks that catch errors early. * Add comprehensive test coverage improvement plan - Create PROJECT_PLAN_TEST_COVERAGE.json with 25 structured tasks - Create TEST_COVERAGE_PLAN.md with executive summary and roadmap - Plan addresses critical gaps: game engine (0%), WebSocket (27%) - 6-week roadmap to reach 85% coverage from current 63% - Target: Phase 1 (weeks 1-3) - critical game engine and network tests - Includes quick wins, production blockers, and success metrics Based on coverage analysis showing: - Strong: Composables (84%), Components (90%), Stores (88%) - Critical gaps: Phaser game engine (~5,500 untested lines) - High priority: WebSocket/multiplayer reliability See TEST_COVERAGE_PLAN.md for overview and week-by-week breakdown. * Add coverage tooling and ignore coverage directory - Add @vitest/coverage-v8 package for coverage analysis - Add coverage/ directory to .gitignore - Used during test coverage analysis for PROJECT_PLAN_TEST_COVERAGE.json
6.8 KiB
Testing Guide: Prize Zone Fix
Branch: fix/defer-board-creation-until-state
What Was Fixed
Bug: Prize zone rectangles (2x3 grid) were appearing even when use_prize_cards: false (Mantimon TCG points mode).
Root Cause: Board was created during scene initialization before WebSocket state arrived, using default usePrizeCards: true.
Fix: Defer Board creation until StateRenderer receives first game state with correct rules_config.
Quick Start
# Terminal 1: Start backend
cd backend && uv run uvicorn app.main:app --reload
# Terminal 2: Start frontend
cd frontend && npm run dev
# Terminal 3: Ensure Docker services running
docker-compose up -d
Open: http://localhost:5173
Test 1: Visual Verification (CRITICAL)
Game: /game/f6f158c4-47b0-41b9-b3c2-8edc8275b70c (or any Mantimon mode game)
What to Look For:
BEFORE FIX (Bug):
+-----------------+
| Opp Active |
| Opp Bench |
| [P][P] <---- Prize rectangles (WRONG!)
| [P][P]
| [P][P]
+-----------------+
| My Active |
| My Bench |
| [P][P] <---- Prize rectangles (WRONG!)
| [P][P]
| [P][P]
+-----------------+
AFTER FIX (Correct):
+-----------------+
| Opp Active |
| Opp Bench |
| (no prizes) | <---- CORRECT!
+-----------------+
| My Active |
| My Bench |
| (no prizes) | <---- CORRECT!
+-----------------+
Expected Board Layout (Mantimon Mode):
Top (Opponent):
- Active Zone (1 large rectangle, center-top)
- Bench Slots (5 rectangles, horizontal row)
- Deck (small rectangle, top-right)
- Discard (small rectangle, next to deck)
- Energy Deck (small rectangle, top-left)
- Hand (row of card backs, very top)
Bottom (You):
- Active Zone (1 large rectangle, center-bottom)
- Bench Slots (5 rectangles, horizontal row)
- Deck (small rectangle, bottom-right)
- Discard (small rectangle, next to deck)
- Energy Deck (small rectangle, bottom-left)
- Hand (fanned cards, very bottom)
What should NOT be there:
- ❌ 2x3 grid of small rectangles (prize cards)
- ❌ Any 6-rectangle groups
- ❌ Empty bordered boxes on the left/right sides
Test 2: Console Verification
Open DevTools Console (F12), look for these logs:
✅ CORRECT Logs:
[StateRenderer] Creating board with layout options: {
usePrizeCards: false, ← Should be FALSE
prizeCount: 4,
benchSize: 5,
energyDeckEnabled: true
}
[StateRenderer] ✓ Board created successfully
[StateRenderer] Creating zones with rules: {
usePrizeCards: false, ← Should be FALSE
energyDeckEnabled: true,
benchSize: 5
}
❌ WRONG Logs (indicates bug):
[StateRenderer] Creating board with layout options: {
usePrizeCards: true, ← WRONG! Should be false
...
}
Test 3: Loading Overlay
- Refresh the game page
- Watch the loading sequence
Expected:
- "Connecting to game..." overlay appears instantly
- Overlay stays for 1-3 seconds
- Overlay disappears, board is fully rendered
- No visual flash or flicker of wrong state
Bug would be: Brief flash of prize rectangles before they disappear
Test 4: Fatal Error Handling
Setup (Temporary):
Edit frontend/src/game/sync/StateRenderer.ts, line 154:
// Add this line temporarily:
throw new Error('Test fatal error')
this.board = createBoard(this.scene, this.layout)
Test Steps:
- Refresh game page
- Observe error handling
Expected:
- ✅ Toast appears (bottom-right): "Failed to initialize game board: Test fatal error"
- ✅ Full-screen overlay appears:
- Red error icon
- "Failed to initialize game board"
- "The game cannot continue. Please return to the menu."
- Blue "Return to Menu" button
- ✅ NO auto-redirect (wait 10+ seconds to verify)
- ✅ Click button → redirects to
/play
Console Expected:
[StateRenderer] ✗ Failed to create board: Error: Test fatal error
[GamePage] Fatal error from Phaser: {
message: 'Failed to initialize game board',
error: 'Test fatal error',
context: 'StateRenderer.render()'
}
Cleanup:
IMPORTANT: Remove the throw new Error() line after testing!
Test 5: Resign Failure Toast
Setup:
- Start a game
- Open DevTools → Network tab → Set to "Offline"
Test Steps:
- Click exit button (X, top-right)
- Click "Resign and Leave"
Expected:
- ✅ Toast appears: "Could not confirm resignation with server. Leaving game anyway."
- ✅ Still redirects to
/play(doesn't get stuck) - ✅ Console:
[GamePage] Failed to resign: ...
Cleanup:
Turn network back to "Online"
Test 6: TypeScript Compilation
cd frontend
npm run typecheck
Expected Output:
> mantimon-tcg-frontend@0.1.0 typecheck
> vue-tsc --noEmit
✓ No errors
Bug would be:
error TS2304: Cannot find name 'gameBridge'
error TS2304: Cannot find name 'Board'
Test 7: Classic Mode (Prize Cards Enabled)
Note: This requires a game with use_prize_cards: true in backend rules.
Expected:
- ✅ 6 prize zone rectangles ARE visible (2x3 grid, left side)
- ✅ Same for opponent (top-left)
Console Should Show:
[StateRenderer] Creating board with layout options: {
usePrizeCards: true, ← Should be TRUE for classic mode
prizeCount: 6,
...
}
Test 8: Multiple Games
- Play game 1 (Mantimon mode)
- Exit
- Start game 2 (any mode)
Expected:
- ✅ Game 1: No prize rectangles
- ✅ Exit works cleanly
- ✅ Game 2: Board matches its rules
- ✅ No leftover visual artifacts
Console Should Show:
[StateRenderer] Board destroyed ← From game 1
[StateRenderer] Creating board... ← For game 2
[StateRenderer] ✓ Board created successfully
Pass/Fail Criteria
✅ ALL TESTS PASS IF:
- Visual: No prize rectangles in Mantimon mode games
- Console:
usePrizeCards: falsein logs - Loading: No visual flash of wrong state
- Fatal Error: Manual button, no auto-redirect
- Resign: Toast appears on failure
- TypeScript: No compilation errors
- Classic Mode: Prize rectangles appear when enabled
- Multiple Games: Clean transitions
❌ FIX FAILED IF:
- Prize rectangles visible when
use_prize_cards: false - Console shows
usePrizeCards: truefor Mantimon games - Fatal error auto-redirects after 3 seconds
- TypeScript compilation errors
Reporting Issues
If any test fails, report:
- Which test failed
- What you saw (screenshot preferred)
- Console logs (copy full output)
- Game ID you tested with
- Browser and version
Success Criteria Summary
The fix is working if:
✓ No prize zone rectangles appear in your test game
✓ Console shows usePrizeCards: false
✓ Board renders correctly after loading overlay
✓ Fatal error requires manual button click
✓ TypeScript compiles without errors
Ready for merge if all tests pass!