mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 21:35:42 +00:00
Create docs/ folder at repo root and move documentation files: - CONNECTION_ARCHITECTURE.md (new comprehensive connection docs) - COMMAND_PROTO_USAGE_ANALYSIS.md - DEPROTO_PLAN.md - SCALA3_MODERNIZATION.md - actions-model-usage-analysis.md - occupants-optimization-report.md - scala3-reflection-issues.md CLAUDE.md remains at root (project instructions for Claude Code). Connection architecture documentation includes: - gRPC bidirectional streaming protocol details - Client-side connection management (PersistentClientConnection) - Server-side implementation (EagleServiceImpl) - nginx proxy configuration and timeouts - Timeout settings across all layers (client, nginx, server) - Eagle ↔ Shardok communication flow Critical findings: - 🔴 SECURITY: Shardok internal interface exposed without auth in nginx config - Mystery "2-minute timeout" doesn't exist in code (all timeouts are 5-20 minutes) - No state resync mechanism after connection drops during Shardok - Inefficient dual-layer heartbeat (HTTP/2 + application level) Hypotheses for remote player connection issues: - Most likely: NAT/firewall timeout at player's router/ISP (60-120s) - HTTP/2 keepalive (45s) may not be frequent enough to keep NAT alive - Shardok's bursty traffic pattern may appear "idle" at transport layer Recommendations: 1. Fix Shardok internal interface security vulnerability 2. Add precise connection drop logging with timestamps 3. Reduce HTTP/2 keepalive from 45s to 15s 4. Get network diagnostics from affected remote player 5. Implement state resync mechanism for Shardok 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
305 lines
17 KiB
Markdown
305 lines
17 KiB
Markdown
# Actions and Commands Model Usage Analysis
|
|
|
|
This document analyzes all actions and commands in `src/main/scala/net/eagle0/eagle/library/actions/impl` to determine which use Scala models vs protobuf models, based on BUILD.bazel dependencies.
|
|
|
|
**Legend:**
|
|
- ✅ **Scala Models Only** - Uses only `//src/main/scala/net/eagle0/eagle/model` dependencies
|
|
- ❌ **Uses Protobuf** - Has dependencies on `//src/main/protobuf` targets
|
|
- 🔄 **Partial Conversion** - Conversion attempted but blocked by dependencies
|
|
|
|
## Summary
|
|
|
|
Based on BUILD.bazel dependency analysis (2025-09-16, updated 2025-09-17):
|
|
- **Total Commands Analyzed:** 41
|
|
- **Commands Fully Migrated (No Protobuf):** 41 (100%) ✅
|
|
- **Commands Still Using Protobuf:** 0 (0%) ✅
|
|
- **Total Actions Analyzed:** 48
|
|
- **Actions Fully Migrated (No Protobuf):** 5 (10.4%)
|
|
- **Actions Partially Migrated:** 19 (39.6%)
|
|
- **Actions Still Using Protobuf:** 24 (50%)
|
|
- **Base Classes:** 8 protoless variants available, 6 still use protobuf
|
|
- **Shared Components:** `ResolvedEagleUnit` migrated to use `Option[BattalionT]` for proper null handling
|
|
|
|
## Conversion Insights
|
|
|
|
Based on conversion attempt of `ResolveTruceOfferCommand` (see [PR #4379](https://github.com/nolen777/eagle0/pull/4379)):
|
|
|
|
### Key Challenges Discovered
|
|
|
|
1. **LLM Integration Dependencies**: Commands that use `DiplomacyResolutionLlmRequestGenerator` face challenges because the LLM system still expects protobuf enum types, not Scala model enums.
|
|
|
|
2. **Inconsistent Package Naming**: Some files have inconsistent package declarations vs BUILD file locations (e.g., `generated_text_request_generators` in package vs `llm_request_generators` in BUILD).
|
|
|
|
3. **Model Constructor Differences**: Scala model constructors (e.g., `TruceOffer`) have different required parameters than their protobuf counterparts, requiring more complex data mapping.
|
|
|
|
4. **Type System Complexity**: Union types and type constraints become more complex when mixing protobuf and Scala model types during transition.
|
|
|
|
5. **Cascading Dependency Issues**: Converting to `ActionResultC` requires extensive trait dependencies (`ChangedBattalionT`, `ChangedHeroT`, `GeneratedTextRequestT`, etc.) that create complex BUILD dependency graphs, unlike simple protobuf `ActionResult`.
|
|
|
|
6. **BUILD Complexity**: Each Scala model conversion requires significantly more BUILD dependencies than protobuf equivalents, making incremental conversion difficult.
|
|
|
|
7. **Build Verification Critical**: Any conversion must maintain working build state - even simple commands like `DefendCommand` can break main server build due to dependency cascades.
|
|
### Successful Conversion Elements
|
|
|
|
- ✅ Base class conversion (`SimpleAction` → `ProtolessSimpleAction`)
|
|
- ✅ Import updates for most Scala model types
|
|
- ✅ BUILD.bazel dependency updates for core action result types
|
|
- ✅ Basic type conversions for simple cases
|
|
|
|
### Recommended Conversion Strategy
|
|
|
|
1. **Architecture-First Approach**: Convert base infrastructure (LLM generators, action result builders) before individual commands
|
|
2. **Wrapper Pattern**: Use existing `Protoless*ActionWrapper` classes as templates for gradual transition
|
|
3. **Dependency Analysis**: Map full dependency trees before attempting conversions to avoid cascading build failures
|
|
4. **Batch Conversions**: Convert related commands together to minimize dependency conflicts
|
|
5. **Build Verification**: **ALWAYS** verify `//src/main/scala/net/eagle0/eagle:eagle_server` and test suite build before creating PRs
|
|
|
|
### Conversion Requirements
|
|
|
|
**Before creating any PR:**
|
|
- ✅ `bazel build //src/main/scala/net/eagle0/eagle:eagle_server` succeeds
|
|
- ✅ `bazel test //src/test/scala/... --keep_going` passes (or doesn't introduce new failures)
|
|
- ✅ All BUILD dependencies are correctly specified
|
|
- ✅ Scalafmt and other linters pass
|
|
|
|
---
|
|
|
|
## Common Base Classes
|
|
|
|
| File | Type | Model Usage | Notes |
|
|
|------|------|-------------|-------|
|
|
| Action.scala | Base Class | ❌ Uses Protobuf | Depends on `action_result_scala_proto`, `game_state_scala_proto` |
|
|
| ActionWithResultingState.scala | Base Class | ❌ Uses Protobuf | Depends on `action_result_scala_proto`, `game_state_scala_proto` |
|
|
| DeterministicSingleResultAction.scala | Base Class | ❌ Uses Protobuf | Depends on `action_result_scala_proto`, `game_state_scala_proto` |
|
|
| DeterministicSequentialResultsAction.scala | Base Class | ❌ Uses Protobuf | Depends on `action_result_scala_proto`, `game_state_scala_proto` |
|
|
| ProtolessRandomSequentialResultsAction.scala | Base Class | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model/action_result` |
|
|
| ProtolessRandomSimpleAction.scala | Base Class | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model/action_result` |
|
|
| ProtolessSequentialResultsAction.scala | Base Class | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model/action_result` |
|
|
| ProtolessSimpleAction.scala | Base Class | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model/action_result` |
|
|
| RandomSequentialResultsAction.scala | Base Class | ❌ Uses Protobuf | Depends on `action_result_scala_proto`, `game_state_scala_proto` |
|
|
| RandomSimpleAction.scala | Base Class | ❌ Uses Protobuf | Depends on `action_result_scala_proto` |
|
|
| RandomStateProtoSequencer.scala | Sequencer | ❌ Uses Protobuf | Bridge class, depends on both protobuf and Scala models |
|
|
| RandomStateTSequencer.scala | Sequencer | ❌ Uses Protobuf | Bridge class, depends on both protobuf and Scala models |
|
|
| SimpleAction.scala | Base Class | ❌ Uses Protobuf | Depends on `action_result_scala_proto` |
|
|
| VigorXPApplier.scala | Utility | ❌ Uses Protobuf | Depends on `action_result_scala_proto` |
|
|
|
|
---
|
|
|
|
## Actions
|
|
|
|
### ✅ Fully Migrated Actions (No Protobuf Dependencies)
|
|
|
|
These actions have been successfully migrated to use Scala models only:
|
|
|
|
| File | Base Class | Notes |
|
|
|------|------------|-------|
|
|
| HeroBackstoryUpdateAction.scala | ProtolessSequentialResultsAction | Processes hero backstory updates with LLM integration |
|
|
| ProvinceConqueredAction.scala | ProtolessSimpleAction | Uses component-based design (gameId, currentRoundId, currentDate, Scala models) |
|
|
| ProvinceHeldAction.scala | ProtolessSimpleAction | Uses specific components (gameId, currentRoundId, defendingProvince, etc.) instead of full GameState |
|
|
| UnaffiliatedHeroAppearedAction.scala | ProtolessSimpleAction | Handles unaffiliated hero appearance with name generation |
|
|
| WithdrawnArmiesReturnHomeAction.scala | ProtolessSequentialResultsAction | Manages army withdrawal and return mechanics |
|
|
|
|
### 🔄 Actions Partially Migrated (Using Protoless Base Classes)
|
|
|
|
These actions use protoless base classes but still have some protobuf dependencies:
|
|
|
|
| File | Model Usage | Notes |
|
|
|------|-------------|-------|
|
|
| CheckForFactionChangesAction.scala | ProtolessSequentialResultsAction | Still has some protobuf dependencies |
|
|
| CheckForFailedQuestsAction.scala | ProtolessSequentialResultsAction | Depends on `unaffiliated_hero_quest_scala_proto` |
|
|
| CheckForFulfilledQuestsAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| EndAttackDecisionPhaseAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| EndBattleAftermathPhaseAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| EndFreeForAllDecisionPhaseAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| EndPlayerCommandsPhaseAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| EndUnaffiliatedHeroActionsPhaseAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| EndVassalCommandsPhaseAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| FreeForAllDrawAction.scala | ProtolessSimpleAction | Depends on multiple protobuf targets |
|
|
| FriendlyMoveAction.scala | ProtolessSimpleAction | Depends on multiple protobuf targets |
|
|
| PerformUncontestedConquestAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| ProvinceConqueredAction.scala | ProtolessSimpleAction | **CONVERTED** - Uses specific components (gameId, currentRoundId, currentDate, Scala models) |
|
|
| SafePassageArmiesProceedAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| ShipmentArrivedAction.scala | ProtolessSimpleAction | Depends on multiple protobuf targets |
|
|
| TruceTurnBackPhaseAction.scala | ProtolessSequentialResultsAction | Depends on multiple protobuf targets |
|
|
| UnaffiliatedHeroRejoinedAction.scala | ProtolessSimpleAction | Depends on multiple protobuf targets |
|
|
| WonFreeForAllAction.scala | ProtolessSimpleAction | Depends on multiple protobuf targets |
|
|
|
|
### ❌ Actions Still Using Protobuf (Not Yet Using Protoless Base Classes)
|
|
|
|
| File | Notes |
|
|
|------|-------|
|
|
| ChronicleEventGenerator.scala | Depends on multiple protobuf targets |
|
|
| EndBattleRequestPhaseAction.scala | Depends on `diplomacy_offer_status_scala_proto` |
|
|
| EndBattleResolutionPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| EndDefenseDecisionPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| EndDiplomacyResolutionPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| EndFreeForAllBattleRequestPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| EndFreeForAllBattleResolutionPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| EndHandleRiotsPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| EndPleaseRecruitMePhaseAction.scala | Depends on multiple protobuf targets |
|
|
| EndProvinceMoveResolutionPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| NewRoundAction.scala | Depends on multiple protobuf targets |
|
|
| NewYearAction.scala | Depends on multiple protobuf targets |
|
|
| PerformFoodConsumptionPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| PerformForcedTurnBackAction.scala | Depends on multiple protobuf targets |
|
|
| PerformHeroDeparturesAction.scala | Depends on multiple protobuf targets |
|
|
| PerformHostileArmySetupAction.scala | Depends on multiple protobuf targets |
|
|
| PerformProvinceEventsAction.scala | Depends on `province_event_scala_proto` |
|
|
| PerformProvinceMoveResolutionAction.scala | Depends on multiple protobuf targets |
|
|
| PerformReconResolutionAction.scala | Depends on multiple protobuf targets |
|
|
| PerformUnaffiliatedHeroesAction.scala | Depends on `unaffiliated_hero_quest_scala_proto` |
|
|
| PerformVassalCommandsPhaseAction.scala | Depends on multiple protobuf targets |
|
|
| PerformVassalDefenseDecisionsAction.scala | Depends on multiple protobuf targets |
|
|
| PrisonerEscapeAction.scala | Depends on `game_state_scala_proto` |
|
|
| PrisonerExchangeAction.scala | Depends on multiple protobuf targets |
|
|
| RequestBattlesAction.scala | Depends on multiple protobuf targets |
|
|
| RequestFreeForAllBattlesAction.scala | Depends on multiple protobuf targets |
|
|
| ResolveBattleAction.scala | Depends on `shardok_internal_interface_scala_grpc` |
|
|
| UnaffiliatedHeroMovedAction.scala | Depends on multiple protobuf targets |
|
|
| UnaffiliatedHeroesChangedAction.scala | Depends on multiple protobuf targets |
|
|
|
|
---
|
|
|
|
## Commands
|
|
|
|
✅ **ALL COMMANDS FULLY MIGRATED** (100% - 41/41 commands)
|
|
|
|
All 41 commands in the codebase have been successfully migrated to use Scala models only, with no protobuf dependencies. This includes:
|
|
|
|
- **Simple Actions**: Use `ProtolessSimpleAction` base class
|
|
- **Random Actions**: Use `ProtolessRandomSimpleAction` base class
|
|
- **Complex Domain Models**: Successfully integrated with LLM systems, diplomacy, quest fulfillment, and state management
|
|
- **Complete Type Safety**: All commands now use type-safe Scala domain models
|
|
|
|
**Key Migration Achievements:**
|
|
- ✅ All military commands (ArmTroops, Train, Organize, etc.)
|
|
- ✅ All diplomacy commands (Resolve Alliance/Truce/Ransom offers, etc.)
|
|
- ✅ All LLM-integrated commands (backstory generation, diplomacy resolution)
|
|
- ✅ All quest and event commands
|
|
- ✅ Final remaining command (FreeForAllDecisionCommand) migrated
|
|
|
|
---
|
|
|
|
## Diplomacy Helpers
|
|
|
|
All diplomacy helpers use **Scala models only**:
|
|
|
|
| File | Model Usage | Notes |
|
|
|------|-------------|-------|
|
|
| AllianceResolutionHelpers.scala | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model` only |
|
|
| BreakAllianceResolutionHelpers.scala | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model` only |
|
|
| InvitationResolutionHelpers.scala | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model` only |
|
|
| RansomResolutionHelpers.scala | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model` only |
|
|
| TruceResolutionHelpers.scala | ✅ Scala Models Only | Uses `//src/main/scala/net/eagle0/eagle/model` only |
|
|
|
|
---
|
|
|
|
## Migration Priority Analysis
|
|
|
|
Based on the BUILD.bazel dependency analysis, here are the key findings and recommendations:
|
|
|
|
### 🎯 High Impact Migration Targets
|
|
|
|
**Core Dependencies Blocking Multiple Commands:**
|
|
|
|
1. **`action_result_scala_proto`** - Used by 12+ commands
|
|
- Blocks: `DefendCommand`, `FreeForAllDecisionCommand`, diplomacy resolvers
|
|
- Impact: Would unlock many command migrations
|
|
|
|
2. **`available_command_scala_proto` / `selected_command_scala_proto`** - Used by 10+ commands
|
|
- Blocks: All UI-interactive commands
|
|
- Impact: Would enable client-server interaction model migration
|
|
|
|
3. **`game_state_scala_proto`** - Used by 8+ commands
|
|
- Blocks: Complex state-dependent commands
|
|
- Impact: Core state representation migration
|
|
|
|
### 📊 Migration Tiers by Complexity
|
|
|
|
**Tier 1 - Quick Wins (2 commands):**
|
|
- `ArmTroopsCommand` - Only `battalion_type` dependency
|
|
- `TrainCommand` - Only `battalion_type` dependency
|
|
- **Effort:** Low, **Impact:** Demonstrates battalion model usage
|
|
|
|
**Tier 2 - API Layer (5 commands):**
|
|
- Commands blocked by `available_command`/`selected_command`
|
|
- **Effort:** Medium, **Impact:** High (enables UI interaction models)
|
|
|
|
**Tier 3 - Diplomacy Suite (6 commands):**
|
|
- All `Resolve*Command` diplomacy commands
|
|
- **Effort:** High, **Impact:** High (complete diplomacy model migration)
|
|
- **Strategy:** Migrate as a group after diplomacy models are ready
|
|
|
|
### 🏆 Success Metrics
|
|
|
|
**Current Status:**
|
|
- ✅ **100% of commands fully migrated** (41/41) 🎉
|
|
- ✅ **All diplomacy helpers use Scala models**
|
|
- ✅ **All protoless base classes available**
|
|
- ✅ **ALL command migration completed**
|
|
|
|
**Completed Milestones:**
|
|
- ✅ **70% target:** Migrate Tier 1 + some Tier 2 commands **COMPLETED**
|
|
- ✅ **80% target:** Continue with remaining non-diplomacy commands **COMPLETED**
|
|
- ✅ **85% target:** Complete API layer migration **COMPLETED**
|
|
- ✅ **95% target:** Complete diplomacy migration **COMPLETED**
|
|
- ✅ **100% target:** Migrate final remaining command (FreeForAllDecisionCommand) **COMPLETED**
|
|
|
|
### 🎯 Action Migration Progress
|
|
|
|
**Migration Statistics:**
|
|
- 5/48 Actions fully migrated (10.4%)
|
|
- 20/48 Actions using protoless base classes but with protobuf dependencies (41.7%)
|
|
- 24/48 Actions still fully on protobuf (50%)
|
|
|
|
**Successfully Migrated Actions:**
|
|
1. **HeroBackstoryUpdateAction** - LLM integration for hero backstories
|
|
2. **ProvinceConqueredAction** - Component-based design with prisoner handling and province conquest
|
|
3. **ProvinceHeldAction** - Component-based design pattern (gameId, currentRoundId, specific models)
|
|
4. **UnaffiliatedHeroAppearedAction** - Hero appearance with name generation
|
|
5. **WithdrawnArmiesReturnHomeAction** - Army withdrawal mechanics
|
|
|
|
**Recent Migration Updates (2025-09-17):**
|
|
- **ResolvedEagleUnit** - Changed `battalion: BattalionT` to `battalion: Option[BattalionT]`
|
|
- Properly handles units without battalions (battalion ID -1)
|
|
- Updated `ShardokInterfaceGrpcClient` to check for `defaultBattalionId` and use `None`
|
|
- Updated `ResolveBattleAction`, `ProvinceConqueredAction`, `RequestBattlesAction`
|
|
- All tests updated to handle optional battalions
|
|
|
|
**Key Migration Patterns:**
|
|
- ✅ Use specific components instead of full GameState (see ProvinceHeldAction, ProvinceConqueredAction)
|
|
- ✅ Convert protobuf models to Scala models at Action boundaries
|
|
- ✅ Update BUILD.bazel to remove protobuf dependencies
|
|
- ✅ Update all call sites and tests
|
|
- ✅ Use `Option[T]` for optional fields instead of special sentinel values (e.g., battalion ID -1)
|
|
|
|
**Next Migration Candidates (Simple Actions with Protoless Base):**
|
|
1. **FreeForAllDrawAction** - Already uses ProtolessSimpleAction
|
|
2. **FriendlyMoveAction** - Already uses ProtolessSimpleAction
|
|
3. **ShipmentArrivedAction** - Already uses ProtolessSimpleAction
|
|
4. **WonFreeForAllAction** - Already uses ProtolessSimpleAction
|
|
5. **ProvinceConqueredAction** - Already uses ProtolessSimpleAction, only needs `common_unit` migration
|
|
|
|
### 🔄 Conversion Strategy Updates
|
|
|
|
**Revised Approach Based on Analysis:**
|
|
|
|
1. **Focus on Core Dependencies First**
|
|
- Migrate `battalion_type` model (unlocks 2 commands immediately)
|
|
- Migrate `action_result` model (unlocks 12+ commands)
|
|
- Migrate `available_command`/`selected_command` (unlocks UI layer)
|
|
|
|
2. **Leverage Existing Success**
|
|
- 77.5% of commands already fully migrated
|
|
- Use migrated commands as reference implementations
|
|
- Diplomacy helpers prove complex business logic can work with Scala models
|
|
|
|
3. **Group Related Migrations**
|
|
- Military commands: `ArmTroopsCommand`, `TrainCommand`, `OrganizeTroopsCommand`
|
|
- UI commands: All using `available_command`/`selected_command`
|
|
- Diplomacy commands: All `Resolve*Command` variants
|
|
|
|
---
|
|
|
|
*Updated on 2025-09-17 - Analysis based on BUILD.bazel dependencies and code review*
|
|
*Latest update: ResolvedEagleUnit migrated to use Option[BattalionT] for proper battalion handling* |