PlayerbotV2 — TrinityCore Bot Module
PlayerbotV2 is a TrinityCore module providing autonomous AI-driven player bots. It operates in two tiers: Fleet (world-population bots managed by a shaper) and Altbots (player-bound companions that follow, assist, and share quests).
Architecture
PlayerbotV2/
├── Altbot/ # Play-bound companion registry (added 2026-08)
├── Bot/ # AI state machine, snapshots, states, rules, dungeons, BGs
├── Combat/ # APL spec rotations (39 class/spec combos)
├── Diagnostics/ # Perf counters, wedge watchdog, inspector, smoketest
├── Fleet/ # Population manager, account pool, factory, guilds, economy
├── Group/ # Group/raid snapshot builder
├── Persistence/ # DB migration manager
├── Quest/ # Class-equivalent quest resolver (added 2026-08)
├── Session/ # Bot session lifecycle, addon control
├── Threading/ # AI worker pool, snapshot publisher, scheduler
├── Travel/ # Quest hubs, portals, taxi graph, repair vendors
├── Util/ # Config reader
├── World/ # World metadata (roads, capitals, danger zones)
├── sql/world/ # Schema migrations
├── PlayerbotV2.cpp # Module entry — hooks, companion maintenance, quest sync
├── PlayerbotV2.h # Module declaration
├── Services.h/cpp # Service locator
└── CMakeLists.txt # 13 sub-library build
Sub-libraries
| Library | Purpose |
|---|---|
playerbot-v2-altbot |
Altbot registry — player-bound companion ownership |
playerbot-v2-bot |
AI core: state machine, snapshots, rules, dungeon scripts |
playerbot-v2-combat |
APL rotation logic for 39 (class, spec) combinations |
playerbot-v2-fleet |
Population shaper, account pool, factories, guild/craft economy |
playerbot-v2-group |
Group/raid snapshot + builder |
playerbot-v2-session |
Headless bot session lifecycle |
playerbot-v2-threading |
AI worker pool, snapshot publisher, tick scheduler |
playerbot-v2-travel |
Quest hub database, portal index, unified travel graph |
playerbot-v2-persistence |
DB migration manager |
playerbot-v2-diagnostics |
Perf counters, wedge watchdog, bot inspector |
playerbot-v2-util |
Config reader |
playerbot-v2-world |
World metadata (roads, capitals, vendors) |
playerbot-v2-core |
Module entry point + service aggregator |
Bot Roles
| Role | Description |
|---|---|
Fleet (BotRole::Fleet) |
Autonomous world bots — population shaper, questing, dungeon/BG filler |
Altbot (BotRole::Altbot) |
Player-bound companion — follow, assist, quest-sync only. No fleet AI |
Altbots are stored in a dedicated table playerbot_v2_altbot and skip all fleet
population logic (spawn/despawn/overflow). Their AI (TickAltbot) handles only
combat and death — follow/formation is managed by the companion maintenance loop
on the world thread.
Commands
Altbot Management
| Command | Description |
|---|---|
.playerbot alt create [class] [race] |
Create a new altbot bound to the player |
.playerbot alt add <name> |
Login an existing altbot |
.playerbot alt remove <name>|* |
Logout one or all altbots |
.playerbot alt list |
List all altbots for the account |
.playerbot alt reload |
Reload altbot registry from DB (GM) |
Companion (Legacy)
| Command | Description |
|---|---|
.playerbot companion [count] [class] |
Create companion bots at player's faction/level |
.playerbot summon <name> |
Summon an existing character as a bot |
Quest Sync System
Class-Equivalent Quest Resolution
Quests often have class-specific variants (e.g. "Lions for Lambs" is quest 28759
for Hunters but 28769 for Mages). The Quest/BotQuestResolve module resolves the
bot's class-equivalent quest ID via these matching criteria:
- ExclusiveGroup — shared by class variants of the same quest
- QuestPackageID — distinguishes steps within a chain (e.g. "Beating Them Back!" step 1 vs step 2)
- LogTitle — fallback when PackageID is 0
When no class variants exist (equivalents.size() == 1), the owner's quest ID
is returned directly — the quest is shared across all classes.
Quest Lifecycle
Owner accepts quest
→ OnAcceptQuest hook
→ ResolveBotQuestId(bot, ownerQuestId)
→ Returns bot's class-equivalent (or owner's if shared)
→ Bot gets quest via AddQuestAndCheckCompletion / SetQuestStatus
Owner completes objectives
→ Kill credit, NPC interaction, loot items propagate to grouped bots
→ QuestSyncScript fires on owner's quest status change
→ bot->SetQuestStatus(botQ, QUEST_STATUS_COMPLETE)
Owner turns in quest
→ OnRewardQuest hook
→ Resolves bot's equivalent quest
→ Force-completes if still incomplete (objectives not synced locally)
→ Marks REWARDED, grants reward item, sets XP from owner's quest template
Owner abandons quest
→ OnAbandonQuest hook
→ FindActiveEquivalentOnBot → abandons bot's class-variant
Kill Credit
OnKillCredit propagates KilledMonsterCredit to all altbots, except when
the owner is actively in combat and the bot is in the owner's party — TC's
party system handles those naturally.
NPC Interaction
OnTalkToCreature propagates TalkedToCreature credit. For NPC interactions
that trigger KilledMonsterCredit (e.g. reviving injured soldiers),
propagation depends on the owner being out of combat (party guard bypass).
Quest Item Propagation
When the owner loots a quest item, OnLootUnit scans the corpse's loot
window and calls GiveQuestItem per slot. Items are given via AddItem
(which correctly handles quest-bound item objectives). Each bot receives
up to need - have items to fill their quest requirement.
Homebind Sync
When the owner sets their hearthstone at an innkeeper:
Player::SetHomebindfires →OnPlayerSetHomebindhookModule::OnSetHomebindcallsbot->SetHomebind(loc, areaId)for every altbot- All altbots now hearth to the same inn
Use /w <bot> hearth_all to mass-hearth the party.
Hooks (Core Integration)
All hooks live in src/server/game/Playerbot/PlayerbotHooks.h/.cpp and
dispatch to Playerbot::V2::Module::instance(). Core touch points:
| Hook | Core Location | Purpose |
|---|---|---|
OnPlayerLogin/Logout |
Player.cpp | Register/unregister bot AI |
OnAcceptQuest |
QuestHandler.cpp | Push class-equivalent quest to bots |
OnRewardQuest |
Player.cpp (RewardQuest) | Mark bot's quest rewarded |
OnAbandonQuest |
- | Abandon bot's equivalent quest |
OnKillCredit |
Player.cpp | Propagate kills/NPC interactions |
OnTalkToCreature |
Player.cpp | Propagate NPC talk credit |
OnLootUnit |
LootHandler.cpp | Scan corpse for quest items |
OnPlayerSetHomebind |
Player.cpp (SetHomebind) | Sync homebind to altbots |
OnPlayerAttack |
Unit.cpp | Combat assist propagation |
Building
Requires TRINITY_PLAYERBOT_V2=1 (set automatically by CMake).
cmake -S . -B build
cmake --build build --target worldserver
Database Migrations
sql/world/0007_playerbot_v2_altbot.sql— Altbot table + migration- Other SQL under
sql/shared/andsql/world/for dungeon routes, BG fixes, etc.
The playerbot_v2_altbot table is auto-created on first BindAlt() call via
CREATE TABLE IF NOT EXISTS. No manual migration required for new deployments.
Configuration
Configuration lives in playerbot.conf (same directory as worldserver.conf).
Key settings:
PlayerbotsV2.FleetBots— ambient-fleet master switch (default 0 = alt-bot-only mode; only the alt creation path runs)Playerbot.V2.Population.TotalTarget— fleet bot population targetPlayerbot.V2.Population.Shape— distribution shape (Pyramid, Bell, Flat, MaxHeavy)Playerbot.V2.MaxAltsAsBots— per-account altbot capPlayerbot.V2.AutoResumeOnBoot— auto-login marked bots on startup- See
conf/playerbot.conf.distfor all options