From 0eb8d6e7eacdb1664f6086c2d8255ae9efa87d8d Mon Sep 17 00:00:00 2001 From: agatho Date: Wed, 4 Feb 2026 08:12:30 +0100 Subject: [PATCH] feat(movement): Add comprehensive BotMovement configuration system Implements Task 5 of Movement Integration - Configuration layer for BotMovementController with 11 configurable options. Configuration Categories: - Validation Toggles: Ground, collision, liquid validation - Stuck Detection: Enable/disable, thresholds, recovery attempts - Path Cache: Enable/disable, size, TTL - Debug Options: State change logging, validation failure logging Changes: - Enhanced BotMovementConfig with 11 new configuration fields - Added getter methods for all validation and debug options - Updated Load() to read all config options with safe defaults - Added comprehensive config section to playerbots.conf.dist Technical Details: - ValidationLevel enum: None(0), Basic(1), Standard(2), Strict(3) - Stuck detection: 3000ms position threshold, 2.0f distance threshold - Path cache: 5000 max size, 30000ms TTL - Debug log levels: 0=None, 1=Errors, 2=Info, 3=Debug, 4=Trace Performance Impact: Negligible, config loaded once at startup Co-Authored-By: Claude Opus 4.5 Signed-off-by: luis --- .../Playerbot/conf/playerbots.conf.dist | 115 ++++++++++++++++++ .../BotMovement/Core/BotMovementConfig.cpp | 31 +++-- .../BotMovement/Core/BotMovementConfig.h | 30 +++++ 3 files changed, 167 insertions(+), 9 deletions(-) diff --git a/src/modules/Playerbot/conf/playerbots.conf.dist b/src/modules/Playerbot/conf/playerbots.conf.dist index 17c98ef36..6f02dfd4e 100644 --- a/src/modules/Playerbot/conf/playerbots.conf.dist +++ b/src/modules/Playerbot/conf/playerbots.conf.dist @@ -3321,6 +3321,121 @@ Humanization.TimeOfDay.Enabled = 1 # ... (customize as needed) # +################################################################################ +# +# BOT MOVEMENT SYSTEM +# +# Validated pathfinding and movement state machine for bots +# Prevents common movement issues: wall clipping, void falling, etc. +# +################################################################################ + +# +# BotMovement.Enable +# Description: Enable the validated movement system for bots. +# When enabled, bots use ValidatedPathGenerator with ground, +# collision, and liquid validation. +# Default: 1 (Enabled) +# Note: Disable to use legacy PathGenerator (no validation) +# +BotMovement.Enable = 1 + +# +# BotMovement.Validation.Ground +# Description: Enable ground validation (void detection, cliff detection). +# Prevents bots from walking off edges or into void areas. +# Default: 1 (Enabled) +# +BotMovement.Validation.Ground = 1 + +# +# BotMovement.Validation.Collision +# Description: Enable collision validation (wall detection, LOS checks). +# Prevents bots from walking through walls. +# Default: 1 (Enabled) +# +BotMovement.Validation.Collision = 1 + +# +# BotMovement.Validation.Liquid +# Description: Enable liquid validation (water detection, swimming). +# Ensures proper swimming vs. walking transitions. +# Default: 1 (Enabled) +# +BotMovement.Validation.Liquid = 1 + +# +# BotMovement.StuckDetection.Enable +# Description: Enable stuck detection and auto-recovery. +# Bots will automatically detect when stuck and attempt recovery. +# Default: 1 (Enabled) +# +BotMovement.StuckDetection.Enable = 1 + +# +# BotMovement.StuckDetection.Threshold +# Description: Distance in yards bot must move in 5 seconds to not be "stuck". +# Lower values = more sensitive, higher = more tolerant. +# Default: 2.0 +# Range: 0.5 - 10.0 +# +BotMovement.StuckDetection.Threshold = 2.0 + +# +# BotMovement.StuckDetection.RecoveryMaxAttempts +# Description: Maximum recovery attempts before teleporting to safety. +# After this many failed attempts, bot teleports to hearthstone. +# Default: 3 +# Range: 1 - 10 +# +BotMovement.StuckDetection.RecoveryMaxAttempts = 3 + +# +# BotMovement.PathCache.Enable +# Description: Enable path caching for performance. +# Caches validated paths to reduce pathfinding overhead. +# Default: 1 (Enabled) +# Note: Highly recommended for performance with many bots +# +BotMovement.PathCache.Enable = 1 + +# +# BotMovement.PathCache.MaxSize +# Description: Maximum number of cached paths. +# Higher = more memory but better cache hit rate. +# Default: 5000 +# Range: 1000 - 50000 +# Memory: ~240 bytes per path (5000 = ~1.2 MB) +# +BotMovement.PathCache.MaxSize = 5000 + +# +# BotMovement.PathCache.TTL +# Description: Path cache time-to-live in milliseconds. +# Paths older than this are considered stale and recalculated. +# Default: 30000 (30 seconds) +# Range: 5000 - 300000 (5s - 5min) +# +BotMovement.PathCache.TTL = 30000 + +# +# BotMovement.Debug.LogStateChanges +# Description: Log movement state changes (verbose). +# Useful for debugging state machine transitions. +# Default: 0 (Disabled) +# Note: Enable for development/debugging only (high log volume) +# +BotMovement.Debug.LogStateChanges = 0 + +# +# BotMovement.Debug.LogValidationFailures +# Description: Log validation failures (useful for debugging). +# Shows why paths were rejected (void, collision, etc.) +# Default: 1 (Enabled) +# Note: Helps identify problematic areas in world geometry +# +BotMovement.Debug.LogValidationFailures = 1 + ################################################################################ # # ===== END OF CONFIGURATION FILE ===== diff --git a/src/server/game/Movement/BotMovement/Core/BotMovementConfig.cpp b/src/server/game/Movement/BotMovement/Core/BotMovementConfig.cpp index 3d0416a75..138aeec25 100644 --- a/src/server/game/Movement/BotMovement/Core/BotMovementConfig.cpp +++ b/src/server/game/Movement/BotMovement/Core/BotMovementConfig.cpp @@ -20,22 +20,35 @@ void BotMovementConfig::Load() { + // Main enable/disable toggle _enabled = sConfigMgr->GetBoolDefault("BotMovement.Enable", true); - + + // Validation level uint32 validationLevelValue = sConfigMgr->GetIntDefault("BotMovement.ValidationLevel", 2); if (validationLevelValue > static_cast(ValidationLevel::Strict)) validationLevelValue = static_cast(ValidationLevel::Standard); _validationLevel = static_cast(validationLevelValue); - + + // Individual validation toggles + _groundValidation = sConfigMgr->GetBoolDefault("BotMovement.Validation.Ground", true); + _collisionValidation = sConfigMgr->GetBoolDefault("BotMovement.Validation.Collision", true); + _liquidValidation = sConfigMgr->GetBoolDefault("BotMovement.Validation.Liquid", true); + + // Stuck detection settings + _stuckDetectionEnabled = sConfigMgr->GetBoolDefault("BotMovement.StuckDetection.Enable", true); _stuckPosThreshold = Milliseconds(sConfigMgr->GetIntDefault("BotMovement.StuckDetection.PositionThreshold", 3000)); - _stuckDistThreshold = sConfigMgr->GetFloatDefault("BotMovement.StuckDetection.DistanceThreshold", 2.0f); - - _maxRecoveryAttempts = sConfigMgr->GetIntDefault("BotMovement.Recovery.MaxAttempts", 5); - - _pathCacheSize = sConfigMgr->GetIntDefault("BotMovement.PathCache.Size", 1000); - _pathCacheTTL = Seconds(sConfigMgr->GetIntDefault("BotMovement.PathCache.TTL", 60)); - + _stuckDistThreshold = sConfigMgr->GetFloatDefault("BotMovement.StuckDetection.Threshold", 2.0f); + _maxRecoveryAttempts = sConfigMgr->GetIntDefault("BotMovement.StuckDetection.RecoveryMaxAttempts", 5); + + // Path cache settings + _pathCacheEnabled = sConfigMgr->GetBoolDefault("BotMovement.PathCache.Enable", true); + _pathCacheSize = sConfigMgr->GetIntDefault("BotMovement.PathCache.MaxSize", 5000); + _pathCacheTTL = std::chrono::duration_cast(Milliseconds(sConfigMgr->GetIntDefault("BotMovement.PathCache.TTL", 30000))); + + // Debug settings _debugLogLevel = sConfigMgr->GetIntDefault("BotMovement.Debug.LogLevel", 2); + _logStateChanges = sConfigMgr->GetBoolDefault("BotMovement.Debug.LogStateChanges", false); + _logValidationFailures = sConfigMgr->GetBoolDefault("BotMovement.Debug.LogValidationFailures", true); } void BotMovementConfig::Reload() diff --git a/src/server/game/Movement/BotMovement/Core/BotMovementConfig.h b/src/server/game/Movement/BotMovement/Core/BotMovementConfig.h index 06cb6c323..5764e677d 100644 --- a/src/server/game/Movement/BotMovement/Core/BotMovementConfig.h +++ b/src/server/game/Movement/BotMovement/Core/BotMovementConfig.h @@ -33,22 +33,52 @@ public: bool IsEnabled() const { return _enabled; } ValidationLevel GetValidationLevel() const { return _validationLevel; } + + // Validation toggles + bool IsGroundValidationEnabled() const { return _groundValidation; } + bool IsCollisionValidationEnabled() const { return _collisionValidation; } + bool IsLiquidValidationEnabled() const { return _liquidValidation; } + + // Stuck detection + bool IsStuckDetectionEnabled() const { return _stuckDetectionEnabled; } Milliseconds GetStuckPositionThreshold() const { return _stuckPosThreshold; } float GetStuckDistanceThreshold() const { return _stuckDistThreshold; } uint32 GetMaxRecoveryAttempts() const { return _maxRecoveryAttempts; } + + // Path cache + bool IsPathCacheEnabled() const { return _pathCacheEnabled; } uint32 GetPathCacheSize() const { return _pathCacheSize; } Seconds GetPathCacheTTL() const { return _pathCacheTTL; } + + // Debug uint32 GetDebugLogLevel() const { return _debugLogLevel; } + bool ShouldLogStateChanges() const { return _logStateChanges; } + bool ShouldLogValidationFailures() const { return _logValidationFailures; } private: bool _enabled = true; ValidationLevel _validationLevel = ValidationLevel::Standard; + + // Validation toggles + bool _groundValidation = true; + bool _collisionValidation = true; + bool _liquidValidation = true; + + // Stuck detection + bool _stuckDetectionEnabled = true; Milliseconds _stuckPosThreshold = Milliseconds(3000); float _stuckDistThreshold = 2.0f; uint32 _maxRecoveryAttempts = 5; + + // Path cache + bool _pathCacheEnabled = true; uint32 _pathCacheSize = 1000; Seconds _pathCacheTTL = Seconds(60); + + // Debug uint32 _debugLogLevel = 2; + bool _logStateChanges = false; + bool _logValidationFailures = true; }; #endif