Add in-game commands to toggle and manage bot cheats via BotCheatMask:
- .bot cheat <name> — toggle a cheat on selected/group bots
- .bot cheat list — show available cheats and active cheats
- .bot cheat off — clear all cheats on selected/group bots
- .bot cheat mult <type> <value> — set speed/damage/XP multipliers
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Gate AI subsystems by RPG state to skip unnecessary work in passive states,
reducing CPU per-bot by 30-60% for bots in low-activity states. Three tiers:
FULL (combat/quest/dungeon), REDUCED (travel/city - movement+safety only),
MINIMAL (idle/resting - safety-critical only). Complements existing ST-1
frequency throttling with scope-per-update reduction. Instant combat
escalation ensures bots under attack switch to FULL within one server tick.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
EnchantGemDatabase now loads entirely from DB2 stores (SpellItemEnchantment,
GemProperties, ChrSpecialization) at startup, scoring each enchant/gem against
spec role and primary stat priorities. Removes all hardcoded SQL data and drops
the now-unnecessary playerbot_enchant_recommendations and
playerbot_gem_recommendations tables. Also replaces hardcoded skill IDs in
GuildTaskManager with SharedDefines enums.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
GuildTaskManager, AccountLinkingManager, ChatTemplateManager, and
EnchantGemDatabase were incorrectly using CharacterDatabase for their
queries. All playerbot tables live in the dedicated playerbot database
accessed via sPlayerbotDatabase.
Changes per file:
- Replace #include "DatabaseEnv.h" with "Database/PlayerbotDatabase.h"
- Replace CharacterDatabase.Query() with sPlayerbotDatabase->Query()
- Replace CharacterDatabase.DirectExecute() with sPlayerbotDatabase->Execute()
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Five behavioral gaps fixed in Temple of Kotmogu bot AI:
1. Carrier fights while traveling to center: Carriers now engage enemies
within 15yd en route instead of being passive targets. Chase within
10yd, attack-and-continue for 10-15yd enemies.
2. Proactive escort combat: Escorts now engage the closest enemy within
20yd of the carrier regardless of carrier combat state, instead of
waiting until the carrier is already being attacked.
3. Dropped orb rush: Any bot within 40yd of a free orb rushes to pick
it up, overriding assigned role. Prevents orbs sitting on ground
while bots escort/hunt/defend elsewhere.
4. Contested orb fighting: When PickupOrb finds no GO (orb was taken),
bots engage nearby enemies at the location instead of standing idle.
5. Carrier kiting in center: When HP 30-60% and 2+ enemies within 10yd,
carrier moves away from enemy cluster while staying in center zone,
maintaining attack on closest enemy.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
- Add player->Attack(enemy, true) at all 15 enemy engagement points
across BattlegroundAI.cpp (7 sites) and TempleOfKotmoguScript.cpp
(8 sites). Without Attack(), bots only did SetSelection+ChaseTarget
which is movement-only — combat never started, no PvP occurred.
- Fix ToK CENTER_X/Y from (1732,1287) to (1783.5,1333.4) — the actual
geometric center of the 4 orb positions. Old coords were ~69yd off,
causing carriers to navigate to the wrong location.
- Simplify carrier movement to always push center for 3-6x scoring
bonus instead of requiring 2+ orbs and time conditions.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
- Replace phase-sensitive GetGameObjectListWithEntryInGrid with
GetGameObjectListWithOptionsInGrid (IgnorePhases=true) for ToK orb
pickup. Dynamically spawned BG orbs may not share bot PhaseShift,
causing silent filter in grid search VisitImpl().
- Add ProcessPendingPopulations() retry system in BGBotManager that
retries PopulateBattleground every 5s for up to 2 minutes after BG
start, fixing 8v5 starts caused by warm pool bots still in async login.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Add explicit BATTLEGROUND_TK and BATTLEGROUND_SM cases to GetBGTeamSize()
(return 10) and GetBGMinPlayers() (return 5). Fix QueueStatePoller DBC
fallback which incorrectly divided BattlemasterListEntry::MaxPlayers by 2
(the field is already per-team, as GetMaxPlayersPerTeam() returns it
directly). Use BGBotManager::GetBGTeamSize() as primary fallback instead
of the DBC lookup.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Replace broken event-based orb tracking (ORB_PICKED_UP never fired) with
aura-based RefreshOrbState() that scans all BG players for orb auras every
second. Add m_orbTargeters map to distribute bots 1-per-orb instead of all
targeting the same one. Clear targeting when no GO found at orb location so
bots fall through to escort/hunt instead of looping. Add EscortOrbCarrier
fallback for ORB_CARRIER role when no orbs are available.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Three fixes for BG bot lifecycle issues:
1. End BG when last human leaves: MonitorActiveBattlegrounds() now checks
for human presence in active BGs. After a 30s grace period with no
humans, the BG ends as a draw via EndBattleground(TEAM_OTHER).
2. Release and logout BG bots on BG end: OnBattlegroundEnd() now releases
pool bots via InstanceBotPool::ReleaseBot(), logs out all BG bots via
BotWorldSessionMgr::RemovePlayerBot(), and notifies the orchestrator
via OnInstanceEnded(). Previously only tracking maps were cleared.
3. Fix zone spawner over-spawning with no humans: CalculateTargetBotCount()
now uses _lastRealPlayerCount (humans only) instead of the broken
condition that always applied minimums in static mode or counted bot
sessions as active players.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Update COMPREHENSIVE_AUDIT_REPORT.md and INCOMPLETE_IMPLEMENTATIONS_REPORT.md
to document the February 2026 TODO cleanup results: 50 TODOs resolved across
29 files, 15 MIGRATION markers standardized across 6 files, zero remaining
production TODOs verified by codebase scan.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Resolve 50 TODO comments across 29 production files and standardize 15 MIGRATION
comments across 6 files, achieving zero remaining TODOs in production code.
Implementations:
- DemandCalculator: IsQuestHub() via QuestHubDatabase, GetBotCountInZone() via BotSpawner
- QuestPathfinder: Replace hardcoded RUN_SPEED with player->GetSpeed(MOVE_RUN)
- PlayerbotGroupScript: Add bot detection via PlayerBotHooks::IsPlayerBot()
Comment standardization:
- TODO stubs → DESIGN/LIMITATION/ARCHITECTURE documentation comments
- MIGRATION COMPLETE noise → descriptive architectural comments
- Empty/stale TODOs removed entirely
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Add `override` keyword to all virtual function overrides across 16 BG
script headers to catch signature mismatches at compile time.
Extract virtual calls (GetNodeCount/GetNodeData) from
DominationScriptBase::OnLoad into a new InitializeNodeTracking() method
called by derived classes after base OnLoad completes. This avoids
virtual dispatch at the fragile IBGScript/DominationScriptBase vtable
slot boundary, where MSVC RelWithDebInfo builds with stale .obj files
could route GetNodeCount (returns uint32, RCX=this) through
GetObjectivePath (returns std::vector<Position>, RCX=hidden_return,
RDX=this), causing ACCESS_VIOLATION when RDX=0.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Coordinator Initialize() accesses Battleground data (GetPlayers, GetMapId),
loads BG scripts, and runs map grid operations (FindNearestGameObject 500yd)
which are NOT thread-safe. The previous commit moved Initialize() outside
the lock but still ran it on worker threads, causing ACCESS_VIOLATION in
TempleOfKotmoguScript::OnLoad -> DominationScriptBase::OnLoad vtable crash.
Fix: Worker threads now queue creation requests via _pendingCreations map.
The main thread processes them in Update() -> ProcessPendingCreations()
where Battleground access is safe. Coordinator available within one tick.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
BattlegroundCoordinatorManager held _mutex during expensive coordinator
Initialize() (grid scans, pathfinding, script loading) and Update() calls,
blocking all worker threads from GetCoordinatorForPlayer() lookups. This
caused thread pool timeouts and bots standing idle at spawn.
Fix: copy-and-release pattern - only hold _mutex for map insert/find/erase,
never during coordinator operations. Added _creatingCoordinators guard to
prevent redundant Initialize() calls from multiple worker threads.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Two root causes for idle bots and over-population in battlegrounds:
1. BGScriptRegistry had 0 registered scripts at runtime. The
REGISTER_BG_SCRIPT macro uses static global constructors for
auto-registration, but MSVC's linker dead-strips object files from
static libraries when no external symbol references them. The previous
ForceInclude/volatile-pointer pattern did not prevent this.
Fix: Replace with explicit RegisterScript() calls in
InitializeBGScripts() for all 14 BG map IDs.
2. QueueStatePoller kept re-polling every 5-10 seconds after assigning
warm pool bots. Since bots take time to login and enter the queue
asynchronously, the poller saw "0/10 Alliance, 0/10 Horde" on each
poll and spawned another full batch (14 rounds = ~280 bots for 10v10).
Fix: Unregister the BG queue from the poller immediately after the
warm pool (or JIT) fully satisfies the demand. Also copy the active
queue set before iterating to avoid iterator invalidation.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>
Two BG fixes:
1. BGBotManager::PopulateBattlegroundLocked now counts in-transit bots
(dispatched via SendToBattleground but not yet in bg->GetPlayers())
when calculating empty slots. Without this, both WAIT_JOIN and
IN_PROGRESS population calls thought teams were empty and spawned
full teams, resulting in 20v20 in a 10v10 BG.
2. BattlegroundAI::Update now calls coordinator->AddBot() when a bot
has a coordinator but UNASSIGNED role. This handles late-joining bots
that arrive after the coordinator was created, ensuring they get
proper roles and participate in strategy execution.
Also converts TODO comments to NOTE/DESIGN NOTE across 10 files where
the TODOs described intentional design decisions rather than future work.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: luis <[email protected]>