AI_Diplomacy/ai_animation/CLAUDE.md
Tyler Marques eebfba0a1b
Initial attempt at some tests that help us determine if the game has basic functionality
Signed-off-by: Tyler Marques <me@tylermarques.com>
2025-06-03 10:14:34 -07:00

10 KiB

AI Diplomacy Animation Project

Key Information

  • This is a TypeScript project using Three.js for 3D visualization of Diplomacy game states
  • The application shows animated conversations between AI players and unit movements
  • It's built with Vite for fast development

Common Commands

  • npm run dev - Start the development server
  • npm run build - Build for production
  • npm run lint - Run TypeScript linting (note: many false negatives due to JS->TS conversion)
  • npm test - Run unit tests with Vitest
  • npm run test:ui - Run tests with UI interface
  • npm run test:e2e - Run end-to-end tests with Playwright
  • npm run test:e2e:ui - Run e2e tests with visual test runner
  • npm run test:e2e:debug - Run e2e tests in debug mode

Project Structure

  • src/ - Source code
    • main.ts - Main entry point, handles game loop and UI events
    • gameState.ts - Central state management for the application
    • config.ts - Global configuration settings
    • phase.ts - Phase progression logic, game completion, and victory handling
    • domElements.ts - Core DOM element references and utilities
    • domElements/ - DOM manipulation and UI components
      • chatWindows.ts - Message display and news banner management
      • standingsBoard.ts - Leaderboard and standings display
      • relationshipPopup.ts - Power relationship visualization
    • map/ - Map rendering and manipulation
    • units/ - Unit creation and animation
    • components/ - Reusable UI components
      • rotatingDisplay.ts - Dynamic information display
      • twoPowerConversation.ts - Two-power conversation overlays
    • utils/ - Utility functions
      • powerNames.ts - Power name display resolution
    • types/ - TypeScript type definitions
    • debug/ - Debug tools and menu system
  • tests/ - Test files
    • e2e/ - End-to-end Playwright tests
    • integration/ - Integration tests (empty)
    • fixtures/ - Test fixtures (empty)
  • public/ - Static assets
    • games/ - Game data files (JSON format)
    • maps/ - Map data and SVG files
    • sounds/ - Audio files for speech
    • fonts/ - Three.js font files

Game Flow

  1. Load game data from JSON files located in public/games/{gameId}/
    • game.json - Main game data with phases, units, orders, messages
    • moments.json - High-interest moments and power model mappings
  2. Display initial phase with units and supply centers
  3. When Play is clicked:
    • Show messages sequentially, one word at a time
    • When all messages are displayed, animate unit movements
    • When animations complete, show phase summary (if available) via speech
    • Check for high-interest moments (score ≥8.0) and display two-power conversations
    • Advance to next phase and repeat
  4. Game completion:
    • When final phase is reached, displayFinalPhase() is called
    • Victory message appears in news banner with winner and supply center count
    • gameState.loadNextGame() is called to transition to next game
    • Game ID increments and new game loads automatically

Power Name Display System

The application now includes a dynamic power name display system:

  1. Model Names: If a moments.json file exists with a power_models key, the UI will display AI model names instead of generic power names (e.g., "o3" instead of "FRANCE")
  2. Fallback: If no model names are available, the system falls back to standard power names (AUSTRIA, ENGLAND, etc.)
  3. Utility Function: getPowerDisplayName(power) resolves the appropriate display name for any power
  4. Game-Aware: The system automatically adapts based on the currently loaded game's data

Agent State Display

The game now includes agent state data that can be visualized:

  1. Goals and Relationships: Each power has strategic goals and relationships with other powers
  2. Journal Entries: Internal thoughts that help explain decision making

JSON Format Expectations:

  • Agent state is stored in the game JSON with the following structure:
    {
      "powers": {
        "FRANCE": {
          "goals": ["Secure Belgium", "Form alliance with Italy"],
          "relationships": {
            "GERMANY": "Enemy",
            "ITALY": "Ally",
            "ENGLAND": "Neutral",
            "AUSTRIA": "Neutral",
            "RUSSIA": "Unfriendly",
            "TURKEY": "Neutral"
          },
          "journal": ["Suspicious of England's fleet movements"]
        }
      }
    }
    
  • Relationship status must be one of: "Enemy", "Unfriendly", "Neutral", "Friendly", "Ally"
  • The code handles case variations but the display should normalize to title case

Known Issues

  • Text-to-speech requires an ElevenLabs API key in .env file
  • Unit animations sometimes don't fire properly after messages
  • Debug mode may cause some animations to run too quickly

Data Format Notes

  • The game data's "orders" field can be either an array or an object in the JSON
  • The schema automatically converts object-format orders to array format for use in the code
  • When debugging order issues, check the format in the original JSON

Debug Tools

The application includes a debug menu system (enabled when config.isDebugMode is true):

Debug Menu Structure

  • Located in src/debug/ directory
  • DebugMenu class (debugMenu.ts) manages the collapsible menu system
  • Individual debug tools are implemented as separate modules and registered with the menu
  • Menu does not close when clicking outside (for better UX during debugging)

Available Debug Tools

Province Highlighting (provinceHighlight.ts)

  • Allows highlighting specific provinces on the map by name
  • Input validation with visual feedback for invalid province names
  • Supports Enter key and button click to trigger highlighting

Next Moment Display (nextMoment.ts)

  • Shows the next chronological moment that will occur in the game
  • Displays current phase, next phase, and next moment information
  • Uses phase name parsing to determine chronological order
  • Finds the next moment across all phases, not just the immediate next phase
  • Shows moment category, phase name, and interest score
  • Color-coded by importance (red for high scores ≥9, blue for others)

Phase Name Format

Phase names follow the format: [Season][Year][Phase]

  • Seasons: Spring (S) → Fall (F) → Winter (W)
  • Phases within each season: Move (M) → Retreat (R) → Adjustment (A)
  • Example: W1901R = Winter 1901 Retreat phase
  • Phase parsing logic is implemented in types/moments.ts with Zod schemas

Adding New Debug Tools

  1. Create a new file in src/debug/ directory
  2. Implement an init function that takes the DebugMenu instance
  3. Use debugMenu.addDebugTool(title, htmlContent, beforeSection?) to add to menu
  4. Register the tool in the DebugMenu's initTools() method
  5. Add any update functions to updateTools() method if needed

End-to-End Testing

The project includes comprehensive Playwright tests to verify game functionality:

Test Coverage

  • Complete Game Playthrough: Verifies games play through to victory and transition to next game
  • Victory Message Timing: Ensures victory popups appear and stay visible for appropriate duration
  • Manual Phase Advancement with Conversation Detection: Clicks through entire game manually while tracking two-power conversations
  • UI Element Loading: Smoke tests for essential interface components
  • Manual Navigation: Tests basic phase advancement controls

Key DOM Elements

Tests rely on these element IDs:

  • #play-btn - Play/Pause button
  • #next-btn, #prev-btn - Manual phase navigation
  • #news-banner-content - Victory messages and news updates
  • #phase-display - Current phase/era information
  • #game-id-display - Current game identifier
  • canvas - Three.js rendering surface
  • .dialogue-overlay - Two-power conversation dialog overlay

Victory Detection

Tests monitor for victory patterns in the news banner:

  • "GAME OVER.*WINS", "VICTORIOUS", "🏆.*WINS"
  • Victory messages should appear when games complete
  • Messages should remain visible until next game loads
  • Game ID should increment when transitioning to next game

Two-Power Conversation Detection

Tests can detect and track two-power conversation overlays:

  • Conversations appear when moments have interest scores ≥8.0 and involve ≥2 powers
  • Tests monitor for .dialogue-overlay elements during phase advancement
  • Conversations auto-close after timeout or can be manually closed
  • Manual advancement test tracks which phases trigger conversations

Test Helpers

Located in tests/e2e/test-helpers.ts:

  • waitForGameReady() - Ensures app loads completely and enables instant mode
  • measureVictoryTiming() - Comprehensive victory detection and timing
  • advanceGameManually() - Manual phase progression with optional two-power conversation tracking
  • isTwoPowerConversationOpen() - Detects when two-power conversation dialogs are displayed
  • waitForTwoPowerConversationToClose() - Waits for conversation dialogs to close
  • getCurrentPhaseName() - Gets current phase name for tracking purposes

Running Tests

npm run test:e2e           # Run all e2e tests
npm run test:e2e:ui        # Visual test runner
npm run test:e2e:debug     # Debug mode

Configuration Notes

  • Tests automatically enable instant mode (VITE_INSTANT_MODE=true) for faster execution
  • Tests automatically enable debug mode (VITE_DEBUG_MODE=true) for auto-loading games
  • Dev server starts automatically on http://localhost:5173
  • Timeouts set appropriately (1-2 minutes for full playthroughs with instant mode)
  • Cross-browser testing on Chromium, Firefox, and WebKit

Game State Management

Central state is managed in gameState.ts with key properties:

  • gameData - Current game's JSON data
  • momentsData - High-interest moments and metadata
  • phaseIndex - Current phase being displayed
  • currentPower - Player's assigned power
  • isPlaying - Automatic playback state
  • messagesPlaying - Message animation state
  • unitAnimations - Active unit movement animations

Game Completion Flow

  1. Final phase detection in phase.ts:_setPhase()
  2. displayFinalPhase() calculates winner by supply center count
  3. Victory message added to news banner via addToNewsBanner()
  4. gameState.loadNextGame() increments game ID
  5. New game file loaded from public/games/{newGameId}/game.json
  6. Application resets to initial state with new game

Code Style Preferences

  • Use descriptive function and variable names
  • Add JSDoc comments for all exported functions
  • Log important state transitions to console
  • Use TypeScript types for all parameters and return values