# 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 _bankingProfiles; std::unordered_map> _transactionHistory; std::unordered_map _playerStatistics; std::unordered_map _lastBankAccessTimes; std::set _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` 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 _bankingProfiles; std::unordered_map _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(_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;` - Update `GameSystemsManager.cpp`: - Constructor: `_bankingManager = std::make_unique(_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 _activeSessions; std::unordered_map _profiles; std::unordered_map _lastFarmingTimes; std::unordered_map _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 _activeSessions; std::unordered_map _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> _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;` - Update `GameSystemsManager.cpp`: - Constructor: `_farmingCoordinator = std::make_unique(_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 _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 lock(_mutex); ``` ### 2. Facade Access Pattern ```cpp ProfessionManager* Manager::GetProfessionManager() { if (!_bot) return nullptr; BotSession* session = static_cast(_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; // Constructor _managerName = std::make_unique(_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)