Files
ThordekkCore/PHASE_1_FOUNDATION_SUBPLAN.md
T
2026-01-20 21:33:16 -03:00

32 KiB

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:

// 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:

// 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:

// 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:

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:

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:

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:

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

// 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

// 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

// 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:

# 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