Repository navigation
Conversation
graphify writes its knowledge graph and per-file cache to graphify-out/ in whichever directory it runs on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TalentSpec::ReadTalents checked HasSpell for each talent rank, which misses ranks whose spell the player does not hold as a learned spell, so a captured talent link recorded only a few points. HasTalent reads the talent map the player actually saves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No behaviour change; groundwork for gearing bots outside the factory: - PlayerbotFactory: RemoveGlyphs and ApplyGlyph are extracted from InitGlyphs; IsBodyArmorSlot and GetPossibleInventoryTypeListBySlot are static. - InitTalentsBySpecNo no longer stores the spec number as the bot's chosen spec; ChangeTalentsAction, the one caller choosing a spec, stores it. - ApplyEnchantAndGemsNew can be limited to some items (onlyItems, counting jeweler's gems already on the others) and take an EnchantScorer that scores candidates in place of StatsWeightCalculator. The gem loop reuses the routine's calculator instead of building one per candidate. - StatsWeightCalculator can take the role from the talent spec instead of the active strategies (roleBySpec). - BisListMgr::GetTiers lists the BiS tiers for a class and tab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pure logic for the arena loadout swap, with no core types so it can be unit tested without a server: - PvpLoadoutRules: the item level curve, PvP premade per talent tree, vendor rating requirements, gear limits and rating eligibility, the rating tier a rating unlocks, the match rating (rated: opposing MMR; skirmish: real players first, then bots), the enter/apply/restore decision, and the snapshot with its item copies in the item_instance column formats. - PvpLoadoutEp: equivalence points from a role profile's stat targets (hit and spell penetration stop counting at their targets, resilience drops to a low weight past it), the four-piece set choice, and biggest-gain-first selection over groups of slots with unique-item constraints. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tier - PvpGearListMgr builds the PvP gear pool once at startup: armor and weapons with resilience or an honor or arena point cost, sold by vendors spawned somewhere other than GM Island, with the personal rating their vendors require. Per class, PvP premade and level it ranks the pool with StatsWeightCalculator in PvP mode. - Match loadouts are chosen once per class, talent tree, level, faction and rating tier and shared by every bot of that spec: a four-piece of the best set the rating allows, then the remaining slots by biggest marginal EP against the role profile, from the ranked PvP items and the PvE item of the highest BiS tier at or below the rating's item level that the bot can wear. Body armor is the heaviest type the bot is proficient in, and candidates need their weapon, armor or shield skill. - PvpLoadoutStats reads items, enchants and bots into EP stats through StatsCollector, with ratings scaled to their level-80 equivalent at the bot's level, so the level-80 profile targets hold below 80. - Config: AiPlayerbot.PvpLoadout* options, the four AiPlayerbot.PvpProfile.* role profiles, and the PvP premade per talent tree. - PvpLoadoutLog: debug lines behind AiPlayerbot.PvpLoadoutDebug. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…after Random bots entering an arena (rated or skirmish) take a PvP loadout and give it back when the match ends; opt-in with AiPlayerbot.PvpLoadoutSwap. - On entry the bot snapshots its PvE talents and glyphs, respecs in place to the PvP premade of its talent tree, and plans its match gear for the opponents' rating: the cached loadout, keeping its own items where they are worth more against its measured hit, spell penetration and resilience. - The PvE items the gear replaces are kept as copies of their persisted state (crafter, gems, enchants, random suffix, durability, charges) in playerbots_pvp_loadout_item, saved with the snapshot in one transaction. Only once that has committed are they destroyed and the match items created in their slots, so a bot needs no bag space and a crash at any point leaves either its items or their copies. Match gear is gemmed and enchanted towards the role's targets. - At match end, on leaving, after a crash or relog, and before a factory refresh or randomize, the bot gets its talents and glyphs back, its match items are destroyed and its PvE items re-equipped or recreated (slot, else bags, else mail). The copies are deleted only once the restored inventory is saved. - Engine: "pvp loadout" strategy, trigger, action and value; a multiplier stops equip upgrades while a loadout is held. AiFactory adds the strategy to random bots. - Optional skirmish announcement to the bot's real teammates (AiPlayerbot.PvpLoadoutAnnounce, translated texts) and debug lines (AiPlayerbot.PvpLoadoutDebug). Every option is documented in playerbots.conf.dist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
playerbots_tests (-DPLAYERBOTS_TESTS=ON, off by default) covers the pure PvpLoadoutRules and PvpLoadoutEp code: config parsing, rating requirements, eligibility and tiers, the match rating, the swap decision, snapshot and item copy formats, EP weights, set choice, and biggest-gain-first selection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds configurable PvP gear selection and loadout scoring for random bots. The feature stores PvE item and talent snapshots, detects arena transitions, and applies or restores PvP talents and gear. It also adds announcement text, debug settings, repository callback processing, and tests for loadout rules, serialization, and transitions. Priority: ➖ Normal Merge Risk: 🔵 Low · up to The opt-in arena loadout feature has no established functional defect. The remaining issues are small comment-style changes required by project guidelines and can be fixed quickly before merging.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/Mgr/Item/PvpGearListMgr.h (1)
20-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueShorten the new comments that run longer than two lines. The path instructions allow comments longer than two lines only in exceptional cases. These comments are not exceptional.
src/Mgr/Item/PvpGearListMgr.h#L20-L24: reduce the class comment to the GM Island exclusion and cache scope in two lines.src/Mgr/PvpLoadout/PvpLoadoutStats.h#L15-L18: keep only the level-80 rating-scaling quirk.src/Ai/Base/Actions/BattleGroundJoinAction.cpp#L721-L723: keep only "armor cannot be equipped in combat".src/Ai/Base/Actions/PvpLoadoutAction.h#L14-L16: state the save-then-equip ordering in two lines.As per path instructions: "flag any new or changed non-exceptional comment longer than two lines."
Source: Path instructions
src/Ai/Base/Strategy/PvpLoadoutStrategy.cpp (1)
12-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the comment that justifies the relevance by a competing action.
The path instructions flag any comment that justifies a relevance value by naming competing actions.
ACTION_HIGHis a named band and needs no justification.
As per path instructions: "Flag bare floats that sit between bands and any comment that justifies a number by listing competing actions."Source: Path instructions
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository: mod-playerbots/mod-playerbots/.coderabbit.yaml
- Review profile: CHILL
- Plan: Advanced
- Run ID:
606adae2-7630-4382-9b67-875fa528f08c
📒 Files selected for processing (52)
.gitignoreconf/playerbots.conf.distdata/sql/playerbots/updates/2026_10_03_00_playerbots_pvp_loadout.sqldata/sql/playerbots/updates/2026_10_04_00_ai_playerbot_pvp_loadout_announce_text.sqlmod-playerbots.cmakesrc/Ai/Base/ActionContext.hsrc/Ai/Base/Actions/BattleGroundJoinAction.cppsrc/Ai/Base/Actions/ChangeTalentsAction.cppsrc/Ai/Base/Actions/PvpLoadoutAction.cppsrc/Ai/Base/Actions/PvpLoadoutAction.hsrc/Ai/Base/Strategy/PvpLoadoutStrategy.cppsrc/Ai/Base/Strategy/PvpLoadoutStrategy.hsrc/Ai/Base/StrategyContext.hsrc/Ai/Base/Trigger/PvpTriggers.cppsrc/Ai/Base/Trigger/PvpTriggers.hsrc/Ai/Base/TriggerContext.hsrc/Ai/Base/Value/PvpLoadoutValue.cppsrc/Ai/Base/Value/PvpLoadoutValue.hsrc/Ai/Base/ValueContext.hsrc/Bot/Factory/AiFactory.cppsrc/Bot/Factory/PlayerbotFactory.cppsrc/Bot/Factory/PlayerbotFactory.hsrc/Bot/Factory/RandomPlayerbotFactory.cppsrc/Db/PlayerbotPvpLoadoutRepository.cppsrc/Db/PlayerbotPvpLoadoutRepository.hsrc/Db/PlayerbotsDatabase.cppsrc/Db/PlayerbotsDatabase.hsrc/Mgr/Item/BisListMgr.cppsrc/Mgr/Item/BisListMgr.hsrc/Mgr/Item/PvpGearListMgr.cppsrc/Mgr/Item/PvpGearListMgr.hsrc/Mgr/Item/StatsWeightCalculator.cppsrc/Mgr/Item/StatsWeightCalculator.hsrc/Mgr/PvpLoadout/PvpLoadoutEp.cppsrc/Mgr/PvpLoadout/PvpLoadoutEp.hsrc/Mgr/PvpLoadout/PvpLoadoutLog.hsrc/Mgr/PvpLoadout/PvpLoadoutMgr.cppsrc/Mgr/PvpLoadout/PvpLoadoutMgr.hsrc/Mgr/PvpLoadout/PvpLoadoutRules.cppsrc/Mgr/PvpLoadout/PvpLoadoutRules.hsrc/Mgr/PvpLoadout/PvpLoadoutStats.cppsrc/Mgr/PvpLoadout/PvpLoadoutStats.hsrc/Mgr/Talent/Talentspec.cppsrc/PlayerbotAIConfig.cppsrc/PlayerbotAIConfig.hsrc/Script/Playerbots.cpptests/PvpLoadoutConfigTest.cpptests/PvpLoadoutCopyTest.cpptests/PvpLoadoutEpTest.cpptests/PvpLoadoutGearTest.cpptests/PvpLoadoutSnapshotTest.cpptests/PvpLoadoutStateTest.cpp
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.
Comments longer than two lines are cut to two or fewer, and the relevance comment that justified ACTION_HIGH by naming competing actions is removed, as asked in the CodeRabbit review. No code changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GCC rejects two warnings Clang does not report: the paired-slot loop copied each pair (-Wrange-loop-construct), and two conditionals mixed the NULL_SLOT enumerator with a uint8 (-Wextra). Iterate by reference and cast NULL_SLOT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Overview
Random bots fight in arenas in their PvE spec and PvE gear: a leveling or raid build with no resilience, whatever the opponents' rating. A 2000-rated player and a fresh 80 meet the same bots.
With
AiPlayerbot.PvpLoadoutSwap = 1(off by default), a random bot entering an arena (rated or skirmish):The PvE items it takes off are saved as full copies (crafter, gems, enchants, random suffix, durability) and recreated afterwards, so a bot needs no free bag space and no item is lost in a crash.
Feature Evaluation
How to Test the Changes
AiPlayerbot.PvpLoadoutSwap = 1. Optional:AiPlayerbot.PvpLoadoutAnnounce = 1(bots say their spec, item level and rating in party chat in skirmishes) andAiPlayerbot.PvpLoadoutDebug = 1.AiPlayerbot.RandomBotAutoJoinBGRatedArena*Count); tested at 70-79 and 80, ratings 0 to ~1900.plans match gear,match gear for ratingandmatch gems and enchants(totals against targets).Impact Assessment
Does this change increase per-bot/per-tick processing or risk scaling poorly with thousands of bots?
Off by default. When on, only bots in arenas do real work, once per match; every random bot carries a cached-value trigger check every 2 s and a multiplier check.
pmon, 500 bots,
BotActiveAlone = 100, smart scale off, rated arenas auto-joined, 103 minutes each: bot AI 1.627 ms per tick with the option off, 1.530 ms with it on (run-to-run noise). With it on, the feature's trigger, action and multiplier took 1.64 s of 951.9 s (0.17%, ~2.6 µs per tick): the trigger 0.5 µs and the multiplier 0.1 µs per call, the action 2.0 ms per call (max 3.7 ms), 360 calls across the arena entries in the window.Does this change modify default bot behavior?
The feature itself is opt-in. Two shared-code changes apply to every bot:
TalentSpec::ReadTalentsnow reads learned talents withHasTalent(it missed most ranks withHasSpell), andInitTalentsBySpecNono longer stores the spec as the bot's chosen spec (ChangeTalentsAction, the caller choosing a spec, stores it).Does this change add new decision branches or increase maintenance complexity?
New strategy, trigger, action and value, two playerbots tables, and ~2,600 lines in
src/Mgr/PvpLoadout,PvpGearListMgrand the repository (3,300 in all, without tests). The decision logic is pure and unit-tested; shared code only gains small, default-off extension points.AI Assistance
Was AI assistance used while working on this change?
Claude Code (Claude Opus 5.5) wrote the design notes and most of the code from my design decisions, iterated with me over in-game tests (skirmishes at 70-79 and 80, a crash mid-match) and ran simplification reviews. I reviewed the changes and tested them in game.
Code Provenance / Attribution
Was any code in this PR copied or adapted from a sister / upstream project (e.g. CMaNGOS playerbots, MaNGOS, another module)?
Final Checklist
Notes for Reviewers
-DPLAYERBOTS_TESTS=ON, off by default; droppable).