Files
ThordekkCore/PHASE_1_FOUNDATION_SUBPLAN.md
T

1133 lines
32 KiB
Markdown
Raw Normal View History

2026-01-20 21:33:16 -03:00
# PHASE 1: FOUNDATION - ENTERPRISE IMPLEMENTATION SUBPLAN
**Version**: 1.0.0
**Status**: READY FOR EXECUTION
**Total Estimated Hours**: 85 hours (2.1 weeks @ 40hrs/week)
**Total Lines of Code**: ~2,100 lines production + ~3,000 lines tests
## EXECUTIVE SUMMARY
Phase 1 establishes the architectural foundation for the PlayerBot refactoring, implementing a robust state machine framework with comprehensive safety guarantees. This foundation will support 5000 concurrent bots with <0.05% CPU overhead per bot through lock-free designs and cache-optimized data structures.
## 1. IMPLEMENTATION ORDER & TASK BREAKDOWN
### Critical Path Tasks (Must Complete in Order)
#### TASK 1.1: Core State Machine Types & Enums
**ID**: FSM-001
**Duration**: 3 hours
**Agent**: cpp-architecture-optimizer (Opus)
**Dependencies**: None
**Files to Create**:
- `src/modules/Playerbot/Core/StateMachine/BotStateTypes.h` (200 lines)
**Acceptance Criteria**:
- ✅ All bot states enumerated with proper categorization
- ✅ State transition matrix defined
- ✅ Event types comprehensive (30+ event types)
- ✅ Priority levels implemented (0-255 range)
- ✅ Thread-safe atomic types used
**Implementation**:
```cpp
// BotStateTypes.h
#pragma once
#include <atomic>
#include <cstdint>
#include <string_view>
#include <array>
namespace Playerbot::StateMachine {
// Primary bot states - mutually exclusive
enum class BotState : uint8_t {
// Initialization states (0-15)
UNINITIALIZED = 0,
INITIALIZING = 1,
LOADING_DATA = 2,
VALIDATING = 3,
// Operational states (16-31)
IDLE = 16,
FOLLOWING = 17,
COMBAT = 18,
CASTING = 19,
LOOTING = 20,
TRADING = 21,
// Movement states (32-47)
MOVING_TO_TARGET = 32,
PATHING = 33,
EVADING = 34,
FLEEING = 35,
// Group states (48-63)
WAITING_FOR_GROUP = 48,
FORMING_GROUP = 49,
IN_INSTANCE = 50,
// Error states (240-255)
ERROR = 240,
RECOVERING = 241,
SHUTDOWN = 254,
TERMINATED = 255
};
// State flags - can be combined
enum class StateFlags : uint32_t {
NONE = 0,
IN_COMBAT = (1 << 0),
IS_DEAD = (1 << 1),
IS_CASTING = (1 << 2),
IS_MOVING = (1 << 3),
HAS_TARGET = (1 << 4),
IN_GROUP = (1 << 5),
IS_LEADER = (1 << 6),
NEEDS_MANA = (1 << 7),
NEEDS_HEALTH = (1 << 8),
HAS_AGGRO = (1 << 9),
IS_MOUNTED = (1 << 10),
IN_STEALTH = (1 << 11),
IS_FLYING = (1 << 12),
PVP_FLAGGED = (1 << 13),
IN_BATTLEGROUND = (1 << 14),
IN_ARENA = (1 << 15)
};
// Event types that trigger state transitions
enum class EventType : uint16_t {
// System events (0-31)
SYSTEM_STARTUP = 0,
SYSTEM_SHUTDOWN = 1,
SYSTEM_ERROR = 2,
// Combat events (32-63)
COMBAT_START = 32,
COMBAT_END = 33,
THREAT_GAINED = 34,
THREAT_LOST = 35,
DAMAGE_TAKEN = 36,
DAMAGE_DEALT = 37,
TARGET_DIED = 38,
TARGET_CHANGED = 39,
// Movement events (64-95)
MOVEMENT_START = 64,
MOVEMENT_STOP = 65,
PATH_COMPLETE = 66,
PATH_FAILED = 67,
COLLISION = 68,
// Group events (96-127)
GROUP_INVITE = 96,
GROUP_JOIN = 97,
GROUP_LEAVE = 98,
GROUP_DISBAND = 99,
LEADER_CHANGED = 100,
// Custom events (1000+)
CUSTOM_BASE = 1000
};
// Priority for state transitions (higher = more important)
using Priority = uint8_t;
constexpr Priority PRIORITY_CRITICAL = 255;
constexpr Priority PRIORITY_HIGH = 192;
constexpr Priority PRIORITY_NORMAL = 128;
constexpr Priority PRIORITY_LOW = 64;
constexpr Priority PRIORITY_IDLE = 0;
// Thread-safe state container
struct StateInfo {
std::atomic<BotState> current{BotState::UNINITIALIZED};
std::atomic<BotState> previous{BotState::UNINITIALIZED};
std::atomic<StateFlags> flags{StateFlags::NONE};
std::atomic<uint64_t> transitionCount{0};
std::atomic<uint64_t> lastTransitionTime{0};
std::atomic<Priority> currentPriority{PRIORITY_IDLE};
};
// State transition validation result
struct TransitionResult {
bool allowed;
BotState newState;
std::string_view reason;
Priority priority;
};
// State metadata for runtime introspection
struct StateMetadata {
std::string_view name;
std::string_view description;
Priority defaultPriority;
uint32_t allowedFlags;
bool isTerminal;
bool isError;
};
// Compile-time state metadata table
constexpr std::array<StateMetadata, 256> STATE_METADATA = {{
{"UNINITIALIZED", "Bot not yet initialized", PRIORITY_IDLE, 0, false, false},
{"INITIALIZING", "Bot initialization in progress", PRIORITY_HIGH, 0, false, false},
// ... (complete for all states)
}};
} // namespace Playerbot::StateMachine
```
---
#### TASK 1.2: State Transition Matrix & Validators
**ID**: FSM-002
**Duration**: 5 hours
**Agent**: cpp-architecture-optimizer (Opus)
**Dependencies**: FSM-001
**Files to Create**:
- `src/modules/Playerbot/Core/StateMachine/StateTransitions.h` (150 lines)
- `src/modules/Playerbot/Core/StateMachine/StateValidators.h` (150 lines)
- `src/modules/Playerbot/Core/StateMachine/StateValidators.cpp` (300 lines)
**Acceptance Criteria**:
- ✅ Complete state transition matrix (all valid transitions)
- ✅ O(1) transition validation
- ✅ Thread-safe validation functions
- ✅ Comprehensive unit tests (100% coverage)
- ✅ Performance: <100ns per validation
**Implementation**:
```cpp
// StateTransitions.h
#pragma once
#include "BotStateTypes.h"
#include <bitset>
namespace Playerbot::StateMachine {
// Compile-time transition matrix using bitsets for O(1) lookup
class TransitionMatrix {
public:
static constexpr size_t STATE_COUNT = 256;
using TransitionBits = std::bitset<STATE_COUNT>;
// Check if transition is valid in O(1)
[[nodiscard]] static constexpr bool IsValidTransition(
BotState from, BotState to) noexcept {
return VALID_TRANSITIONS[static_cast<uint8_t>(from)]
.test(static_cast<uint8_t>(to));
}
// Get all valid transitions from a state
[[nodiscard]] static constexpr TransitionBits GetValidTransitions(
BotState from) noexcept {
return VALID_TRANSITIONS[static_cast<uint8_t>(from)];
}
private:
// Compile-time generation of transition matrix
static constexpr std::array<TransitionBits, STATE_COUNT>
GenerateTransitionMatrix() noexcept {
std::array<TransitionBits, STATE_COUNT> matrix{};
// Define all valid transitions
// UNINITIALIZED -> INITIALIZING
matrix[0].set(1);
// INITIALIZING -> LOADING_DATA, ERROR
matrix[1].set(2);
matrix[1].set(240);
// LOADING_DATA -> VALIDATING, ERROR
matrix[2].set(3);
matrix[2].set(240);
// VALIDATING -> IDLE, ERROR
matrix[3].set(16);
matrix[3].set(240);
// IDLE -> any operational state
for (uint8_t i = 17; i <= 50; ++i) {
matrix[16].set(i);
}
// Combat can transition to most states
matrix[18].set(16); // COMBAT -> IDLE
matrix[18].set(20); // COMBAT -> LOOTING
matrix[18].set(34); // COMBAT -> EVADING
matrix[18].set(35); // COMBAT -> FLEEING
// Error recovery paths
matrix[240].set(241); // ERROR -> RECOVERING
matrix[241].set(16); // RECOVERING -> IDLE
matrix[241].set(254); // RECOVERING -> SHUTDOWN
// Terminal states
matrix[254].set(255); // SHUTDOWN -> TERMINATED
return matrix;
}
static constexpr auto VALID_TRANSITIONS = GenerateTransitionMatrix();
};
// Priority-based transition rules
class TransitionRules {
public:
// Check if transition should override current state based on priority
[[nodiscard]] static bool ShouldOverride(
Priority current, Priority incoming) noexcept {
return incoming > current;
}
// Calculate transition priority based on event and state
[[nodiscard]] static Priority CalculatePriority(
EventType event, BotState currentState) noexcept;
// Validate transition with context
[[nodiscard]] static TransitionResult ValidateTransition(
const StateInfo& state,
BotState targetState,
EventType event) noexcept;
};
} // namespace Playerbot::StateMachine
```
---
#### TASK 1.3: Core State Machine Implementation
**ID**: FSM-003
**Duration**: 8 hours
**Agent**: cpp-architecture-optimizer (Opus) + concurrency-threading-specialist (Opus)
**Dependencies**: FSM-001, FSM-002
**Files to Create**:
- `src/modules/Playerbot/Core/StateMachine/BotStateMachine.h` (300 lines)
- `src/modules/Playerbot/Core/StateMachine/BotStateMachine.cpp` (500 lines)
**Acceptance Criteria**:
- ✅ Lock-free state transitions using atomics
- ✅ Event queue with bounded capacity (1024 events)
- ✅ O(1) state queries
- ✅ Memory usage <1KB per state machine
- ✅ Thread-safe for 5000 concurrent instances
- ✅ Performance: <500ns per state transition
**Implementation**:
```cpp
// BotStateMachine.h
#pragma once
#include "BotStateTypes.h"
#include "StateTransitions.h"
#include <atomic>
#include <memory>
#include <functional>
#include <chrono>
#include <optional>
namespace Playerbot::StateMachine {
// Forward declarations
class StateObserver;
class StateHistory;
// Lock-free state machine with event queue
class BotStateMachine {
public:
using StateCallback = std::function<void(BotState, BotState)>;
using EventHandler = std::function<void(EventType, const void*)>;
using Clock = std::chrono::steady_clock;
using TimePoint = Clock::time_point;
// Constructor/Destructor
explicit BotStateMachine(ObjectGuid botGuid);
~BotStateMachine();
// Non-copyable, non-movable (stateful)
BotStateMachine(const BotStateMachine&) = delete;
BotStateMachine& operator=(const BotStateMachine&) = delete;
BotStateMachine(BotStateMachine&&) = delete;
BotStateMachine& operator=(BotStateMachine&&) = delete;
// State queries (lock-free, wait-free)
[[nodiscard]] BotState GetCurrentState() const noexcept {
return m_state.current.load(std::memory_order_acquire);
}
[[nodiscard]] BotState GetPreviousState() const noexcept {
return m_state.previous.load(std::memory_order_acquire);
}
[[nodiscard]] StateFlags GetStateFlags() const noexcept {
return m_state.flags.load(std::memory_order_acquire);
}
[[nodiscard]] bool IsInState(BotState state) const noexcept {
return GetCurrentState() == state;
}
[[nodiscard]] bool HasFlag(StateFlags flag) const noexcept {
auto flags = GetStateFlags();
return (static_cast<uint32_t>(flags) &
static_cast<uint32_t>(flag)) != 0;
}
// State transitions (lock-free)
[[nodiscard]] bool TransitionTo(
BotState newState,
EventType trigger = EventType::SYSTEM_STARTUP,
Priority priority = PRIORITY_NORMAL);
[[nodiscard]] bool TryTransitionTo(
BotState newState,
std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
// Event handling (lock-free queue)
bool PostEvent(EventType event,
const void* data = nullptr,
Priority priority = PRIORITY_NORMAL);
void ProcessEvents(uint32_t maxEvents = 10);
// Flag management (atomic operations)
void SetFlag(StateFlags flag) noexcept;
void ClearFlag(StateFlags flag) noexcept;
void ToggleFlag(StateFlags flag) noexcept;
// Observer pattern for state changes
void RegisterObserver(std::shared_ptr<StateObserver> observer);
void UnregisterObserver(std::shared_ptr<StateObserver> observer);
// Statistics and debugging
[[nodiscard]] uint64_t GetTransitionCount() const noexcept {
return m_state.transitionCount.load(std::memory_order_relaxed);
}
[[nodiscard]] TimePoint GetLastTransitionTime() const noexcept;
[[nodiscard]] std::optional<StateHistory> GetHistory(size_t count) const;
// Validation
[[nodiscard]] bool ValidateState() const noexcept;
[[nodiscard]] bool CanTransitionTo(BotState target) const noexcept;
private:
// Core state storage (cache-line aligned)
alignas(64) StateInfo m_state;
// Bot identifier
const ObjectGuid m_botGuid;
// Lock-free event queue (MPSC)
struct Event {
EventType type;
Priority priority;
TimePoint timestamp;
const void* data;
};
// Bounded lock-free queue implementation
class EventQueue {
public:
static constexpr size_t CAPACITY = 1024;
bool Push(const Event& event) noexcept;
bool Pop(Event& event) noexcept;
[[nodiscard]] bool IsEmpty() const noexcept;
[[nodiscard]] size_t Size() const noexcept;
private:
alignas(64) std::atomic<size_t> m_head{0};
alignas(64) std::atomic<size_t> m_tail{0};
std::array<std::atomic<Event*>, CAPACITY> m_buffer{};
};
alignas(64) EventQueue m_eventQueue;
// Observer management (RCU-style)
mutable std::shared_mutex m_observerMutex;
std::vector<std::weak_ptr<StateObserver>> m_observers;
// State history ring buffer
static constexpr size_t HISTORY_SIZE = 32;
struct HistoryEntry {
BotState state;
EventType trigger;
TimePoint timestamp;
Priority priority;
};
alignas(64) std::array<HistoryEntry, HISTORY_SIZE> m_history;
std::atomic<size_t> m_historyIndex{0};
// Internal methods
bool DoTransition(BotState newState, EventType trigger, Priority priority);
void NotifyObservers(BotState oldState, BotState newState);
void RecordHistory(BotState state, EventType trigger, Priority priority);
void HandleEvent(const Event& event);
// Performance counters
alignas(64) struct {
std::atomic<uint64_t> totalTransitions{0};
std::atomic<uint64_t> failedTransitions{0};
std::atomic<uint64_t> eventsProcessed{0};
std::atomic<uint64_t> eventsDropped{0};
} m_stats;
};
// State observer interface
class StateObserver {
public:
virtual ~StateObserver() = default;
virtual void OnStateChanged(ObjectGuid botGuid,
BotState oldState,
BotState newState) = 0;
virtual void OnFlagChanged(ObjectGuid botGuid,
StateFlags oldFlags,
StateFlags newFlags) = 0;
};
} // namespace Playerbot::StateMachine
```
---
#### TASK 1.4: Initialization State Machine
**ID**: FSM-004
**Duration**: 6 hours
**Agent**: cpp-architecture-optimizer (Opus)
**Dependencies**: FSM-003
**Files to Create**:
- `src/modules/Playerbot/Core/StateMachine/BotInitStateMachine.h` (200 lines)
- `src/modules/Playerbot/Core/StateMachine/BotInitStateMachine.cpp` (400 lines)
**Acceptance Criteria**:
- ✅ Specialized initialization flow with checkpoints
- ✅ Rollback capability on failure
- ✅ Progress tracking (0-100%)
- ✅ Timeout handling for each phase
- ✅ Integration with TrinityCore Player initialization
---
#### TASK 1.5: Safe Reference System
**ID**: REF-001
**Duration**: 6 hours
**Agent**: concurrency-threading-specialist (Opus)
**Dependencies**: None (parallel with FSM tasks)
**Files to Create**:
- `src/modules/Playerbot/Core/Memory/SafeReference.h` (400 lines)
- `src/modules/Playerbot/Core/Memory/ReferenceValidator.h` (200 lines)
- `src/modules/Playerbot/Core/Memory/ReferenceValidator.cpp` (300 lines)
**Acceptance Criteria**:
- ✅ RAII-based reference management
- ✅ Automatic validation before access
- ✅ Zero overhead in release builds
- ✅ Thread-safe reference counting
- ✅ Integration with ObjectAccessor
---
#### TASK 1.6: Event System Framework
**ID**: EVT-001
**Duration**: 8 hours
**Agent**: concurrency-threading-specialist (Opus)
**Dependencies**: FSM-003
**Files to Create**:
- `src/modules/Playerbot/Core/Events/EventDispatcher.h` (300 lines)
- `src/modules/Playerbot/Core/Events/EventDispatcher.cpp` (500 lines)
- `src/modules/Playerbot/Core/Events/EventSubscriber.h` (150 lines)
**Acceptance Criteria**:
- ✅ Lock-free event dispatch
- ✅ Priority-based event processing
- ✅ Event batching for performance
- ✅ <1μs dispatch latency
- ✅ Support for 10,000 events/second
---
#### TASK 1.7: Behavior Interface Definitions
**ID**: BEH-001
**Duration**: 4 hours
**Agent**: cpp-architecture-optimizer (Opus)
**Dependencies**: FSM-003
**Files to Create**:
- `src/modules/Playerbot/Core/Behavior/IBehavior.h` (200 lines)
- `src/modules/Playerbot/Core/Behavior/BehaviorContext.h` (150 lines)
- `src/modules/Playerbot/Core/Behavior/BehaviorResult.h` (100 lines)
**Acceptance Criteria**:
- ✅ Pure virtual interfaces (no implementation)
- ✅ Context passing without allocation
- ✅ Result types for all outcomes
- ✅ Composable behavior chains
- ✅ Testability through mocking
---
#### TASK 1.8: State Machine Unit Tests
**ID**: TEST-001
**Duration**: 10 hours
**Agent**: test-automation-engineer (Sonnet)
**Dependencies**: FSM-001 through FSM-004
**Files to Create**:
- `src/modules/Playerbot/Tests/StateMachine/BotStateMachineTest.cpp` (800 lines)
- `src/modules/Playerbot/Tests/StateMachine/StateValidatorTest.cpp` (400 lines)
- `src/modules/Playerbot/Tests/StateMachine/TransitionMatrixTest.cpp` (300 lines)
- `src/modules/Playerbot/Tests/StateMachine/InitStateMachineTest.cpp` (500 lines)
**Acceptance Criteria**:
- ✅ 100% code coverage
- ✅ Thread safety tests (TSan clean)
- ✅ Performance benchmarks included
- ✅ Edge case coverage
- ✅ Mock implementations for dependencies
---
#### TASK 1.9: Safe Reference Unit Tests
**ID**: TEST-002
**Duration**: 6 hours
**Agent**: test-automation-engineer (Sonnet)
**Dependencies**: REF-001
**Files to Create**:
- `src/modules/Playerbot/Tests/Memory/SafeReferenceTest.cpp` (600 lines)
- `src/modules/Playerbot/Tests/Memory/ReferenceValidatorTest.cpp` (400 lines)
---
#### TASK 1.10: Event System Unit Tests
**ID**: TEST-003
**Duration**: 6 hours
**Agent**: test-automation-engineer (Sonnet)
**Dependencies**: EVT-001
**Files to Create**:
- `src/modules/Playerbot/Tests/Events/EventDispatcherTest.cpp` (600 lines)
- `src/modules/Playerbot/Tests/Events/EventSubscriberTest.cpp` (300 lines)
---
#### TASK 1.11: Integration Tests
**ID**: TEST-004
**Duration**: 8 hours
**Agent**: trinity-integration-tester (Sonnet)
**Dependencies**: All previous tasks
**Files to Create**:
- `src/modules/Playerbot/Tests/Integration/StateMachineIntegrationTest.cpp` (500 lines)
- `src/modules/Playerbot/Tests/Integration/EventSystemIntegrationTest.cpp` (400 lines)
---
#### TASK 1.12: Performance Profiling & Optimization
**ID**: PERF-001
**Duration**: 10 hours
**Agent**: windows-memory-profiler (Sonnet) + resource-monitor-limiter (Sonnet)
**Dependencies**: All implementation tasks
**Files to Create**:
- `src/modules/Playerbot/Tests/Performance/StateMachineBenchmark.cpp` (400 lines)
- `src/modules/Playerbot/Tests/Performance/MemoryProfileTest.cpp` (300 lines)
**Acceptance Criteria**:
- ✅ Memory usage <1KB per state machine
- ✅ State transition <500ns
- ✅ Event dispatch <1μs
- ✅ No memory leaks (Valgrind/ASan clean)
- ✅ 5000 concurrent instances stable
---
#### TASK 1.13: Documentation & Code Review
**ID**: DOC-001
**Duration**: 6 hours
**Agent**: code-quality-reviewer (Sonnet)
**Dependencies**: All tasks
**Files to Create**:
- `src/modules/Playerbot/Docs/StateMachineArchitecture.md` (500 lines)
- `src/modules/Playerbot/Docs/API/Phase1API.md` (400 lines)
---
## 2. COMPONENT SPECIFICATIONS
### 2.1 BotStateMachine Component
**Purpose**: Core state management with lock-free transitions and event processing
**Responsibility**:
- Maintain current bot state atomically
- Validate and execute state transitions
- Process events with priority ordering
- Notify observers of state changes
- Track state history for debugging
**Public API**:
```cpp
class BotStateMachine {
public:
// State queries - O(1), lock-free
BotState GetCurrentState() const noexcept;
bool IsInState(BotState state) const noexcept;
bool HasFlag(StateFlags flag) const noexcept;
// State transitions - lock-free
bool TransitionTo(BotState newState, EventType trigger, Priority priority);
bool CanTransitionTo(BotState target) const noexcept;
// Event handling
bool PostEvent(EventType event, const void* data, Priority priority);
void ProcessEvents(uint32_t maxEvents);
// Observer pattern
void RegisterObserver(std::shared_ptr<StateObserver> observer);
};
```
**Key Algorithms**:
- Lock-free MPSC queue for events (Dmitry Vyukov's algorithm)
- RCU-style observer management
- Cache-line aligned data structures
- Memory-ordered atomic operations
**TrinityCore 11.2 APIs**:
- `ObjectGuid` for bot identification
- `Player*` validation through `ObjectAccessor`
- `sWorld->GetGameTime()` for timestamps
- Thread primitives from `Common.h`
**Performance Requirements**:
- State transition: <500ns
- Memory per instance: <1KB
- Cache misses: <2 per transition
- Lock contention: 0 (lock-free)
**Error Handling**:
- Invalid transitions return false (no exceptions)
- Event queue overflow drops lowest priority
- Null checks on all external pointers
- Graceful degradation on memory pressure
**Thread Safety**:
- All public methods thread-safe
- Lock-free algorithms throughout
- Memory ordering specified explicitly
- No data races (TSan verified)
### 2.2 SafeReference Component
**Purpose**: RAII-based safe pointer management with automatic validation
**Responsibility**:
- Wrap TrinityCore pointers safely
- Validate before every access
- Automatic cleanup on scope exit
- Thread-safe reference counting
- Zero overhead in release mode
**Public API**:
```cpp
template<typename T>
class SafeRef {
public:
explicit SafeRef(T* ptr);
SafeRef(ObjectGuid guid);
// Access with validation
T* operator->() const;
T& operator*() const;
explicit operator bool() const noexcept;
// Explicit operations
bool IsValid() const noexcept;
void Reset(T* ptr = nullptr);
T* Release() noexcept;
};
```
**TrinityCore 11.2 APIs**:
- `ObjectAccessor::GetPlayer()`
- `ObjectAccessor::GetCreature()`
- `Map::GetPlayer()`
- GUID validation APIs
### 2.3 EventDispatcher Component
**Purpose**: High-performance event routing with priority and batching
**Responsibility**:
- Route events to subscribers
- Priority-based processing
- Event batching for efficiency
- Lock-free dispatch
- Subscriber lifecycle management
**Public API**:
```cpp
class EventDispatcher {
public:
// Event posting
void Post(EventType type, const void* data, Priority priority);
void PostDelayed(EventType type, const void* data, uint32_t delayMs);
// Subscription management
SubscriptionId Subscribe(EventType type, EventHandler handler);
void Unsubscribe(SubscriptionId id);
// Processing
void ProcessEvents(uint32_t maxEvents, uint32_t maxTimeMs);
void ProcessPriority(Priority minPriority);
};
```
## 3. TESTING STRATEGY
### 3.1 Unit Test Requirements
**Per Component Test Coverage**:
- BotStateMachine: 50 tests minimum
- All state transitions (30 tests)
- Flag operations (5 tests)
- Event queue operations (10 tests)
- Edge cases (5 tests)
- SafeReference: 30 tests minimum
- Valid/invalid pointers (10 tests)
- Thread safety (10 tests)
- RAII behavior (5 tests)
- Performance benchmarks (5 tests)
- EventDispatcher: 40 tests minimum
- Event routing (15 tests)
- Priority handling (10 tests)
- Subscription management (10 tests)
- Performance under load (5 tests)
### 3.2 Integration Test Scenarios
1. **Multi-Bot State Coordination** (10 scenarios)
- 100 bots transitioning simultaneously
- Cascade state changes through events
- Group state synchronization
2. **Memory Pressure Testing** (5 scenarios)
- 5000 state machines concurrent
- Memory allocation failures
- Reference invalidation cascades
3. **Event Storm Handling** (5 scenarios)
- 100,000 events/second
- Priority inversion scenarios
- Queue overflow recovery
### 3.3 Performance Benchmarks
**Required Benchmarks**:
```cpp
BENCHMARK(BM_StateTransition)->Range(1, 5000);
BENCHMARK(BM_EventDispatch)->Range(100, 100000);
BENCHMARK(BM_SafeRefAccess)->Range(1, 10000);
BENCHMARK(BM_ConcurrentTransitions)->Threads(16);
```
**Target Metrics**:
- State transition: <500ns (p99)
- Event dispatch: <1μs (p99)
- Memory per bot: <1KB
- CPU per bot: <0.05%
### 3.4 Mock/Stub Requirements
**Required Mocks**:
- `MockPlayer` - TrinityCore Player interface
- `MockObjectAccessor` - GUID lookups
- `MockMap` - Map operations
- `MockWorld` - Global state
## 4. CLAUDE.md COMPLIANCE CHECKLIST
### For Each Component
#### ✅ Complete Implementation
- [ ] No TODO comments
- [ ] No placeholder functions
- [ ] All error paths handled
- [ ] Full algorithm implementation
- [ ] Documentation complete
#### ✅ Module-Only Code
- [ ] All code in src/modules/Playerbot/
- [ ] No core file modifications
- [ ] Hook pattern for integration
- [ ] Clean module boundaries
#### ✅ TrinityCore 11.2 APIs
- [ ] All APIs verified to exist
- [ ] Correct parameter types
- [ ] Return value handling
- [ ] Version compatibility checked
#### ✅ Error Handling
- [ ] All pointers validated
- [ ] All returns checked
- [ ] Graceful degradation
- [ ] No uncaught exceptions
- [ ] Logging on errors
#### ✅ Performance
- [ ] Memory usage measured
- [ ] CPU usage profiled
- [ ] Cache efficiency verified
- [ ] Lock contention analyzed
- [ ] Benchmarks passing
## 5. RISK MITIGATION
### 5.1 Potential Blockers
**Risk 1: TrinityCore API Changes**
- **Probability**: Medium
- **Impact**: High
- **Mitigation**: Version lock to specific commit, abstraction layer
- **Rollback**: Previous API wrapper version
**Risk 2: Lock-Free Algorithm Bugs**
- **Probability**: Medium
- **Impact**: Critical
- **Mitigation**: Extensive testing, formal verification tools
- **Rollback**: Mutex-based fallback implementation
**Risk 3: Memory Overhead Exceeds Target**
- **Probability**: Low
- **Impact**: High
- **Mitigation**: Early profiling, object pooling
- **Rollback**: Reduce history buffer, compress state
### 5.2 Validation Checkpoints
**Checkpoint 1 (After Task 1.3)**:
- Basic state machine functional
- Memory usage within bounds
- Thread safety verified
**Checkpoint 2 (After Task 1.7)**:
- All interfaces defined
- API stability confirmed
- Integration points identified
**Checkpoint 3 (After Task 1.11)**:
- All tests passing
- Performance targets met
- No memory leaks
**Checkpoint 4 (After Task 1.13)**:
- Code review complete
- Documentation approved
- Ready for Phase 2
### 5.3 Rollback Points
1. **Before Task 1.4**: Can revert to simpler state machine
2. **Before Task 1.8**: Can adjust architecture
3. **After Task 1.11**: Can optimize before Phase 2
## 6. CODE EXAMPLES
### 6.1 Complete BotStateMachine Usage
```cpp
// Example: Bot combat initialization
void BotCombatManager::EnterCombat(Player* bot, Unit* target) {
// Get bot's state machine
auto& fsm = GetStateMachine(bot->GetGUID());
// Validate transition
if (!fsm.CanTransitionTo(BotState::COMBAT)) {
LOG_WARN("Cannot enter combat from state: {}",
fsm.GetCurrentState());
return;
}
// Set combat flags
fsm.SetFlag(StateFlags::IN_COMBAT);
fsm.SetFlag(StateFlags::HAS_TARGET);
// Transition with high priority
bool success = fsm.TransitionTo(
BotState::COMBAT,
EventType::COMBAT_START,
PRIORITY_HIGH
);
if (success) {
// Post target acquisition event
CombatData data{target->GetGUID(), bot->GetDistance(target)};
fsm.PostEvent(EventType::TARGET_CHANGED, &data, PRIORITY_HIGH);
// Process immediate events
fsm.ProcessEvents(5);
}
}
```
### 6.2 SafeReference Pattern
```cpp
// Safe bot access pattern
class BotGroupManager {
public:
void UpdateGroupPosition(ObjectGuid leaderGuid) {
// Safe reference with automatic validation
SafeRef<Player> leader(leaderGuid);
if (!leader) {
LOG_DEBUG("Leader {} not found", leaderGuid.ToString());
return;
}
// Access is validated on each dereference
Position leaderPos = leader->GetPosition();
float orientation = leader->GetOrientation();
// Iterate group members safely
for (auto& botGuid : m_groupBots) {
SafeRef<Player> bot(botGuid);
if (bot && bot->IsAlive()) {
// Calculate formation position
Position formationPos = CalculateFormation(
leaderPos, orientation, bot->GetFormationIndex()
);
// Move bot (reference validated automatically)
bot->GetMotionMaster()->MovePoint(
POINT_FORMATION, formationPos
);
}
}
} // References cleaned up automatically
};
```
### 6.3 Event Subscription Pattern
```cpp
// Event-driven behavior
class BotThreatManager : public EventSubscriber {
public:
BotThreatManager(EventDispatcher& dispatcher)
: m_dispatcher(dispatcher) {
// Subscribe to combat events
m_subs.push_back(
dispatcher.Subscribe(EventType::THREAT_GAINED,
[this](const void* data) { OnThreatGained(data); })
);
m_subs.push_back(
dispatcher.Subscribe(EventType::COMBAT_START,
[this](const void* data) { OnCombatStart(data); })
);
}
private:
void OnThreatGained(const void* data) {
auto* threatData = static_cast<const ThreatData*>(data);
SafeRef<Player> bot(threatData->botGuid);
if (bot && bot->IsAlive()) {
// Update threat table
UpdateThreat(bot.get(), threatData->sourceGuid,
threatData->amount);
// Post state change if needed
if (GetTotalThreat(bot.get()) > FLEE_THRESHOLD) {
m_dispatcher.Post(EventType::MOVEMENT_START,
nullptr, PRIORITY_HIGH);
}
}
}
};
```
## 7. DELIVERY ARTIFACTS
### Phase 1 Completion Criteria
1. **Source Files** (14 files, ~2,100 lines)
- All state machine components
- Safe reference system
- Event framework
- Full documentation
2. **Test Files** (15 files, ~3,000 lines)
- Unit tests with 100% coverage
- Integration tests passing
- Performance benchmarks met
- Memory leak free
3. **Documentation** (2 files, ~900 lines)
- Architecture overview
- API reference
- Usage examples
- Migration guide
4. **Metrics Dashboard**
- Memory usage: <1KB/bot ✓
- CPU usage: <0.05%/bot ✓
- State transition: <500ns ✓
- Event dispatch: <1μs ✓
- Thread safety: TSan clean ✓
## 8. PHASE 2 PREPARATION
### Handoff Requirements
1. **Stable APIs** - No breaking changes after Phase 1
2. **Test Coverage** - Minimum 95% for all components
3. **Performance Baseline** - All benchmarks documented
4. **Known Issues** - Complete list with workarounds
5. **Integration Points** - Documented for Phase 2
### Dependencies for Phase 2
Phase 2 teams can begin work when:
- State machine API stable (Task 1.3 complete)
- Behavior interfaces defined (Task 1.7 complete)
- Event system functional (Task 1.6 complete)
## EXECUTION COMMAND
To begin Phase 1 implementation:
```bash
# Create branch
git checkout -b phase1-foundation
# Create directory structure
mkdir -p src/modules/Playerbot/Core/StateMachine
mkdir -p src/modules/Playerbot/Core/Memory
mkdir -p src/modules/Playerbot/Core/Events
mkdir -p src/modules/Playerbot/Core/Behavior
mkdir -p src/modules/Playerbot/Tests/StateMachine
mkdir -p src/modules/Playerbot/Tests/Memory
mkdir -p src/modules/Playerbot/Tests/Events
mkdir -p src/modules/Playerbot/Tests/Integration
mkdir -p src/modules/Playerbot/Tests/Performance
mkdir -p src/modules/Playerbot/Docs/API
# Begin with Task 1.1
# Agent: cpp-architecture-optimizer
# File: src/modules/Playerbot/Core/StateMachine/BotStateTypes.h
```
## APPROVAL GATE
This plan requires explicit approval before implementation begins.
**Approval Checklist**:
- [ ] Architecture approved
- [ ] Resource allocation confirmed
- [ ] Agent availability verified
- [ ] TrinityCore APIs validated
- [ ] Performance targets agreed
---
**END OF PHASE 1 FOUNDATION SUBPLAN**
*Total: 85 hours, 14 implementation files, 15 test files, 2 documentation files*
*Delivers: Complete foundation for Phases 2-6 with zero technical debt*