Files
ThordekkCore/PHASE_5_PLAN.md
T

448 lines
16 KiB
Markdown
Raw Normal View History

2026-01-20 21:33:16 -03:00
# Phase 5: Management System Refactoring - Per-Bot Instance Pattern
**Status**: 📋 **PLANNED**
**Date**: 2025-11-18
**Branch**: `claude/playerbot-cleanup-analysis-01CcHSnAWQM7W9zVeUuJMF4h`
---
## Executive Summary
Phase 5 continues the architectural transformation from Phase 4, converting additional singleton manager systems to per-bot instances integrated into GameSystemsManager. This phase targets **management systems** with clear per-bot state that manage bot behaviors and resources.
### Scope
- **Managers to Convert**: 2 (BankingManager, FarmingCoordinator)
- **Estimated Lines**: ~2,000 across 14 files
- **New Managers in GameSystemsManager**: 21 → 23
- **Pattern**: Singleton → Per-Bot Instance (established in Phase 4)
---
## Architecture Analysis
### Current Singleton Landscape
After Phase 4 completion, I identified **90 files** with `static.*instance()` patterns in the PlayerBot module. These fall into three categories:
#### 1. Already Per-Bot (21 managers in GameSystemsManager)
✅ QuestManager, TradeManager, GatheringManager, ProfessionManager, 3 Bridges, AuctionManager, GroupCoordinator, DeathRecoveryManager, UnifiedMovementCoordinator, CombatStateManager, TargetScanner, GroupInvitationHandler, EventDispatcher, ManagerRegistry, 5 Decision Systems
#### 2. Should Stay Global (Infrastructure)
🔒 **BotTalentManager** - Immutable talent loadout cache shared by all bots
🔒 **ConfigManager** - Global configuration system
🔒 **PlayerbotDatabase** - Database connection pool
🔒 **BotLifecycleManager** - Global bot creation/spawning orchestration
🔒 **PlayerbotGroupManager** - Global group management
🔒 **LFGBotManager** - LFG queue management (global)
🔒 **SpatialGridManager** - Spatial indexing (global)
🔒 **BotPriorityManager** - Global bot priority scheduling
🔒 **Event Buses** - Global pub-sub systems (ProfessionEventBus, etc.)
#### 3. Should Be Per-Bot (Phase 5 Candidates)
🎯 **BankingManager** - Personal banking automation (★★★★★ High Priority)
🎯 **FarmingCoordinator** - Profession farming coordination (★★★★★ High Priority)
🎯 **EquipmentManager** - Equipment evaluation and auto-equip (★★★★ Medium Priority)
🎯 **MountManager** - Mount selection and usage (★★★ Lower Priority)
🎯 **BattlePetManager** - Battle pet management (★★★ Lower Priority)
🎯 **UnifiedQuestManager** - Quest management (complex, future phase)
🎯 **UnifiedLootManager** - Loot management (complex, group-based, future phase)
---
## Phase 5 Execution Plan
### Phase 5.1: BankingManager (22nd Manager)
**Priority**: ★★★★★ (Highest)
**Complexity**: Medium
**Estimated Time**: 2-3 hours
#### Why BankingManager First?
1. **Clear Per-Bot State**:
```cpp
std::unordered_map<uint32, BotBankingProfile> _bankingProfiles;
std::unordered_map<uint32, std::vector<BankingTransaction>> _transactionHistory;
std::unordered_map<uint32, BankingStatistics> _playerStatistics;
std::unordered_map<uint32, uint32> _lastBankAccessTimes;
std::set<uint32> _currentlyBanking;
```
2. **All Methods Take Player* Parameter**: 25+ methods all operate on `Player*`
3. **Inherits from BehaviorManager**: Already follows manager lifecycle pattern
4. **Coordinates with Profession Systems**: Integrates with ProfessionManager, GatheringMaterialsBridge, ProfessionAuctionBridge
5. **Thread-Safe via Mutex**: Uses `OrderedRecursiveMutex<TRADE_MANAGER>` for synchronization
#### BankingManager Statistics
- **File**: `src/modules/Playerbot/Banking/BankingManager.h` (494 lines)
- **File**: `src/modules/Playerbot/Banking/BankingManager.cpp` (~800 lines estimated)
- **Public Methods**: 25 methods
- **Key Features**:
- Gold management (auto-deposit/withdraw)
- Item management (deposit excess, withdraw for crafting)
- Banking rules and priorities
- Transaction history tracking
- Bank space analysis
- Banker access and travel
#### Conversion Steps
1. **Header Refactoring** (`BankingManager.h`):
- Remove `static instance()` method
- Add `explicit BankingManager(Player* bot);`
- Add `~BankingManager();` destructor
- Remove `Player*` parameters from all 25 methods
- Convert data structures:
```cpp
// BEFORE
std::unordered_map<uint32, BotBankingProfile> _bankingProfiles;
std::unordered_map<uint32, BankingStatistics> _playerStatistics;
// AFTER
BotBankingProfile _profile;
BankingStatistics _statistics;
uint32 _lastBankAccessTime{0};
bool _currentlyBanking{false};
```
- Keep shared data static (default banking rules, etc.)
2. **Implementation Refactoring** (`BankingManager.cpp`):
- Implement static member initialization
- Implement per-bot constructor/destructor
- Refactor all 25 methods to use `_bot` member
- Remove mutex locking (per-bot isolation)
- Update ProfessionManager access via GameSystemsManager facade:
```cpp
ProfessionManager* BankingManager::GetProfessionManager()
{
if (!_bot) return nullptr;
BotSession* session = static_cast<BotSession*>(_bot->GetSession());
if (!session || !session->GetBotAI()) return nullptr;
return session->GetBotAI()->GetGameSystems()->GetProfessionManager();
}
```
3. **GameSystemsManager Integration**:
- Update `GameSystemsManager.h`:
- Add include: `#include "Banking/BankingManager.h"`
- Add getter: `BankingManager* GetBankingManager() const { return _bankingManager.get(); }`
- Add member: `std::unique_ptr<BankingManager> _bankingManager;`
- Update `GameSystemsManager.cpp`:
- Constructor: `_bankingManager = std::make_unique<BankingManager>(_bot);`
- Initialize: Call `_bankingManager->OnInitialize();`
- Update: Call `_bankingManager->OnUpdate(diff);`
- Destructor: `_bankingManager.reset();`
4. **Legacy Cleanup**:
- Remove singleton registration from `PlayerbotModule.cpp`
- Remove DI registration from `ServiceRegistration.h`
- Update any direct `BankingManager::instance()` calls
5. **Testing**:
- Verify bot banking automation works
- Test gold deposit/withdrawal triggers
- Test item banking rules
- Test profession material coordination
---
### Phase 5.2: FarmingCoordinator (23rd Manager)
**Priority**: ★★★★★ (Highest)
**Complexity**: Medium-High
**Estimated Time**: 2-3 hours
#### Why FarmingCoordinator Second?
1. **Clear Per-Bot State**:
```cpp
std::unordered_map<uint32, FarmingSession> _activeSessions;
std::unordered_map<uint32, FarmingCoordinatorProfile> _profiles;
std::unordered_map<uint32, uint32> _lastFarmingTimes;
std::unordered_map<uint32, FarmingStatistics> _playerStatistics;
```
2. **All Methods Take Player* Parameter**: 19+ methods all operate on `Player*`
3. **Complex Profession Coordination**: Works with ProfessionManager, GatheringManager, auction systems
4. **Session Management**: Manages farming sessions per bot with state tracking
5. **Zone Selection Logic**: Per-bot zone scoring and travel logic
#### FarmingCoordinator Statistics
- **File**: `src/modules/Playerbot/Professions/FarmingCoordinator.h` (383 lines)
- **File**: `src/modules/Playerbot/Professions/FarmingCoordinator.cpp` (~1,200 lines estimated)
- **Public Methods**: 19 methods
- **Key Features**:
- Skill gap analysis (character level vs profession skill)
- Farming session management (start/stop/update)
- Zone selection and optimization
- Material stockpile management
- Travel and positioning
- Statistics tracking
#### Conversion Steps
1. **Header Refactoring** (`FarmingCoordinator.h`):
- Remove `static instance()` method
- Add `explicit FarmingCoordinator(Player* bot);`
- Add `~FarmingCoordinator();` destructor
- Remove `Player*` parameters from all 19 methods
- Convert data structures:
```cpp
// BEFORE
std::unordered_map<uint32, FarmingSession> _activeSessions;
std::unordered_map<uint32, FarmingCoordinatorProfile> _profiles;
// AFTER
FarmingSession _activeSession; // Only one session per bot
FarmingCoordinatorProfile _profile;
uint32 _lastFarmingTime{0};
FarmingStatistics _statistics;
```
- Keep shared data static (farming zones, node database, etc.):
```cpp
static std::unordered_map<ProfessionType, std::vector<FarmingZoneInfo>> _farmingZones;
static bool _farmingZonesInitialized;
```
2. **Implementation Refactoring** (`FarmingCoordinator.cpp`):
- Implement static member initialization (farming zones)
- Implement per-bot constructor/destructor
- Refactor all 19 methods to use `_bot` member
- Remove mutex locking (per-bot isolation)
- Update ProfessionManager/GatheringManager access via facade
3. **GameSystemsManager Integration**:
- Update `GameSystemsManager.h`:
- Add include: `#include "Professions/FarmingCoordinator.h"`
- Add getter: `FarmingCoordinator* GetFarmingCoordinator() const { return _farmingCoordinator.get(); }`
- Add member: `std::unique_ptr<FarmingCoordinator> _farmingCoordinator;`
- Update `GameSystemsManager.cpp`:
- Constructor: `_farmingCoordinator = std::make_unique<FarmingCoordinator>(_bot);`
- Initialize: Call `_farmingCoordinator->Initialize(_bot);`
- Update: Call `_farmingCoordinator->Update(diff);`
- Destructor: `_farmingCoordinator.reset();`
4. **Legacy Cleanup**:
- Remove singleton registration from `PlayerbotModule.cpp`
- Update any direct `FarmingCoordinator::instance()` calls
5. **Testing**:
- Verify farming session triggers when skill gap detected
- Test zone selection and travel
- Test farming session completion
- Test material stockpile coordination
---
## Established Patterns (From Phase 4)
### 1. Singleton → Per-Bot Transformation Pattern
```cpp
// STEP 1: Remove singleton
- static Bridge* instance();
+ explicit Bridge(Player* bot);
+ ~Bridge();
// STEP 2: Convert data structures
- std::unordered_map<playerGuid, T> _playerData;
+ T _data; // Direct member
// STEP 3: Update method signatures
- void Method(Player* player, ...);
+ void Method(...); // Use _bot instead
// STEP 4: Add static shared data
+ static SharedData _sharedData;
+ static bool _sharedDataInitialized;
// STEP 5: Remove mutex (per-bot isolation)
- std::mutex _mutex;
- std::lock_guard<std::mutex> lock(_mutex);
```
### 2. Facade Access Pattern
```cpp
ProfessionManager* Manager::GetProfessionManager()
{
if (!_bot) return nullptr;
BotSession* session = static_cast<BotSession*>(_bot->GetSession());
if (!session || !session->GetBotAI()) return nullptr;
return session->GetBotAI()->GetGameSystems()->GetProfessionManager();
}
```
### 3. GameSystemsManager Integration Pattern
```cpp
// Header
#include "Path/ManagerName.h"
ManagerName* GetManagerName() const { return _managerName.get(); }
std::unique_ptr<ManagerName> _managerName;
// Constructor
_managerName = std::make_unique<ManagerName>(_bot);
// Initialize
if (_managerName)
{
_managerName->Initialize(_bot); // or OnInitialize() for BehaviorManager
TC_LOG_DEBUG("playerbot", "GameSystemsManager: ManagerName initialized");
}
// Update
if (_managerName)
_managerName->Update(diff); // or OnUpdate() for BehaviorManager
// Destructor (explicit ordering)
_managerName.reset();
```
---
## Performance Improvements Expected
### Memory Optimization
| Aspect | Before | After | Improvement |
|--------|--------|-------|-------------|
| Map Overhead | ~48 bytes/entry | 0 bytes | 100% reduction |
| Cache Locality | Poor (scattered) | Excellent (contiguous) | 40% estimated |
| Memory per Bot | Variable | Fixed | 30-50% reduction |
### Concurrency Improvements
| Aspect | Before | After | Improvement |
|--------|--------|-------|-------------|
| Mutex Locks | Required | Zero | 100% elimination |
| Lock Contention | High (100+ bots) | None | ∞% improvement |
| Thread Safety | Explicit locking | Implicit isolation | Simplified |
---
## Testing Strategy
### Per-Phase Testing
1. **Compilation**: Ensure all files compile without errors
2. **Linkage**: Verify no undefined references
3. **Runtime**: Test bot creation, initialization, update loop
4. **Integration**: Verify manager interactions work correctly
5. **Performance**: Monitor memory usage and CPU contention
### Integration Testing
1. **Banking Automation**:
- Bot deposits gold when exceeds threshold
- Bot withdraws materials for crafting
- Bank space optimization works
2. **Farming Coordination**:
- Bot detects skill gap and starts farming session
- Bot travels to optimal farming zone
- Bot gathers nodes and gains skill points
- Session completes when target skill reached
3. **Cross-Manager Coordination**:
- BankingManager ↔ ProfessionManager (material needs)
- FarmingCoordinator ↔ GatheringManager (node harvesting)
- FarmingCoordinator ↔ ProfessionManager (skill tracking)
---
## Migration Guide for Developers
### Old Code (Singleton)
```cpp
BankingManager::instance()->DepositGold(player, 50000);
FarmingCoordinator::instance()->StartFarmingSession(player, ProfessionType::MINING);
```
### New Code (Per-Bot)
```cpp
auto* gameSystems = botAI->GetGameSystems();
gameSystems->GetBankingManager()->DepositGold(50000);
gameSystems->GetFarmingCoordinator()->StartFarmingSession(ProfessionType::MINING);
```
**Key Differences**:
1. No more `::instance()` calls
2. No more `Player* player` parameters
3. Access via `GameSystemsManager` facade
4. Each bot has its own manager instances
---
## Future Phases (Phase 6+)
### Phase 6 Candidates (Medium Priority)
- **EquipmentManager** - Equipment evaluation and auto-equip (per-bot profiles, metrics)
- **MountManager** - Mount selection and usage (per-bot preferences)
- **BattlePetManager** - Battle pet management (per-bot collection)
### Complex Refactoring (Future)
- **UnifiedQuestManager** - Large manager with 100+ methods (requires careful analysis)
- **UnifiedLootManager** - Group-based loot coordination (complex interactions)
- **GuildBankManager** - Guild-level vs per-bot considerations
---
## Success Criteria
Phase 5 is considered complete when:
- ✅ BankingManager converted to per-bot instance (22nd manager)
- ✅ FarmingCoordinator converted to per-bot instance (23rd manager)
- ✅ Both managers integrated into GameSystemsManager
- ✅ All legacy singleton calls removed
- ✅ Code compiles without errors
- ✅ Integration tests pass
- ✅ Documentation updated (PHASE_5_COMPLETE.md)
- ✅ DEVELOPER_GUIDE.md updated with new managers
---
## Risks and Mitigations
### Risk 1: Breaking Existing Functionality
**Mitigation**: Systematic testing after each conversion, maintain backward compatibility during transition
### Risk 2: Performance Regression
**Mitigation**: Profile before/after, measure memory usage and lock contention
### Risk 3: Complex Dependencies
**Mitigation**: Use facade access pattern, document all cross-manager interactions
### Risk 4: Initialization Ordering
**Mitigation**: Follow established GameSystemsManager initialization order, document dependencies
---
## Conclusion
Phase 5 continues the architectural evolution from Phase 4, converting 2 high-priority management systems from singleton to per-bot instances. This phase targets systems with clear per-bot state and strong integration with the profession ecosystem.
**Expected Benefits**:
- Zero lock contention (100% mutex elimination for these 2 managers)
- Better cache locality (direct members vs maps)
- Cleaner API (no Player* parameters)
- Clear ownership (facade pattern)
- Improved scalability (per-bot isolation)
**GameSystemsManager Evolution**: 21 → 23 managers
---
**Document Version**: 1.0
**Last Updated**: 2025-11-18
**Author**: Claude (Anthropic)