Animation fixes:
- Fix held card positioning bug (was appearing at bottom of page)
- Fix discard pile blank/white flash on turn transitions
- Fix blank card at round end by skipping animations during round_over/game_over
- Set card content before triggering flip animation to prevent flash
- Center suit symbol on 10 cards
Timing improvements:
- Reduce post-discard delay from 700ms to 500ms
- Reduce post-swap delay from 1800ms to 1000ms
- Speed up swap flip animation from 1150ms to 550ms
- Reduce CPU initial thinking delay from 150-250ms to 80-150ms
- Pause now happens after swap completes (showing result) instead of before
E2E test suite:
- Add Playwright-based test bot that plays full games
- State parser extracts game state from DOM for validation
- AI brain ports decision logic for automated play
- Freeze detector monitors for UI hangs
- Visual validator checks CSS states
- Full game, stress, and visual test specs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reset all CPU profiles on server shutdown to prevent stuck profiles
- Clean up all rooms during shutdown
- Add GET /api/debug/cpu-profiles to check allocation status
- Add POST /api/debug/reset-cpu-profiles for emergency cleanup
This fixes the issue where CPU profiles get "stuck" when connections
drop without clean teardown, preventing new games from adding CPUs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When you accidentally click the discard pile, you can now put the card
back instead of being forced to swap. The "Put Back" button appears
only when you've drawn from the discard pile.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 - Critical Fixes:
- Add game_lock (asyncio.Lock) to Room class for serializing mutations
- Wrap all game action handlers in lock to prevent race conditions
- Split Card.to_dict into to_dict (full data) and to_client_dict (hidden)
- Fix CardState.from_dict to handle missing rank/suit gracefully
- Fix GameOptions reconstruction in recovery_service (dict -> object)
- Extend state cache TTL from 4h to 24h, add touch_game method
Phase 2 - Security:
- Add optional WebSocket authentication via token query param
- Use authenticated user ID/name when available
- Add auth support to spectator WebSocket endpoint
Phase 3 - Performance:
- Make stats processing async (fire-and-forget) to avoid blocking
game completion notifications
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adjust dimple size and spacing for balanced appearance
- Enlarge card suit symbols (font-size 32) in single row
- Fine-tune symbol positioning and spacing
- Increase margin between logo and golfer emoji
- Add /golfball-logo.svg static file route
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add SVG golf ball logo with dimples and card suit symbols (♣♦♠♥)
- Place logo to the left of the golfer emoji in header
- Fix server shutdown hanging by removing custom signal handlers
that intercepted SIGINT/SIGTERM without triggering uvicorn shutdown
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Early Knock variant: flip all remaining cards (≤2) to go out early
- Update RULES.md with comprehensive documentation for all new variants
- Shorten flip mode dropdown descriptions for cleaner UI
- Add try-catch and optional chaining in startGame() for robustness
- Add WebSocket connection error feedback with reject sound
- AI awareness for Early Knock decisions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Opponent draw highlight: scale + outline flash animation
- House rules reorganized: Gameplay, Jokers, Card Values, Bonuses & Penalties
- Compact inline rule descriptions with alternating suit separators (♣♦♠♥)
- Wolfpack + Four of a Kind combo note when both selected
- Toast notifications now yellow/green with charcoal text
- Brief pause after AI draw for visual feedback
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add comprehensive docstrings to game.py, room.py, constants.py
- Document all classes, methods, and module-level items
- Move active rules display into game header as inline column
- Update header to 5-column grid layout
- Update joker mode descriptions (Lucky Swing, Eagle-Eye)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add big final results modal at game end with rankings and share button
- Add active rules bar showing enabled variants during gameplay
- Increase spacing between player cards and opponents row
- Add Wolfpack bonus rule (2 pairs of Jacks = -5 pts)
- Change joker options to radio buttons (None/Standard/Lucky Swing/Eagle-Eye)
- Update Eagle-Eye jokers: +2 pts unpaired, -4 pts paired
- Add card flip animation on discard pile
- Redesign waiting room layout with side-by-side columns
- Style card backs with red Bee-style diamond crosshatch pattern
- Compact standings panel to show top 4 per category
- Various CSS polish and responsive improvements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add constants.py as the single source of truth for card values
- Derive RANK_VALUES from DEFAULT_CARD_VALUES instead of duplicating
- Add centralized get_card_value() function in game.py for Card objects
- Add get_card_value_for_rank() in constants.py for string-based lookups
- Fix bug: AI ten_penny returned 0 instead of 1 per RULES.md
- Update ai.py and game_analyzer.py to use centralized functions
- UI improvements for client
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Features:
- Multiplayer WebSocket game server (FastAPI)
- 8 AI personalities with distinct play styles
- 15+ house rule variants
- SQLite game logging for AI analysis
- Comprehensive test suite (80+ tests)
AI improvements:
- Fixed Maya bug (taking bad cards, discarding good ones)
- Personality traits influence style without overriding competence
- Zero blunders detected in 1000+ game simulations
Testing infrastructure:
- Game rules verification (test_game.py)
- AI decision analysis (game_analyzer.py)
- Score distribution analysis (score_analysis.py)
- House rules testing (test_house_rules.py)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>