mirror of
https://github.com/GoodStartLabs/AI_Diplomacy.git
synced 2026-04-19 12:58:09 +00:00
10 KiB
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 servernpm run build- Build for productionnpm run lint- Run TypeScript linting (note: many false negatives due to JS->TS conversion)npm test- Run unit tests with Vitestnpm run test:ui- Run tests with UI interfacenpm run test:e2e- Run end-to-end tests with Playwrightnpm run test:e2e:ui- Run e2e tests with visual test runnernpm run test:e2e:debug- Run e2e tests in debug mode
Project Structure
src/- Source codemain.ts- Main entry point, handles game loop and UI eventsgameState.ts- Central state management for the applicationconfig.ts- Global configuration settingsphase.ts- Phase progression logic, game completion, and victory handlingdomElements.ts- Core DOM element references and utilitiesdomElements/- DOM manipulation and UI componentschatWindows.ts- Message display and news banner managementstandingsBoard.ts- Leaderboard and standings displayrelationshipPopup.ts- Power relationship visualization
map/- Map rendering and manipulationunits/- Unit creation and animationcomponents/- Reusable UI componentsrotatingDisplay.ts- Dynamic information displaytwoPowerConversation.ts- Two-power conversation overlays
utils/- Utility functionspowerNames.ts- Power name display resolution
types/- TypeScript type definitionsdebug/- Debug tools and menu system
tests/- Test filese2e/- End-to-end Playwright testsintegration/- Integration tests (empty)fixtures/- Test fixtures (empty)
public/- Static assetsgames/- Game data files (JSON format)maps/- Map data and SVG filessounds/- Audio files for speechfonts/- Three.js font files
Game Flow
- Load game data from JSON files located in
public/games/{gameId}/game.json- Main game data with phases, units, orders, messagesmoments.json- High-interest moments and power model mappings
- Display initial phase with units and supply centers
- 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
- 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
- When final phase is reached,
Power Name Display System
The application now includes a dynamic power name display system:
- Model Names: If a
moments.jsonfile exists with apower_modelskey, the UI will display AI model names instead of generic power names (e.g., "o3" instead of "FRANCE") - Fallback: If no model names are available, the system falls back to standard power names (AUSTRIA, ENGLAND, etc.)
- Utility Function:
getPowerDisplayName(power)resolves the appropriate display name for any power - 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:
- Goals and Relationships: Each power has strategic goals and relationships with other powers
- 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
.envfile - 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 DebugMenuclass (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.tswith Zod schemas
Adding New Debug Tools
- Create a new file in
src/debug/directory - Implement an init function that takes the DebugMenu instance
- Use
debugMenu.addDebugTool(title, htmlContent, beforeSection?)to add to menu - Register the tool in the DebugMenu's
initTools()method - 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 identifiercanvas- 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-overlayelements 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 modemeasureVictoryTiming()- Comprehensive victory detection and timingadvanceGameManually()- Manual phase progression with optional two-power conversation trackingisTwoPowerConversationOpen()- Detects when two-power conversation dialogs are displayedwaitForTwoPowerConversationToClose()- Waits for conversation dialogs to closegetCurrentPhaseName()- 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 datamomentsData- High-interest moments and metadataphaseIndex- Current phase being displayedcurrentPower- Player's assigned powerisPlaying- Automatic playback statemessagesPlaying- Message animation stateunitAnimations- Active unit movement animations
Game Completion Flow
- Final phase detection in
phase.ts:_setPhase() displayFinalPhase()calculates winner by supply center count- Victory message added to news banner via
addToNewsBanner() gameState.loadNextGame()increments game ID- New game file loaded from
public/games/{newGameId}/game.json - 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