Files
ThordekkCore/INTEGRATION_EXAMPLES.md
T

10 KiB

Playerbot Movement Integration Examples

Quick Start Integration

1. Add to BotAI Class

In BotAI.h:

// Add these includes near the top
#include "Movement/MovementIntegration.h"
#include "Humanization/Core/AdvancedPersonalityProfile.h"

// Add to BotAI class declaration
class BotAI
{
private:
    std::unique_ptr<MovementIntegration> _movementIntegration;
    std::unique_ptr<AdvancedPersonalityProfile> _advancedPersonality;
    
public:
    // Movement interface methods
    bool MoveTo(Position const& destination, uint32 priority = 0);
    bool Follow(Unit* target, float distance, uint32 priority = 0);
    bool Wander(Position const& center, float radius, Milliseconds duration);
    void StopMovement();
    
    // Access to subsystems
    MovementIntegration* GetMovementIntegration() const { return _movementIntegration.get(); }
    AdvancedPersonalityProfile* GetAdvancedPersonality() const { return _advancedPersonality.get(); }
};

In BotAI.cpp:

// In constructor:
BotAI::BotAI(Player* bot) 
    : _bot(bot)
{
    // Initialize movement integration
    _movementIntegration = std::make_unique<MovementIntegration>(_bot);
    
    // Initialize advanced personality
    _advancedPersonality = std::make_unique<AdvancedPersonalityProfile>(
        AdvancedPersonalityType::CASUAL_EXPLORER);
    
    // Configure movement systems
    MovementSystemConfig config;
    config.enableHumanizedMovement = true;
    config.enableAdvancedDeduplication = true;
    config.humanizationStrength = 0.8f;
    config.deduplicationStrength = 0.8f;
    _movementIntegration->SetConfig(config);
    
    // Initialize systems
    _movementIntegration->Initialize();
}

// In UpdateAI:
void BotAI::UpdateAI(uint32 diff)
{
    // Update movement integration
    if (_movementIntegration)
        _movementIntegration->Update(diff);
    
    // Rest of your existing UpdateAI logic...
}

// Movement interface implementations:
bool BotAI::MoveTo(Position const& destination, uint32 priority)
{
    if (_movementIntegration)
        return _movementIntegration->MoveTo(destination, priority, "BotAI");
    return false;
}

bool BotAI::Follow(Unit* target, float distance, uint32 priority)
{
    if (_movementIntegration)
        return _movementIntegration->Follow(target, distance, priority);
    return false;
}

bool BotAI::Wander(Position const& center, float radius, Milliseconds duration)
{
    if (_movementIntegration)
        return _movementIntegration->Wander(center, radius, duration);
    return false;
}

void BotAI::StopMovement()
{
    if (_movementIntegration)
        _movementIntegration->StopMovement();
}

2. Replace Existing Movement Calls

Find and replace patterns:

Old code:

BotMovementUtil::MoveToPosition(bot, destination);
bot->GetMotionMaster()->MovePoint(0, destX, destY, destZ);
bot->GetMotionMaster()->MoveChase(target, distance);

New code:

// Replace with:
if (botAI->GetMovementIntegration()) {
    botAI->GetMovementIntegration()->MoveTo(destination, priority, "SpecificSystem");
} else {
    // Fallback to original
    BotMovementUtil::MoveToPosition(bot, destination);
}

3. Update Strategy Classes

Example in a movement strategy:

class MoveToTargetStrategy : public Strategy
{
public:
    ActionResult Execute(BotAI* ai, ActionContext const& context) override
    {
        Unit* target = context.GetValue<Unit*>("target");
        if (!target)
            return ActionResult::FAILED;

        // Use enhanced movement
        if (ai->GetMovementIntegration())
        {
            Position targetPos = target->GetPosition();
            bool result = ai->GetMovementIntegration()->MoveTo(targetPos, 5, "MoveToTargetStrategy");
            return result ? ActionResult::SUCCESS : ActionResult::FAILED;
        }

        // Fallback
        return ai->DoAction("move to target", context);
    }
};

4. Personality-Driven Behavior

Example of using advanced personality:

class SocialBehaviorStrategy : public Strategy
{
public:
    ActionResult Execute(BotAI* ai, ActionContext const& context) override
    {
        auto* personality = ai->GetAdvancedPersonality();
        if (!personality)
            return ActionResult::FAILED;

        // Check if bot should socialize based on personality
        float socialTendency = personality->GetTraits().extraversion;
        if (urand(0, 100) < socialTendency * 100)
        {
            // Find nearby players to greet
            Player* nearbyPlayer = FindNearbyPlayer(ai->GetBot(), 15.0f);
            if (nearbyPlayer)
            {
                // Calculate greeting likelihood based on personality
                float greetChance = personality->CalculateSocialLikelihood("greeting");
                if (urand(0, 100) < greetChance * 100)
                {
                    ai->GetBot()->Say("Hello there!", LANG_UNIVERSAL);
                    return ActionResult::SUCCESS;
                }
            }
        }

        return ActionResult::FAILED;
    }
};

5. Configuration Integration

Add to your config system:

// In your config loading code:
void LoadMovementConfig()
{
    MovementSystemConfig config;
    
    config.enableHumanizedMovement = sConfigMgr->GetBoolDefault("Playerbot.HumanizedMovement.Enabled", true);
    config.enableAdvancedDeduplication = sConfigMgr->GetBoolDefault("Playerbot.Deduplication.Enabled", true);
    config.humanizationStrength = sConfigMgr->GetFloatDefault("Playerbot.Humanization.Strength", 0.8f);
    config.deduplicationStrength = sConfigMgr->GetFloatDefault("Playerbot.Deduplication.Strength", 0.8f);
    config.cacheSize = sConfigMgr->GetIntDefault("Playerbot.Deduplication.CacheSize", 1000);
    config.cacheAgeMs = sConfigMgr->GetIntDefault("Playerbot.Deduplication.CacheAge", 300000);
    
    // Apply to all bots
    for (auto& botAI : allBotAIs)
    {
        if (botAI->GetMovementIntegration())
            botAI->GetMovementIntegration()->SetConfig(config);
    }
}

6. CMakeLists.txt Updates

Add to your CMakeLists.txt:

# Add new movement files
set(PLAYERBOT_MOVEMENT_SOURCES
    ${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Movement/HumanizedMovement.cpp
    ${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Movement/EnhancedMovementDeduplication.cpp
    ${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Movement/MovementIntegration.cpp
    # ... existing movement sources
)

# Add new humanization files
set(PLAYERBOT_HUMANIZATION_SOURCES
    ${CMAKE_SOURCE_DIR}/src/modules/Playerbot/Humanization/Core/AdvancedPersonalityProfile.cpp
    # ... existing humanization sources
)

Testing Your Integration

1. Basic Movement Test

// Test command to verify movement works
bool TestMovement(BotAI* ai)
{
    Position testPos = ai->GetBot()->GetPosition();
    testPos.Relocate(testPos.GetPositionX() + 10.0f, 
                    testPos.GetPositionY() + 10.0f, 
                    testPos.GetPositionZ());
    
    return ai->MoveTo(testPos, 1, "TestMovement");
}

2. Personality Test

// Test different personalities
void TestPersonalities(BotAI* ai)
{
    auto* personality = ai->GetAdvancedPersonality();
    if (!personality)
        return;
        
    TC_LOG_INFO("test", "Personality type: {}", personality->GetTypeName());
    TC_LOG_INFO("test", "Extraversion: {:.2f}", personality->GetTraits().extraversion);
    TC_LOG_INFO("test", "Risk taking: {:.2f}", personality->GetTraits().behavior.riskTaking);
}

3. Performance Test

// Monitor movement performance
void MonitorMovementPerformance(BotAI* ai)
{
    auto* integration = ai->GetMovementIntegration();
    if (!integration)
        return;
        
    auto stats = integration->GetStatistics();
    TC_LOG_INFO("performance", "Total movements: {}", stats.totalMovements);
    TC_LOG_INFO("performance", "Humanized: {} ({:.1f}%)", 
                 stats.humanizedMovements, 
                 stats.humanizationScore * 100.0f);
    TC_LOG_INFO("performance", "Deduplicated: {} ({:.1f}%)", 
                 stats.deduplicatedMovements,
                 stats.averageReduction * 100.0f);
}

Troubleshooting Integration Issues

Common Problems and Solutions

1. Compilation Errors:

// Missing includes - add these:
#include "Movement/MovementIntegration.h"
#include "Humanization/Core/AdvancedPersonalityProfile.h"
#include "Player.h"
#include "Position.h"

2. Linker Errors:

# Make sure new files are included in CMakeLists.txt
# Check that namespaces are correct
using namespace Playerbot;
using namespace Playerbot::Humanization;

3. Runtime Crashes:

// Always check for null pointers:
if (!ai->GetMovementIntegration()) {
    TC_LOG_WARN("playerbot", "Movement integration not initialized");
    return false;
}

// Check bot is in world:
if (!_bot->IsInWorld()) {
    return false;
}

4. Movement Not Working:

// Verify configuration:
MovementSystemConfig config = movementIntegration->GetConfig();
TC_LOG_INFO("debug", "Humanized enabled: {}", config.enableHumanizedMovement);
TC_LOG_INFO("debug", "Deduplication enabled: {}", config.enableAdvancedDeduplication);

// Check initialization:
if (!movementIntegration->IsInitialized()) {
    movementIntegration->Initialize();
}

Migration Checklist

  • Add new files to CMakeLists.txt
  • Update BotAI class with movement integration
  • Replace existing movement calls with new interface
  • Add configuration options
  • Test basic movement functionality
  • Test personality-driven behavior
  • Verify performance improvements
  • Update documentation
  • Train staff on new systems

Performance Monitoring

After integration, monitor these metrics:

Movement Efficiency:

  • Movement calls per second (should decrease by 60-80%)
  • CPU usage for movement calculations
  • Pathfinding cache hit rates

Behavior Quality:

  • Player feedback on bot naturalness
  • Personality diversity in behavior
  • Social interaction frequency

System Stability:

  • Crash rates
  • Memory usage
  • Response times

This integration provides a solid foundation for more natural, efficient playerbot movement while maintaining compatibility with your existing systems.