mirror of
https://github.com/GoodStartLabs/AI_Diplomacy.git
synced 2026-04-19 12:58:09 +00:00
229 lines
No EOL
10 KiB
Markdown
229 lines
No EOL
10 KiB
Markdown
# 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:
|
|
```json
|
|
{
|
|
"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
|
|
```bash
|
|
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 |