<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.
DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.
Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.
Before submitting, make sure your changes aligns with these principles.
-->
## Pull Request Description
<!-- Describe what this change does and why it is needed -->
Hello playerbots community! I have been working diligently whilst on
vacation to help get pvp gear up and running for pvp specs. Throughout
this process, I have looked at our current autogear system, tested it
through and through, and made some changes to make gearing more
appropriate per spec. _I am going to have my description of the changes
in italics_, **and the AI description overview will be bolded.** Let's
begin!
**This PR makes some improvements to the bot autogear system across item
scoring, spec tracking(pvp specs and gear), and stat weights. Changes
are split between those that are always active and those controlled by
new config options.**
**Mandatory Changes:**
**PvP Spec Detection (IsSpecPvp)
A new method RandomPlayerbotMgr::IsSpecPvp(botGuid, cls) checks the
bot's stored specNo against the spec name string defined in config. If
the name contains "pvp", the bot is treated as a PvP spec throughout the
entire gear pipeline. This is the single source of truth used by both
InitEquipment() and ItemUsageValue. In the future this detection can be
expanded to drive bot behavior decisions — such as prioritizing dueling
players in the world, joining Wintergrasp, or preferring BG and Arena
queues over PvE content.**
_This is scalable, so if someone were to create their own pvp spec in
the config, it would still be tracked if the name contains "pvp". I like
the idea of pvp specced random bots having an identifier for pvp
events._
**PvP Weights Applied During Loot Evaluation
ItemUsageValue::QueryItemUsageForEquip() now calls IsSpecPvp() before
scoring a looted item. If the bot is on a PvP spec, it passes
SetPvpSpec(true) to the StatsWeightCalculator, ensuring looted items are
evaluated with PvP stat priorities (including resilience weighting)
rather than PvE weights. Previously, a PvP-specced bot would score loot
identically to a PvE bot.**
_So, during autogear and upgrade equips, pvp specced bots will now
heavily prioritize resilience. On the flip side, pve bots really don't
want resilience gear, so a negative weight modifier (penalty for
resilience items) has been applied to pve autogearing and upgrade
equips. This is important, because you can switch a bot from a pve spec
to a pvp spec, and it will automatically consider resilience items in
it's inventory as upgrades, and equip them. Same for when you switch a
bot from a pvp spec back to a pve spec - the resilience penalty will
encourage the bot to switch back to the best available pve gear._
**Resilience Weighting
After all per-spec weights are generated in GenerateBasicWeights(), a
global resilience modifier is applied unconditionally:**
**PvP specs: +7.0 resilience weight — strongly prioritizes resilience
gear
Non-PvP specs: −3.0 resilience weight — actively discourages resilience
gear
Resilience is additionally excluded entirely from trinket slot scoring
via SetExcludeResilience(true), preventing the PvP resilience bonus from
inflating the scores of non-CC trinkets.**
_I tried several different numbers here - as high as 10 and as low as 3
for resilience. I ended up with 7 so nearly all specs will slot
resilience in every slot EXCEPT for trinkets. I stopped weighing
resilience on trinkets because they ended up being garbage trinkets for
the most part - other endgame pve trinkets were way more impactful. In
my testing, the only class/specs that wont use 100% resilience gears are
the tanks, since defense rating/parry/block/dodge weights are so high._
**CC-Break Trinket Cache
At server startup, PlayerbotFactory::BuildCcBreakTrinketCache() queries
the world database for all trinkets (InventoryType=12, Quality≥2) whose
spell IDs include spell 42292 — the CC-break / PvP trinket effect shared
by items like Medallion of the Alliance/Horde. Results are sorted by
item level descending and cached in a static vector, ready for fast
lookup during gearing.**
_This creates a cache of cc trinkets on startup, for this:_
**CC-Break Trinket Force-Equip
During InitEquipment(), PvP-specced bots at level 50 or higher (level
minimum for autogear to apply trinkets) run a pre-selection pass over
ccBreakTrinketCache to find the best CC-break trinket they meet the
level requirement and quality limit for. Human and Undead bots are
excluded from this — they have racial abilities (Every Man for Himself,
Will of the Forsaken) that share the PvP trinket cooldown, making a
dedicated trinket redundant.**
**If a suitable trinket is found, it is stored as pvpTrinket1 and
force-equipped into TRINKET1 before the main gear loop runs. If an item
already occupies the slot, it is moved to bags first. The second-chance
pass also skips TRINKET1 when pvpTrinket1 is set, so the CC trinket is
never overwritten.**
_This is the catch-all forced pvp trinket for trinket slot 1. In my
testing, I really found out how few cc trinkets there are - most of them
are epic, and blue ones start showing up super late in the game. An
heirloom patch would really help the lower levels, being able to equip a
pvp trinket at level 10 or something. Keep in mind, that if your bot
isn't getting a pvp trinket with autogear, make sure they aren't human
or undead, and check your config for what quality items are allowed with
autogear. NOTE - PVP TRINKET STRATEGIES ARE NOT CURRENTLY CODED, SAME
WITH CC RACIALS. They will not break out of stun/cc currently. This is
for future updates if/when I make a trinketstrategy._
**Enhancement Shaman Dual Wield Fix
Classes like Rogues, Frost DKs, and Fury Warriors have their dual wield
capability established through class initialization code in the core.
Enhancement Shamans acquire Dual Wield only through a specific talent
(spell 30798, learned around level 40), and the bot factory had no code
to detect and apply this. The result was that Enhancement Shaman bots
would sometimes have their offhand weapon unequipped — despite having
the talent. After talents are applied in both InitTalentsTree() and
InitTalentsBySpecNo(), the code now checks for spell 30798 and
explicitly grants SKILL_DUAL_WIELD and SetCanDualWield(true) when
present.**
_When testing the weapon speed preferences, I noticed that randombot
enhancement shamans were unequipping their offhand randomly. They would
just walk around with a single 1-hand weapon. This is because they were
not considered in the system as dual wielding, so when initequipment or
autoequipupgrades was ran, it would unequip the offhand through a
function, despite having the dual wield talent. Looking at the code, the
other classes already have this flag (warriors, rogues, dks, hunters)
because they didn't acquire it through talents._
**CalculateItem() Slot Awareness
StatsWeightCalculator::CalculateItem() now accepts an optional slot
parameter (default -1). When provided and the item is a weapon,
ApplyWeaponSpeedGovernance() can be called. Both item scoring calls
inside InitEquipment() — the candidate scoring loop and the incremental
old-item comparison — now pass the current equipment slot.**
_This change allows the calculate item function to know what slot it's
working with, and that's how it modifies it's decision making for some
of the optional features below._
**Holy Paladin Weapon Scoring Fix
Prior to this change, Holy Paladin could end up equipping 2H weapons
because haste and crit sticks (2H weapons) were outscoring appropriate
1H caster weapons — the item type penalty was not catching them
correctly. Holy Paladin is now explicitly added to the dual-wield
penalty group (preventing 2H weapons from being viable), excluded from
the generic caster 1H penalty (since they use 1H + shield rather than a
staff), and given a 0.8x soft preference for 1H weapons.**
_In autogear testing, sometimes 2h weps with high crit/haste would win
over caster gear - this is especially noticeable at lower levels, with
shallower item pools (greens only). You'd hit autogear and the holy
paladin would equip a 2h axe with crit :( So this makes it so holy
paladins only use 1h weapons. They can use either a shield or an
offhand, depending on stat weights._
**PvP Spec Slots Added for All Classes
The existing RandomClassSpecProb / RandomClassSpecIndex config entries
control what percentage of random bots in the world are assigned each
spec. Previously only PvE specs (indices 0–2, or 0–3 for Druids) were
defined, giving server operators no way to introduce PvP-specced random
bots into the world population. This PR adds PvP spec slots for every
class (indices 3–6 depending on class), all defaulting to 0 probability.
Server operators can raise these values to spawn PvP-specced random bots
— e.g., setting RandomClassSpecProb.1.3 = 20 would make 20% of Warrior
bots run Arms PvP.
Two additional PvE specs have also been added:
Death Knight index 3: Double-aura Blood (a hybrid Blood/Frost PvE tank
variant)
Mage index 3: Frostfire (a PvE hybrid spec)
All existing spec entries have been annotated with comments identifying
each one (e.g., # arms pve, # holy pve) for readability.**
_This change was actually added at the start - I realized that there was
no way for pvp-specced randombots to spawn naturally, so I added
optional probabilities to the config. They are currently set at 0% by
default, but giving the user the option I feel is necessary. Also, it
would have been impossible for me to test the init on randombots with
pvp gear otherwise. Also, I noticed that the frostfire mage and the
dual-aura dk didn't have an option, so I added them in as well, as well
as names above each option for quality of life._
**Stat Weight Corrections
The following per-spec stat weights were adjusted to better reflect
actual WotLK priorities. Entries marked NEW did not previously exist;
unmarked rows show old → new values.**
<img width="795" height="268" alt="arms warrior"
src="https://github.com/user-attachments/assets/cb0deb00-a985-432d-81a1-133fc953088b"
/>
_Arms warriors would prefer leather/ap gear about half of the time - the
combined weights of both would often beat strength gear, especially at
lower levels, or where the item pool was shallow. Also, they continued
to spawn with spell power gear and defense gear occasionally, especially
on gear with resilience (resilience, spell power, crit, haste, stam
items)._
<img width="796" height="301" alt="fury warrior"
src="https://github.com/user-attachments/assets/715ff3a3-3d20-4e0e-a953-7ed6fd9386db"
/>
_Fury warriors had the same issues as arms warrior, but really can't
afford to lose a strength item - beserker stance increases strength by
20%. Also had to reduce haste here because haste really isn't nearly as
important as strength, crit, arp. Haste items would win often over
strength/crit/arp gear._
<img width="796" height="300" alt="prot tanks"
src="https://github.com/user-attachments/assets/624de09a-2506-4aee-95aa-c49cbc5b85d3"
/>
_So, prot paladins and prot warriors currently are weighed identically
fyi. Look at that whopping 2.0 agility - twice as important as strength?
I noticed that my prot paladins/warriors were equipping
agility/haste/crit items instead of defense gear on their neck, rings,
trinkets, and back. This adjustment pretty much ensures that defense
gear takes those slots if it's available. Removed the crit/haste
weightings, because realistically if a tank wants more damage, it will
just get strength. Lastly added the spell power penalty because prot
paladins would spawn in fully holy gear if they were pvp specced
(resilience is weighted so high, resilience/spellpower/stam/haste gear
would often win). This aims to prevent that._
<img width="802" height="421" alt="dps dks"
src="https://github.com/user-attachments/assets/371d1344-2382-4460-b3a7-f38b33025b73"
/>
_Same issue with plate dps as the warriors had. Spell power gear would
occasionally spawn on crit/hit items in pve, and a ton of spell power
resilience gear would spawn. There is no scenario where a DK wants spell
power, this isn't patch 3.0.1..._
<img width="796" height="447" alt="blood dk"
src="https://github.com/user-attachments/assets/c84a2bbf-7daa-4805-acf3-cd3bf815eda4"
/>
_Similar issues to prot paladin/warrior. I was really tired of seeing
block rating/value gear as a result of getting gear with defense/stam.
This results in a lot more defense rating/expertise/hit/dodge/parry
gear, and basically makes shield stats nearly non-existent (unless the
upgrade is good enough, it could still win)_
<img width="794" height="226" alt="ret paladin"
src="https://github.com/user-attachments/assets/b09f40ed-b25f-4945-940c-2ce92f81c7c4"
/>
_Prior to this PR, the positive spellpower and int weights were enough
for ret paladins to spawn with spellpower/int/haste/crit gear. This is
unlikely now. And agility/ap was reduced to favor more strength gear._
<img width="795" height="306" alt="Enhancement Shaman"
src="https://github.com/user-attachments/assets/1e5231fd-36ea-4b7e-a546-cf0075d17bd4"
/>
_While spell power is a decent stat on enhancment shamans, it was
appearing on too much gear, especially on items that were
haste/crit/spell power. And for elemental shamans, they were getting
agi/haste/crit gear, so this aims to get rid of those items entirely
without reducing haste/crit._
<img width="800" height="119" alt="shaman pally"
src="https://github.com/user-attachments/assets/6ea3300a-effd-4a03-8f6f-4ae13c5383a5"
/>
_Holy paladins and resto shamans are scored the same, but this prevents
attack power/haste/crit gear, since haste and crit are weighted high._
<img width="1025" height="385" alt="mage"
src="https://github.com/user-attachments/assets/03191dfd-dc09-477d-8424-8fd56f3e0d71"
/>
_Prevents mages from equipping/autogearing items with attack power, some
attack power/crit/haste/hit items were winning with shallow item pools._
<img width="1022" height="502" alt="hunter rogue"
src="https://github.com/user-attachments/assets/06fa67c9-7709-4ee8-a0e2-34de18594018"
/>
_Prevents hunters and rogues from getting spell power leather gear with
hit/crit. Crit is very heavy for hunters so this was decently common._
**Optional Changes (Config-Controlled)**
**AiPlayerbot.PreferClassArmorType (default: 0)
Applies a 3x score multiplier to armor matching the bot's
class-appropriate type (plate/mail/leather/cloth). A significantly
better off-type item can still win — this is a soft preference, not a
hard filter.**
_Are you tired of your fury warrior being a leather daddy? Are you tired
of your holy paladin running around in cloth lingerie? This will fix
that. For mail classes (hunters/shamans) and plate classes, this only
kicks in after level 40. But it really helps adhere to the highest armor
class available. This would be the perfect solution to the quarterly
question "Why is my paladin wearing leather?". This definitely should
remain optional, as quite a few BIS lists would disagree with it.
Leather at certain stages is great for hunters/shamans/warriors/dks._
**AiPlayerbot.AutogearAllowsQuestRewards (default: 0)
Builds a cache of equippable armor and weapon quest rewards at startup.
Bots can then equip these items during autogear, using the quest's
minimum level as the effective required level gate.**
_So, I noticed that autogear didn't allow items without a level
requirement (quest rewards), because it didn't know how to handle that
when giving out gear. It would previously just flat out reject all quest
rewards, as they wouldn't be a part of the item pool. This option
enables quest rewards to be considered in the item pool, and the level
correlates to the lowest level you could get the quest. I have tested
this for about 3 hours across all specs and using blue/green gear, it
seems like a really nice bonus. Keep in mind that I do 0 quests on my
way to 80, so players like me could still benefit from those items. I
think this should remain optional._
**AiPlayerbot.EquipAllSlotsAtAnyLevel (default: 0)
Bypasses the low-level slot restrictions in InitEquipment():
Trinkets normally locked until level 50
Head/Neck until level 30
Rings until level 20
All other non-weapon slots until level 5**
_Autogear currently has level floors for slots - they will not ever give
items below the above thresholds. This config option bypasses that. I
have not tested this as much as I should have, so as people test this,
they could let us know of items that should be blacklisted._
**AiPlayerbot.WeaponSpeedGovernance (default: 0)
When enabled, ApplyWeaponSpeedGovernance() applies a 3x score multiplier
to weapons matching the spec's ideal attack speed profile. Applies to
mainhand, offhand, and ranged slots only. Per-spec preferences:
Arms Warrior: Slow 2H (>=3400ms) in mainhand; poleaxes and axes
preferred (Axe Specialization)
Ret Paladin / Blood & Unholy DK: Slow 2H (>=3400ms) in mainhand
Prot Warrior & Paladin: Slow 1H (>=2600ms) in mainhand
Fury Warrior dual wield: Slow 1H (>=2600ms) in both hands
Fury Warrior titan's grip: Slow 2H (>=3400ms) in both hands
Frost DK: Slow 1H (>=2600ms) in both hands; 2H excluded
Enhancement Shaman (dual wield): Slow 1H (>=2600ms) in both hands;
synchronized MH/OH speeds for flurry procs
Enhancement Shaman (pre-dual wield): Slow 2H (>=3400ms) in mainhand
Combat Rogue: Slow MH (>=2600ms) + Fast OH (<=1500ms)
Assassination / Subtlety Rogue: Slow dagger MH (>=1700ms) + Fast dagger
OH (<=1500ms)
Hunter: Slow ranged (>=2600ms); melee is a stat stick, speed ignored
Feral Druid: No preference (forms normalize attack speed)**
_Besides pvp gearing for pvp specs, I feel like this is one of the
nicest additions. It was really frustrating to see an enhancement shaman
put windfury on a 1.5 dagger. Without this, weights for melee dps are
calculated on dps alone, not weapon speed. You'll see 2h specs use fast
2h weapons (3.0), rogues use 2 fast weapons or slow weapons, frost dks
occasionally using 2h weapons while having dual wield talents. I tested
this for about 6 hours across all mentioned specs at levels 20, 30, 40,
50, 60, 65, 70, 75, and 80, with 3 quality types (greens, blues,
purples). I would actually consider making this mandatory, simply
because of the impact I saw in the dps charts. Super happy and proud of
this._
<img width="1021" height="470" alt="files changes"
src="https://github.com/user-attachments/assets/f55d955c-8760-4adf-b4d9-84797da2dc65"
/>
## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->
<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
_Two caches are built upon startup - the pvp trinket cache and the quest
reward cache. From there, this directly modifies the stat weight
calculations involving initequipement (autogear) and autoequipupgrades,
as both go off of stat weight calculations. I tried to implement these
changes with as little custom functions and coding as possible, and
relied as much as I could on the pre-existing framework._
- Describe the **processing cost** when this logic executes across many
bots.
_Fortunately most of the gates are boolean so it shouldn't impact
performance much at all. I ran these changes on my local server with
stock 500 bots, noticed no pmon difference from the main branch. Did a
24h stress test on my server yesterday, stats looked consistent with the
stress test I did prior to making any changes on 3-31-26._
_It helps that it uses pre-existing functions such as initequipment and
autoequipupgrades, and it really just modifies them with slightly more
logic. That being said, autogear didn't lag my server at all, nor did
the bots equipping upgrades._
## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->
_So, with the basic stock playerbots config (do not forget to copy the
new config!), the only thing that should change is the pvp gear
appearing on pvp specs, and the classes preferring more appropriate
stats across the board. You can load into the game, level a bot to 20,
autogear, and notice the difference. Same at level 40, 60, 75, or
whatever. You could add in the optional config settings to further
streamline the gear you want. I currently run with all 4 enabled, 2 of
which increase the item pool, and 2 of which help guide them to more
appropriate gear (armor/weps)._
## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
- - [x] No, not at all
- - [ ] Minimal impact (**explain below**)
- - [ ] Moderate impact (**explain below**)
_The code is only used on startup (cache generation) and when
autogear/autoequipupgrades is called. Not all the time, and not per
tick. I noticed no performance impact after these changes._
- Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)
_It modifies the decision making as far as equipment goes, but as far as
priority/strategies, this does not affect that._
- Does this change add new decision branches or increase maintenance
complexity?
- - [x] No
- - [ ] Yes (**explain below**)
_Not to my knowledge, but I'll rely on testers and the community to let
me know if it does._
## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- - [ ] No
- - [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
_AI was used in the research of the initequipment system, stat weights,
and cache building. As far as generating the code, using AI was 2 steps
forward, 1 step back. I used Claude Code with Sonnet 4.6 (high) and had
gemini/copilot review the work. **AI did generate a large portion of the
code being used.** I have personally reviewed every line, and a lot was
removed out of being obsolete/new system that copied an old one/too many
comments. I don't think anything else can be trimmed, though. I also
used AI in the PR description, and made my own comments in italics below
each entry. I hate explaining/writing._
<!--
TRANSLATIONS:
Anything new that the bots say in chat must be in a translatable format.
This is done using GetBotTextOrDefault,
which you can search for in the codebase to find examples. Your code
needs to have English as the default fallback,
while the full translations need to be in an SQL update file. The
languages in the file are the nine language
options supported by AzerothCore: English, Korean, French, German,
Chinese, Taiwanese, Spanish, Spanish Mexico, and
Russian. See
data/sql/playerbots/updates/2025_12_27_ai_playerbot_fishing_text.sql as
an example of a translation SQL
update, whose content are called within the codebase at
src/strategy/actions/FishingAction.cpp
-->
## Final Checklist
- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Any new bot dialogue lines are translated.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).
## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
_I would like atleast 5-10 people to review this over the next 1-6
months. The big problem I used to have with my PRs was I was acting like
they were a sprint, when it's really a marathon - good changes take
time, and I was too quick to bust out new content. The old PRs I made
introduced just as many new bugs as they did features. I learned my
lesson, and have tested this extensively (code was pretty much complete
on 4-10-26, been testing alone for the last 11 days) and it's ready for
the test realm for others to try out. I think it's going to be a good
step forward when it comes to gear decision making for bots as a whole.
PvPers have come and gone too much from this project due to the lack of
options, and this helps captivate that audience. Please reach out to me
on discord at Zhur#4391, I am happy to hear results/suggestions there as
well as here._
---------
Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
## Pull Request Description
Initialize random bot professions from the factory using class-matching
or weighted-random profession pairs, respect the active primary
profession cap, and restore required profession tools during bot
init/refresh.
This PR also initializes profession specializations for eligible bots so
crafted professions are not left in an unspecialized state after
profession assignment. Supported specialization families include:
- Alchemy: Transmute / Elixir / Potion
- Engineering: Goblin / Gnomish
- Leatherworking: Dragonscale / Elemental / Tribal
- Tailoring: Spellfire / Mooncloth / Shadoweave
- Blacksmithing: Armorsmith / Weaponsmith, plus Hammersmith / Axesmith /
Swordsmith for eligible Weaponsmith bots
Specialization choices are stored in bot values so they remain stable
across later refreshes. Required tool items are also restored for
relevant professions during maintenance.
## Feature Evaluation
- Describe the **minimum logic** required to achieve the intended
behavior.
- Select one or two professions during factory initialization from a
small weighted list.
- Clamp the assigned professions to the configured primary profession
limit.
- Learn the profession starter spell and set skill to the bot’s
profession cap.
- For professions with supported specialization branches, assign exactly
one valid specialization when the bot meets the same level/skill gates
used by AzerothCore profession scripts.
- Persist the specialization selection in stored bot values so the
choice is stable and does not need to be recalculated repeatedly.
- Restore missing profession tools only when the bot has the related
profession and the tool is absent.
- Describe the **processing cost** when this logic executes across many
bots.
- The added logic executes only during bot init/refresh, not as part of
per-tick combat or trigger evaluation.
- Runtime cost is limited to a few small switch statements, stored value
lookups, spell checks, and item presence checks.
- No expensive repeated searches, map scans, or per-trigger decision
trees were added.
- The design keeps specialization selection deterministic after first
assignment by storing the result, avoiding repeated random branching
later.
## How to Test the Changes
1. Build and restart the server with this branch.
2. Trigger random bot creation, refresh, or level-based reroll for
multiple bots.
3. Verify in `Playerbots.log` that bots receive profession pairs and,
when eligible, profession specializations.
4. Check that low-level bots do not receive specializations before the
required thresholds.
5. Check that eligible bots do receive one specialization for supported
profession families.
6. Verify that specialization choices remain stable across subsequent
refreshes.
7. Verify that profession tools are restored when missing:
- Mining Pick
- Blacksmith Hammer
- Arclight Spanner
- Runed Arcanite Rod
- Skinning Knife
8. For a few bots, inspect in game or via debug tooling that profession
spells/specialization spells are present as expected.
Expected behavior:
- Bots receive professions that respect the configured primary
profession limit.
- Profession skill values are initialized to the level-based cap.
- Eligible bots receive exactly one valid specialization for supported
profession families.
- Specialization assignments are logged and persist across refreshes.
- Profession tools are restored only when required.
## Impact Assessment
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
- - [ ] No, not at all
- - [x] Minimal impact (**explain below**)
- - [ ] Moderate impact (**explain below**)
Explanation:
- The added work runs during initialization/refresh rather than normal
per-tick behavior.
- Logic is bounded, data-local, and based on direct skill/spell/value
checks.
- Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)
Explanation:
- Bots can now start with initialized professions, required tools, and
eligible profession specializations instead of remaining partially
configured or unspecialized.
- Does this change add new decision branches or increase maintenance
complexity?
- - [ ] No
- - [x] Yes (**explain below**)
Explanation:
- The factory now contains specialization assignment branches for
supported profession families.
- Complexity is intentionally limited to init-time switch-based logic
with stored specialization values to preserve predictability.
## AI Assistance
Was AI assistance used while working on this change?
- - [ ] No
- - [x] Yes (**explain below**)
AI assistance was used for:
- code generation and refactoring in `PlayerbotFactory`
- drafting and refining profession/specialization initialization logic
- PR description preparation
All generated and suggested code was reviewed, adjusted, built locally,
and validated before submission.
## Final Checklist
- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Any new bot dialogue lines are translated.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).
## Notes for Reviewers
- Target branch is `test-staging`.
- Profession/specialization logic is intentionally limited to
init/refresh paths to avoid per-tick cost.
- Specialization selections are stored to keep bot behavior stable
across later refreshes.
- Recent changes also add debug logging for assigned specializations and
save the bot after specialization learning so assignments are visible
and persisted.
---------
Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.
DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.
Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.
Before submitting, make sure your changes aligns with these principles.
-->
## Pull Request Description
<!-- Describe what this change does and why it is needed -->
Adds the vendor/quest hub areas of the Isle of Quel'danas to excluded
PvP areas (Shattered Sun Staging Area, Sun's Reach Sanctum, Sun's Reach
Harbor, Sun's Reach Armory). Otherwise, bots attack each other and piss
off all the Shattered Sun Offensive guards and NPCs.
## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->
<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.
## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->
Go to one of the above-mentioned areas while PvP flagged (or on a PvP
server, like me). See if bots attack.
## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
- - [x] No, not at all
- - [ ] Minimal impact (**explain below**)
- - [ ] Moderate impact (**explain below**)
- Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)
- Does this change add new decision branches or increase maintenance
complexity?
- - [x] No
- - [ ] Yes (**explain below**)
## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
Was AI assistance used while working on this change?
- - [x] No
- - [ ] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
<!--
TRANSLATIONS:
Anything new that the bots say in chat must be in a translatable format.
This is done using GetBotTextOrDefault,
which you can search for in the codebase to find examples. Your code
needs to have English as the default fallback,
while the full translations need to be in an SQL update file. The
languages in the file are the nine language
options supported by AzerothCore: English, Korean, French, German,
Chinese, Taiwanese, Spanish, Spanish Mexico, and
Russian. See
data/sql/playerbots/updates/2025_12_27_ai_playerbot_fishing_text.sql as
an example of a translation SQL
update, whose content are called within the codebase at
src/strategy/actions/FishingAction.cpp
-->
## Final Checklist
- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Any new bot dialogue lines are translated.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).
## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
---------
Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
## Pull Request Description
Bots will now engage with outdoor pvp targets when in an area with them.
I carved this out of the guildrpg system Im working on since it should
work just fine as a standalone. Note this requires a core update
https://github.com/azerothcore/azerothcore-wotlk/pull/25103
## Feature Evaluation
Its not expensive. the status checks are fairly light and simple. Should
be on par with current rpg system actions
## How to Test the Changes
You can try to use selfbot to enable this while in EPL, or set the
probability of all other rpg actions to 0.
## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
- [ ] No, not at all
- [x] Minimal impact (**explain below**)
- [ ] Moderate impact (**explain below**)
There is some impact, but should be minimal overall.
- Does this change modify default bot behavior?
- [ ] No
- [x] Yes (**explain why**)
It will activate automatically based on default config.
- Does this change add new decision branches or increase maintenance
complexity?
- [ ] No
- [x] Yes (**explain below**)
## AI Assistance
Was AI assistance used while working on this change?
- [ ] No
- [x] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
Nothing beyond search functionality and autocomplete.
## Final Checklist
- [x] Stability is not compromised.
- [x] Performance impact is understood, tested, and acceptable.
- [x] Added logic complexity is justified and explained.
- [x] Documentation updated if needed (Conf comments, WiKi commands).
## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
---------
Co-authored-by: bash <hermensb@gmail.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
<!--
Thank you for contributing to mod-playerbots, please make sure that
you...
1. Submit your PR to the test-staging branch, not master.
2. Read the guidelines below before submitting.
3. Don't delete parts of this template.
DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND
PREDICTABILITY over behavioral realism.
Every action and decision executes PER BOT AND PER TRIGGER. Small
increases in logic complexity scale
poorly across thousands of bots and negatively affect all. We prioritize
a stable system over a smarter
one. Bots don't need to behave perfectly; believable behavior is the
goal, not human simulation.
Default behavior must be cheap in processing; expensive behavior must be
opt-in.
Before submitting, make sure your changes aligns with these principles.
-->
## Pull Request Description
- Bugfix the jittering on/off of botAlone activity
- BotActiveAlone activity duration configurable
- Updated the default config values for general user for a smoother
experience
- Added offset jittering for the check allowedActivity and check next AI
delay to prevent cpu spikes
(disabled WhenIsFriend can cause race conditions)
## Feature Evaluation
<!--
If your PR is very minimal (comment typo, wrong ID reference, etc), and
it is very obvious it will not have
any impact on performance, you may skip these question. If necessary, a
maintainer may ask you for them later.
-->
<!-- Please answer the following: -->
- Describe the **minimum logic** required to achieve the intended
behavior.
- Describe the **processing cost** when this logic executes across many
bots.
## How to Test the Changes
<!--
- Step-by-step instructions to test the change.
- Any required setup (e.g. multiple players, number of bots, specific
configuration).
- Expected behavior and how to verify it.
-->
## Impact Assessment
<!-- As a generic test, before and after measure of pmon (playerbot pmon
tick) can help you here. -->
- Does this change increase per-bot/per-tick processing or risk scaling
poorly with thousands of bots?
- - [ ] No, not at all
- - [ ] Minimal impact (**explain below**)
- - [x] Moderate impact (**explain below**)
In a positive way, bots in your zone and 150 radius will always be
active, meanwhile other bots will be active 40%
of the time with intervals for 60 seconds per bot. With much lower
latencies. All configurable without say.
40% and 60 seconds for more balance for those who seek bots create world
feel more natural and live vs bots leveling without killing the server
performance. Why not 50 due activity of bots itself 40% will result more
into 45-50% like behavior and 50% prolly more 55%-60%. This it not
something we want incorporate when calculating the value since it
depends on various config and situation. But 40% is good base with
default config.
- Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)
- Does this change add new decision branches or increase maintenance
complexity?
- - [x] No
- - [ ] Yes (**explain below**)
## Messages to Translate
<!--
Bot messages have to be translatable, but you don't need to do the
translations here. You only need to make sure
the message is in a translatable format, and list in the table the
message_key and the default English message.
Search for GetBotTextOrDefault in the codebase for examples.
-->
- Does this change add bot messages to translate?
- - [x] No
- - [ ] Yes (**list messages in the table**)
| Message key | Default message |
| --------------- | ------------------ |
| | |
| | |
## AI Assistance
<!--
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
We expect contributors to be honest about what they do and do not
understand.
-->
- Was AI assistance used while working on this change?
- - [x] No
- - [ ] Yes (**explain below**)
<!--
If yes, please specify:
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation).
- Which parts of the change were influenced or generated, and whether it
was thoroughly reviewed.
-->
## Final Checklist
- - [x] Stability is not compromised.
- - [x] Performance impact is understood, tested, and acceptable.
- - [x] Added logic complexity is justified and explained.
- - [x] Documentation updated if needed (Conf comments, WiKi commands).
## Notes for Reviewers
<!-- Anything else that's helpful to review or test your pull request.
-->
---------
Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
Co-authored-by: Revision <tkn963@gmail.com>
Co-authored-by: kadeshar <kadeshar@gmail.com>
# Pull Request
Feature - Enable multi node flying for bots
- Bots currently only do node to node flying. This PR makes it so they
can connect multiple noted.
-- This is enabled by sending a vector containing the node sequence
instead of a single destination node
-- To minimize the run-time cost of searching for available nodes and
connection, a cache of all possible connections is prepared at start up
using a BFS search algorithm.
Refactor
- Move all world destination logic (cities, banks, inns) to existing
Travel manager
- Eliminate flightmastercache and integrate to new manager
- replace SQLs calls with in-memory data search by core
- Add in new map that stores creature areas by template.
Clean up
- Move other rpg files to related folder.
(Next steps) The selection for where bots fly to should be smarter than
it is. Instead of trying to determine where a bot can go, it should
first decide where it should go, and then identify the correct way to
get there.
---
## Feature Evaluation
Please answer the following:
- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?
---
## How to Test the Changes
- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it
## Complexity & Impact
Does this change add new decision branches?
- - [x[ No
- - [ ] Yes (**explain below**)
Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)
Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
The call itself is fairly infrequent, and although now there are a
greater number of paths available for the bots, I dont think it would be
significant.
## Defaults & Configuration
Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)
If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---
## AI Assistance
Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [ ] No
- - [x] Yes (**explain below**)
Gemini first suggested the use of a BFS algorithm. This was rewritten by
me to actually work as intended. Verification by additional logging not
present in final code.
Claude code converted the SQL filtering to the atrocious if statements
found in PrepareDestinationCache, but after verifying them it works. If
there are better ways to do this Im open to it.
---
## Final Checklist
- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
# Pull Request
This fixes the loot rolling behavior issue created by #2068 .
Introduce the ability for enchanter bots to disenchant items they dont
need, and roll need on recipes they also need.
Make it so ITEM_USAGE_AH ensures the item is not BOP.
Try to reduce the call for item_usage in CalculateRollVote by passing
usage if available.
---
## Design Philosophy
We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.
Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.
Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.
Principles:
- **Stability before intelligence**
A stable system is always preferred over a smarter one.
- **Performance is a shared resource**
Any increase in bot cost affects all players and all bots.
- **Simple logic scales better than smart logic**
Predictable behavior under load is more valuable than perfect decisions.
- **Complexity must justify itself**
If a feature cannot clearly explain its cost, it should not exist.
- **Defaults must be cheap**
Expensive behavior must always be optional and clearly communicated.
- **Bots should look reasonable, not perfect**
The goal is believable behavior, not human simulation.
Before submitting, confirm that this change aligns with those
principles.
---
## Feature Evaluation
Please answer the following:
- Describe the **minimum logic** required to achieve the intended
behavior?
-- Add a new check that downgrades greed rolls to desired levels, or
bools for the other two options.
- Describe the **cheapest implementation** that produces an acceptable
result?
-- As implemented.
- Describe the **runtime cost** when this logic executes across many
bots?
-- Same as before. Item usage is the heaviest part, and that hasnt
changed to accommodate this.
---
## How to Test the Changes
- multiple bots in a group with group loot on, do a dungeon or
something. One bot should be an enchanter.
## Complexity & Impact
Does this change add new decision branches?
- - [ ] No
- - [x] Yes (**explain below**)
Does this change increase per-bot or per-tick processing?
- - [X] No
- - [ ] Yes (**describe and justify impact**)
Could this logic scale poorly under load?
- - [X] No
- - [ ] Yes (**explain why**)
---
## Defaults & Configuration
Does this change modify default bot behavior?
- - [ ] No
- - [X] Yes (**explain why**)
- - - Corrects the looting behavior to original design.
If this introduces more advanced or AI-heavy logic:
- - [ ] Lightweight mode remains the default
- - [X] More complex behavior is optional and thereby configurable
---
## AI Assistance
Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)
---
## Final Checklist
- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
# Pull Request
Added all TBC attunement quests to conf
---
## Design Philosophy
We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.
Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.
Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.
Principles:
- **Stability before intelligence**
A stable system is always preferred over a smarter one.
- **Performance is a shared resource**
Any increase in bot cost affects all players and all bots.
- **Simple logic scales better than smart logic**
Predictable behavior under load is more valuable than perfect decisions.
- **Complexity must justify itself**
If a feature cannot clearly explain its cost, it should not exist.
- **Defaults must be cheap**
Expensive behavior must always be optional and clearly communicated.
- **Bots should look reasonable, not perfect**
The goal is believable behavior, not human simulation.
Before submitting, confirm that this change aligns with those
principles.
---
## Feature Evaluation
Please answer the following:
- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?
---
## How to Test the Changes
- Step-by-step instructions to test the change
Run maintenance on bots
- Any required setup (e.g. multiple players, bots, specific
configuration)
This only applies to Individual Progression mod, since attunements
aren't required in base AC
- Expected behavior and how to verify it
Bots should be able to enter:
- The Eye (Tempest Keep)
- Mount Hyjal
- Black Temple
## Complexity & Impact
Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)
Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)
Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---
## Defaults & Configuration
Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)
All attunements for TBC are now added on 'maintenance' command
If this introduces more advanced or AI-heavy logic:
- - [ ] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---
## AI Assistance
Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)
If yes, please specify:
- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.
---
## Final Checklist
- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
# Pull Request
Moving hardcoded values to config
## How to Test the Changes
- use maintenance command
- unequip and destroy item get from this command
- turn off server
- add item to config
- turn on server
- use maintenace command
- check that different item was provided
## Complexity & Impact
Does this change add new decision branches?
- - [X] No
- - [ ] Yes (**explain below**)
Does this change increase per-bot or per-tick processing?
- - [X] No
- - [ ] Yes (**describe and justify impact**)
Could this logic scale poorly under load?
- - [X] No
- - [ ] Yes (**explain why**)
---
## Defaults & Configuration
Does this change modify default bot behavior?
- - [X] No
- - [ ] Yes (**explain why**)
---
## AI Assistance
Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [X] No
- - [ ] Yes (**explain below**)
---
## Final Checklist
- - [X] Stability is not compromised
- - [X] Performance impact is understood, tested, and acceptable
- - [X] Added logic complexity is justified and explained
- - [X] Documentation updated if needed
---
## Notes for Reviewers
# Pull Request
Feat:
A common problem I have with follower bots is that if I quickly run up
to a flightmaster and select a destination, as I go on my way, the bots
can't get on a damn bird and say "Cannot find any flightmaster to talk".
Guy was 8 yards away and they're completely blind to him.
This is because when you select a destination, at that moment the bot
would check `GetNPCIfCanInteractWith` from core, which uses
`INTERACTION_DISTANCE`, which is defined as 5.5 yards. So the bot has to
have caught up with you to be within 5.5 yards of the flightmaster.
This PR expands that distance to use our own
`sPlayerbotAIConfig.farDistance`, which is by default set to 20 yards.
So just as long as bots have caught up to be within 20 yards from the
flightmaster, they will follow you.
Fix:
While I was doing this, I noticed that the timings for bot flight
staggering (introduced in #1281) are defined in TaxiAction and
PlayerbotAIConfig. So I removed their definitions from TaxiAction, made
proper calls to the configs, and renamed them to similar format that
other configs use.
---
## Design Philosophy
We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.
Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.
Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.
Principles:
- **Stability before intelligence**
A stable system is always preferred over a smarter one.
- **Performance is a shared resource**
Any increase in bot cost affects all players and all bots.
- **Simple logic scales better than smart logic**
Predictable behavior under load is more valuable than perfect decisions.
- **Complexity must justify itself**
If a feature cannot clearly explain its cost, it should not exist.
- **Defaults must be cheap**
Expensive behavior must always be optional and clearly communicated.
- **Bots should look reasonable, not perfect**
The goal is believable behavior, not human simulation.
Before submitting, confirm that this change aligns with those
principles.
---
## Feature Evaluation
Please answer the following:
- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?
Changes here use a minimal amount of code to accomplish the objective,
including using pre-defined distance values rather than creating new
ones. Changes have no effect on processing.
---
## How to Test the Changes
For expanding flightmaster search distance: You will be using the `stay`
command. A bot commanded to `stay` will still take a flight with you, if
it is near a flightmaster. So you can use the command to position the
bot exactly where you want it to be
1. Place your follower bot immediately next to the flightmaster
2. Take a flight and the bot should follow. Nothing new here
3. Place the bot about 12 yards away from flightmaster.
4. Take a flight and the bot should follow. Same as before.
5. Repeat again, but this time place the bot 22 yards away. It should
not follow you and instead say "Cannot find any flightmaster to talk"
6. The change should work correctly with `InstantFlightPaths = 0` in
worldserver.conf, or if it's set to 1/2 and bots can instantly fly.
For the config of staggering:
1. Make sure `InstantFlightPaths = 0` in worldserver.conf.
2. Change the timings in playerbots.conf under the `# FLIGHTPATH`
section.
3. Changes should be correctly reflected in world.
## Complexity & Impact
Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)
Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)
Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---
## Defaults & Configuration
Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)
Follower bots search a slightly bigger distance for nearby
flightmasters.
If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [x] More complex behavior is optional and thereby configurable
---
## AI Assistance
Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)
If yes, please specify:
- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.
---
## Final Checklist
- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
# Pull Request
I've being getting ready to test Serpentshrine Cavern strategy on
`test-staging`, but noticed the bots don't currently have attunement
setup.
Added attunement quest.
---
## Design Philosophy
We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.
Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.
Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.
Principles:
- **Stability before intelligence**
A stable system is always preferred over a smarter one.
- **Performance is a shared resource**
Any increase in bot cost affects all players and all bots.
- **Simple logic scales better than smart logic**
Predictable behavior under load is more valuable than perfect decisions.
- **Complexity must justify itself**
If a feature cannot clearly explain its cost, it should not exist.
- **Defaults must be cheap**
Expensive behavior must always be optional and clearly communicated.
- **Bots should look reasonable, not perfect**
The goal is believable behavior, not human simulation.
Before submitting, confirm that this change aligns with those
principles.
---
## Feature Evaluation
Please answer the following:
- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?
---
## How to Test the Changes
- Add bots and convert to raid
- Make sure you have attunement by completing
[this](https://www.wowhead.com/tbc/quest=13431/the-cudgel-of-kardesh)
quest
- Teleport to SSC and summon bots. The bots should appear in the raid.
## Complexity & Impact
Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)
Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)
Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---
## Defaults & Configuration
Does this change modify default bot behavior?
- - [ ] No
- - [x] Yes (**explain why**)
This adds the attunement quest for SSC by default
If this introduces more advanced or AI-heavy logic:
- - [x] Lightweight mode remains the default
- - [ ] More complex behavior is optional and thereby configurable
---
## AI Assistance
Was AI assistance (e.g. ChatGPT or similar tools) used while working on
this change?
- - [x] No
- - [ ] Yes (**explain below**)
If yes, please specify:
- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.
---
## Final Checklist
- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
# Pull Request
* Fix the rest of the trainer-related functionality: list spells and
learn (cast vs. direct learn) spells.
* Rewrite `TrainerAction`: split the logic between appropriate methods
(`GetTarget`, `isUseful`, `isPossible`) instead of pushing everything
inside a single `Execute` method.
* Change method definitions to remove unnecessary declarations and
parameters overhead.
* Move the `Trainer` header into the implementation. Rewrite
`RpgTrainTrigger` to fit the original logic and move all validation to
`RpgTrainAction` (`isUseful` + `isPossible`).
* Implement "can train" context value calculation to use with
`RpgTrainTrigger`.
* Update and optimize "train cost" context value calculation -- it
should be much faster.
* Replace `AiPlayerbot.AutoTrainSpells` with
`AiPlayerbot.AllowLearnTrainerSpells` and remove the "free" value
behavior — please use `AiPlayerbot.BotCheats` if you want bots to learn
trainer's spells for "free".
* Add `nullptr` checks wherever necessary (only inside targeted
methods/functions).
* Make some codestyle changes and corrections based on the AC codestyle
guide.
---
## Design Philosophy
We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.
Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.
Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.
Principles:
- **Stability before intelligence**
A stable system is always preferred over a smarter one.
- **Performance is a shared resource**
Any increase in bot cost affects all players and all bots.
- **Simple logic scales better than smart logic**
Predictable behavior under load is more valuable than perfect decisions.
- **Complexity must justify itself**
If a feature cannot clearly explain its cost, it should not exist.
- **Defaults must be cheap**
Expensive behavior must always be optional and clearly communicated.
- **Bots should look reasonable, not perfect**
The goal is believable behavior, not human simulation.
Before submitting, confirm that this change aligns with those
principles.
---
## How to Test the Changes
Force bots to learn spells from trainers using the chat command `trainer
learn` or `trainer learn <spellId>`. Bots should properly list available
spells (`trainer` command) or learn them (based on configuration and
command).
## Complexity & Impact
- Does this change add new decision branches?
- [x] No
- [ ] Yes (**explain below**)
- Does this change increase per-bot or per-tick processing?
- [x] No
- [ ] Yes (**describe and justify impact**)
- Could this logic scale poorly under load?
- [x] No
- [ ] Yes (**explain why**)
---
## Defaults & Configuration
- Does this change modify default bot behavior?
- [x] No
- [ ] Yes (**explain why**)
If this introduces more advanced or AI-heavy logic:
- [x] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable
---
## AI Assistance
- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
- [x] No
- [ ] Yes (**explain below**)
If yes, please specify:
- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted
AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.
---
## Final Checklist
- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
---------
Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
# Pull Request
- Applies the clean and corrected singletons, Meyer pattern. (cherry
picked from @SmashingQuasar )
Testing by just playing the game in various ways. Been tested by myself
@Celandriel and @SmashingQuasar
---
## Complexity & Impact
- Does this change add new decision branches?
- [x] No
- [ ] Yes (**explain below**)
- Does this change increase per-bot or per-tick processing?
- [x] No
- [ ] Yes (**describe and justify impact**)
- Could this logic scale poorly under load?
- [x] No
- [ ] Yes (**explain why**)
---
## Defaults & Configuration
- Does this change modify default bot behavior?
- [x] No
- [ ] Yes (**explain why**)
---
## AI Assistance
- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
- [x] No
- [ ] Yes (**explain below**)
---
## Final Checklist
- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
---------
Co-authored-by: Nicolas Lebacq <nicolas.cordier@outlook.com>
Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
The idea is to centralize the creation, assignment, and management of
bot guilds into a single class that can be referenced.
The way this is intended to work.
when the manager is created, if the config option to delete guilds is
set, then it deletes all bot guilds.
On startup
1. Load all guild names from database. Shuffle keys for some
randomization.
2. Load Guilds from database
3. For existing guilds, identify the guild faction, number of members,
and assess if the guild is 'full' based on the number of bots set in
config.
4. Determine if the leader of the guild is a real player based on the
leader account.
5. Mark any playerbot guild names as not available (false).
The validation process (2-5) is set to run once an hour.
Guild Creation.
Now guild creation occurs on an as needed bases during the
initialization process. Previously, all of the guilds would be created
at once, and then randomly assigned.
When a bot is not in a guild during initialization, it will check if
there are any partially filled guilds of that bots faction where the bot
can be assigned to. If not, and the cache of bot guilds is less than the
set number in config, it will randomly return the available name. This
then goes to the CreateGuild function where the core guild manager
creates a guild, the guild emblem is set, and the cache updated.
If a bot is assigned to guild, but fails to join then it throws an
error.
Checking for real player guilds function now lives in the guild manager.
---------
Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
### Update :Thank you to @notOrrytrout from prompting me to work on
this. Its been a huge learning experience.
With @notOrrytrout I started working on enabling bot fishing with
master, but also on their own.
The first commit didnt crash, showing that it was possible to have a bot
cast when master does. Currently it compiles but crashes when you try to
fish with a bot in the group, whether the bot has fishing or not. It
makes me think that the check in FishingValues is broken somehow, but I
cant figure out how.
---------
Co-authored-by: bash <31279994+hermensbas@users.noreply.github.com>
This PR adds a couple of neutral quest hubs in Outland to PvP restricted
areas (and makes a couple of very minor formatting fixes to the Karazhan
files).
3786: Ogri'la
3973: Blackwind Landing (Sha'tari Skyguard quest hub in Skettis)
Fixes crashes and race conditions when bots perform group/guild/arena
operations by moving thread-unsafe code to world thread.
Potentially fixes#1124
## Changes
- Added operation queue system that runs in world thread
- Group operations (invite, remove, convert to raid, set leader) now
queued
- Arena formation refactored to use queue
- Guild operations changed to use packet queueing
## Testing
Set `MapUpdate.Threads` > 1 in worldserver.conf to enable multiple map
threads, then test:
- Group formation and disbanding
- Arena team formation
- Guild operations (invite, promote, demote, remove)
- Run with TSAN
cmake ../ \
-DCMAKE_CXX_FLAGS="-fsanitize=thread -g -O1" \
-DCMAKE_C_FLAGS="-fsanitize=thread -g -O1" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" \
-DCMAKE_INSTALL_PREFIX=/path/to/install \
-DCMAKE_BUILD_TYPE=RelWithDebInfo
build
export
TSAN_OPTIONS="log_path=tsan_report:halt_on_error=0:second_deadlock_stack=1"
./worldserver
The crashes/race conditions should no longer occur with concurrent map
threads.
## New Files
- `PlayerbotOperation.h` - Base class defining the operation interface
(Execute, IsValid, GetPriority)
- `PlayerbotOperations.h` - Concrete implementations:
GroupInviteOperation, GroupRemoveMemberOperation,
GroupConvertToRaidOperation, GroupSetLeaderOperation,
ArenaGroupFormationOperation
- `PlayerbotWorldThreadProcessor.h/cpp` - Singleton processor with
mutex-protected queue, processes operations in WorldScript::OnUpdate
hook, handles batch processing and validation
---------
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
Co-authored-by: SaW <swerkhoven@outlook.com>
Co-authored-by: bash <hermensb@gmail.com>
This update reorganizes and rewrites the random bot timing configuration
section for clarity and accuracy. The previous section was mislabeled as
"INTERVALS" and lacked precise descriptions. The new version:
1. Renames the header to RANDOM BOT TIMING AND BEHAVIOR
2. Adds concise, standardized comments for each parameter
3. Corrects misleading terminology (not all values are intervals)
4. Documents defaults and actual behavior clearly for easier tuning and
maintenance
5. No functional code changes — documentation and readability only.
Note, this is derived information from reading the code.
Please double check if I have captured each param accurately!
* Maintenance config controls
bools in config
* Update TrainerAction.cpp
removed some note-to-selfs (personal config preferences)
* Set default to true
Also tidied up some comments
* Update playerbots.conf.dist
* Reorganised
Changed the description in conf to be less conversational.
Rearranged the order that options are arranged, grouping by what made sense to me (the type of gameplay made easier/skipped by the option being enabled).
Rearranged the order the variables and method calls are listed in the code to match the order they are presented in the conf to make future maintenance of maintenance (:P) more intuitive.
* Update playerbots.conf.dist
Revert previous commit (change to call order in MaintenanceAction::Execute)
conf settings grouped
* Paladin buff logic: Sanctuary+Kings synergy, role-aware targeting, safer Greater buffs
* Update PaladinActions.cpp
* Update PaladinActions.cpp
* All configs should be implement into PlayerbotAIConfig and sPlayerbotAIConfig used in code
* added: prayer of fortitude
* Magic number removed
* Update PaladinActions.cpp
* Update PaladinActions.cpp
* Update PaladinActions.cpp
* Update PaladinActions.cpp
* Update PaladinActions.cpp
* Add patch for solo paladin in group
* Correction review
* Update PaladinActions.cpp
* Add harcoded text to DB
* Update playerbots.conf.dist
Added Half-Burried Bottle to the list of dissallowed GO's
* Update PlayerbotAIConfig.cpp
Added Half-Burried Bottle to the list of disallowed GO's in the standard values of the source to complete this PR
* Add SMV area IDs to PvP Prohibited Areas
Sanctum of the Stars and the Altar of Sha’tar
* Update source default pvpProhibitedAreaIDs
* Update source default pvpProhibitedAreaIDs
Now with Sanctum of the Stars & Altar of Sha'tar as well
Hello everyone,
I am on a quest to make bot's pets completely functional, focuses on solving issues #1351 , #1230 , and #1137 . This PR achieves the following:
1. Changes the current "pet" chat command to "tame", which is more intuitive that only hunters can use it. The modes are "tame name (name)", "tame id (id)", "tame family (family)", "tame rename (new name)", and "tame abandon". Tame abandon is new - it simply abandons the current pet. Also, now, if you type in "tame family" by itself, it will list the available families. See pictures below for examples.
2. Added new "pet" chat command, with the following modes: "pet passive", "pet aggressive", "pet defensive", "pet stance" (shows current pet stance), "pet attack", "pet follow", and "pet stay". Previously, the pet's stance was not changeable, and there were some less than desired effects from summonable pets - see the issues above.
3. New config option: AiPlayerbot.DefaultPetStance, which changes the stance that all bot's pets are summoned as. This makes sure when feral spirits or treants are summoned by shamans and druids, they are immediately set to this configured stance. Set as 1 as default, which is defensive. (0 = Passive, 1 = Defensive, 2 = Aggressive)
4. New config option: AiPlayerbot.PetChatCommandDebug, which enables debug messages for the "pet" chat command. By default it is set to 0, which is disabled, but if you would like to see when pet's stances are changed, or when you tell the pet to attack/follow/stay, and when pet spells are auto-toggled, this is an option. I made this for myself mainly to test the command - if anyone notices any wierd pet behavior, this will be an option to help them report it as well.
5. Modified FollowActions to not constantly execute the petfollow action, overriding any stay or attack commands issued.
6. Modified GenericActions to have TogglePetSpellAutoCastAction optionally log when spells are toggled based on AiPlayerbot.PetChatCommandDebug.
7. Modified PetAttackAction to not attack if the pet is set to passive, and not override the pet's stance to passive every time it was executed.
8. Modified CombatStrategy.cpp to not constantly issue the petattack command, respecting the "pet stay" and "pet follow" commands. Pets will still automatically attack the enemy if set to aggressive or defensive.
9. Warlocks, Priests, Hunters, Shamans, Mages, Druids, and DKs (all classes that have summons): Added a "new pet" trigger that executes the "set pet stance" action. The "new pet" trigger happens only once, upon summoning a pet. It sets the pet's stance from AiPlayerbot.DefaultPetStance's value.