Skip to content

Commit 299e439

Browse files
authored
Merge pull request mod-playerbots#2191 from mod-playerbots/test-staging
Test staging to master
2 parents 652c7a1 + 2925f24 commit 299e439

60 files changed

Lines changed: 3817 additions & 257 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/check_pr_source.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: Enforce test-staging → master
22

33
on:
44
pull_request:
5+
types: [opened, synchronize, reopened, edited]
56
branches:
67
- master
78
- test-staging

PULL_REQUEST_TEMPLATE.md

Lines changed: 69 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,103 @@
1-
# Pull Request
1+
<!--
2+
Thank you for contributing to mod-playerbots, please make sure that you...
3+
1. Submit your PR to the test-staging branch, not master.
4+
2. Read the guidelines below before submitting.
5+
3. Don't delete parts of this template.
26
3-
Describe what this change does and why it is needed...
7+
DESIGN PHILOSOPHY: We prioritize STABILITY, PERFORMANCE, AND PREDICTABILITY over behavioral realism.
48
5-
---
9+
Every action and decision executes PER BOT AND PER TRIGGER. Small increases in logic complexity scale
10+
poorly across thousands of bots and negatively affect all. We prioritize a stable system over a smarter
11+
one. Bots don't need to behave perfectly; believable behavior is the goal, not human simulation.
12+
Default behavior must be cheap in processing; expensive behavior must be opt-in.
613
7-
## Design Philosophy
14+
Before submitting, make sure your changes aligns with these principles.
15+
-->
816

9-
We prioritize **stability, performance, and predictability** over behavioral realism.
10-
Complex player-mimicking logic is intentionally limited due to its negative impact on scalability, maintainability, and
11-
long-term robustness.
17+
## Pull Request Description
18+
<!-- Describe what this change does and why it is needed -->
1219

13-
Excessive processing overhead can lead to server hiccups, increased CPU usage, and degraded performance for all
14-
participants. Because every action and
15-
decision tree is executed **per bot and per trigger**, even small increases in logic complexity can scale poorly and
16-
negatively affect both players and
17-
world (random) bots. Bots are not expected to behave perfectly, and perfect simulation of human decision-making is not a
18-
project goal. Increased behavioral
19-
realism often introduces disproportionate cost, reduced predictability, and significantly higher maintenance overhead.
2020

21-
Every additional branch of logic increases long-term responsibility. All decision paths must be tested, validated, and
22-
maintained continuously as the system evolves.
23-
If advanced or AI-intensive behavior is introduced, the **default configuration must remain the lightweight decision
24-
model**. More complex behavior should only be
25-
available as an **explicit opt-in option**, clearly documented as having a measurable performance cost.
2621

27-
Principles:
28-
29-
- **Stability before intelligence**
30-
A stable system is always preferred over a smarter one.
31-
32-
- **Performance is a shared resource**
33-
Any increase in bot cost affects all players and all bots.
34-
35-
- **Simple logic scales better than smart logic**
36-
Predictable behavior under load is more valuable than perfect decisions.
37-
38-
- **Complexity must justify itself**
39-
If a feature cannot clearly explain its cost, it should not exist.
22+
## Feature Evaluation
23+
<!--
24+
If your PR is very minimal (comment typo, wrong ID reference, etc), and it is very obvious it will not have
25+
any impact on performance, you may skip these question. If necessary, a maintainer may ask you for them later.
26+
-->
4027

41-
- **Defaults must be cheap**
42-
Expensive behavior must always be optional and clearly communicated.
28+
<!-- Please answer the following: -->
29+
- Describe the **minimum logic** required to achieve the intended behavior.
30+
- Describe the **processing cost** when this logic executes across many bots.
4331

44-
- **Bots should look reasonable, not perfect**
45-
The goal is believable behavior, not human simulation.
4632

47-
Before submitting, confirm that this change aligns with those principles.
4833

49-
---
34+
## How to Test the Changes
35+
<!--
36+
- Step-by-step instructions to test the change.
37+
- Any required setup (e.g. multiple players, number of bots, specific configuration).
38+
- Expected behavior and how to verify it.
39+
-->
5040

51-
## Feature Evaluation
5241

53-
Please answer the following:
5442

55-
- Describe the **minimum logic** required to achieve the intended behavior?
56-
- Describe the **cheapest implementation** that produces an acceptable result?
57-
- Describe the **runtime cost** when this logic executes across many bots?
43+
## Impact Assessment
44+
<!-- As a generic test, before and after measure of pmon (playerbot pmon tick) can help you here. -->
45+
- Does this change increase per-bot/per-tick processing or risk scaling poorly with thousands of bots?
46+
- [ ] No, not at all
47+
- [ ] Minimal impact (**explain below**)
48+
- [ ] Moderate impact (**explain below**)
5849

59-
---
6050

61-
## How to Test the Changes
6251

63-
- Step-by-step instructions to test the change
64-
- Any required setup (e.g. multiple players, bots, specific configuration)
65-
- Expected behavior and how to verify it
52+
- Does this change modify default bot behavior?
53+
- [ ] No
54+
- [ ] Yes (**explain why**)
6655

67-
## Complexity & Impact
6856

69-
Does this change add new decision branches?
70-
- - [ ] No
71-
- - [ ] Yes (**explain below**)
7257

73-
Does this change increase per-bot or per-tick processing?
74-
- - [ ] No
75-
- - [ ] Yes (**describe and justify impact**)
58+
- Does this change add new decision branches or increase maintenance complexity?
59+
- [ ] No
60+
- [ ] Yes (**explain below**)
7661

77-
Could this logic scale poorly under load?
78-
- - [ ] No
79-
- - [ ] Yes (**explain why**)
80-
---
8162

82-
## Defaults & Configuration
8363

84-
Does this change modify default bot behavior?
85-
- - [ ] No
86-
- - [ ] Yes (**explain why**)
64+
## Messages to Translate
65+
<!--
66+
Bot messages have to be translatable, but you don't need to do the translations here. You only need to make sure
67+
the message is in a translatable format, and list in the table the message_key and the default English message.
68+
Search for GetBotTextOrDefault in the codebase for examples.
69+
-->
70+
Does this change add bot messages to translate?
71+
- [ ] No
72+
- [ ] Yes (**list messages in the table**)
8773

88-
If this introduces more advanced or AI-heavy logic:
89-
- - [ ] Lightweight mode remains the default
90-
- - [ ] More complex behavior is optional and thereby configurable
91-
---
74+
| Message key | Default message |
75+
| --------------- | ------------------ |
76+
| | |
77+
| | |
9278

9379
## AI Assistance
94-
95-
Was AI assistance (e.g. ChatGPT or similar tools) used while working on this change?
96-
- - [ ] No
97-
- - [ ] Yes (**explain below**)
98-
80+
<!--
81+
AI assistance is allowed, but all submitted code must be fully understood, reviewed, and owned by the contributor.
82+
We expect contributors to be honest about what they do and do not understand.
83+
-->
84+
Was AI assistance used while working on this change?
85+
- [ ] No
86+
- [ ] Yes (**explain below**)
87+
<!--
9988
If yes, please specify:
89+
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code generation).
90+
- Which parts of the change were influenced or generated, and whether it was thoroughly reviewed.
91+
-->
10092

101-
- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
102-
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code generation)
103-
- Which parts of the change were influenced or generated
104-
- Whether the result was manually reviewed and adapted
10593

106-
AI assistance is allowed, but all submitted code must be fully understood, reviewed, and owned by the contributor.
107-
Any AI-influenced changes must be verified against existing CORE and PB logic. We expect contributors to be honest
108-
about what they do and do not understand.
109-
110-
---
11194

11295
## Final Checklist
11396

114-
- - [ ] Stability is not compromised
115-
- - [ ] Performance impact is understood, tested, and acceptable
116-
- - [ ] Added logic complexity is justified and explained
117-
- - [ ] Documentation updated if needed
118-
119-
---
97+
- [ ] Stability is not compromised.
98+
- [ ] Performance impact is understood, tested, and acceptable.
99+
- [ ] Added logic complexity is justified and explained.
100+
- [ ] Documentation updated if needed (Conf comments, WiKi commands).
120101

121102
## Notes for Reviewers
122-
123-
Anything that significantly improves realism at the cost of stability or performance should be carefully discussed
124-
before merging.
103+
<!-- Anything else that's helpful to review or test your pull request. -->

conf/playerbots.conf.dist

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,10 @@ AiPlayerbot.AutoGearScoreLimit = 0
566566
# Default: food, taxi, and raid are enabled
567567
AiPlayerbot.BotCheats = "food,taxi,raid"
568568

569-
# Attunement quests (comma-separated list of quest IDs)
569+
# List of attunement quests (comma-separated list of quest IDs) that are automatically completed for all bots.
570+
# While mod-playerbots does not restore removed attunement requirements, although other mods, such as mod-individual-progression, may do so.
571+
# This is meant to exclude bots from such requirements.
572+
#
570573
# Default:
571574
# Caverns of Time - Part 1
572575
# - 10279, To The Master's Lair
@@ -592,7 +595,17 @@ AiPlayerbot.BotCheats = "food,taxi,raid"
592595
#
593596
# Serpentshrine Cavern
594597
# - 10901, The Cudgel of Kar'desh
595-
AiPlayerbot.AttunementQuests = 10279,10277,10282,10283,10284,10285,10296,10297,10298,11481,11482,11488,11490,11492,10901
598+
#
599+
# The Eye
600+
# - 10888, Trial of the Naaru: Magtheridon
601+
#
602+
# Mount Hyjal
603+
# - 10445, The Vials of Eternity
604+
#
605+
# Black Temple
606+
# - 10985, A Distraction for Akama
607+
#
608+
AiPlayerbot.AttunementQuests = 10279,10277,10282,10283,10284,10285,10296,10297,10298,11481,11482,11488,11490,11492,10901,10888,10445,10985
596609

597610
#
598611
#
@@ -796,6 +809,10 @@ AiPlayerbot.LimitGearExpansion = 1
796809
# Set between 0 (0%) and 1 (100%)
797810
AiPlayerbot.RandomGearLoweringChance = 0
798811

812+
# Unobtainable or unusable items (comma-separated list of item IDs)
813+
# Default: Chilton Wand (12468), Totem of the Earthen Ring (46978)
814+
AiPlayerbot.UnobtainableItems = 12468,46978
815+
799816
# Randombots check player's gearscore level and deny the group invitation if it's too low
800817
# Default: 0 (disabled)
801818
AiPlayerbot.GearScoreCheck = 0
@@ -2213,4 +2230,4 @@ AiPlayerbot.SummonAtInnkeepersEnabled = 1
22132230
# 30% more damage, 40% damage reduction (tank bots), increased all resistances, reduced threat for non tank bots, increased threat for tank bots.
22142231
# Buffs will be applied on PP, Sindragosa and Lich King
22152232

2216-
AiPlayerbot.EnableICCBuffs = 1
2233+
AiPlayerbot.EnableICCBuffs = 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
UPDATE `ai_playerbot_texts` SET `text_loc3`='%s, du hörst den triefenden Sarkasmus in meinem text nicht' WHERE `id`=1353;

src/Ai/Base/Actions/ChatShortcutActions.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ bool MaxDpsChatShortcutAction::Execute(Event /*event*/)
237237
return true;
238238
}
239239

240+
bool NaxxChatShortcutAction::Execute(Event /*event*/)
241+
{
242+
Player* master = GetMaster();
243+
if (!master)
244+
return false;
245+
246+
botAI->Reset();
247+
botAI->ChangeStrategy("+naxx", BOT_STATE_NON_COMBAT);
248+
botAI->ChangeStrategy("+naxx", BOT_STATE_COMBAT);
249+
botAI->TellMasterNoFacing("Add Naxx Strategies!");
250+
// bot->Say("Add Naxx Strategies!", LANG_UNIVERSAL);
251+
return true;
252+
}
253+
240254
bool BwlChatShortcutAction::Execute(Event /*event*/)
241255
{
242256
Player* master = GetMaster();

src/Ai/Base/Actions/ChatShortcutActions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ class MaxDpsChatShortcutAction : public Action
8585
bool Execute(Event event) override;
8686
};
8787

88+
class NaxxChatShortcutAction : public Action
89+
{
90+
public:
91+
NaxxChatShortcutAction(PlayerbotAI* ai) : Action(ai, "naxx chat shortcut") {}
92+
virtual bool Execute(Event event);
93+
};
94+
8895
class BwlChatShortcutAction : public Action
8996
{
9097
public:

src/Ai/Base/Actions/MovementActions.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,14 +854,19 @@ float MovementAction::GetFollowAngle()
854854
if (!group)
855855
return 0.0f;
856856

857+
// Prevent bots with orphaned raid groups from dividing by 0, which freezes the server.
858+
uint32 memberCount = group->GetMembersCount();
859+
if (memberCount <= 1)
860+
return 0.0f;
861+
857862
uint32 index = 1;
858863
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
859864
{
860865
if (ref->GetSource() == master)
861866
continue;
862867

863868
if (ref->GetSource() == bot)
864-
return 2 * M_PI / (group->GetMembersCount() - 1) * index;
869+
return 2 * M_PI / (memberCount - 1) * index;
865870

866871
++index;
867872
}

src/Ai/Base/ChatActionContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ class ChatActionContext : public NamedObjectContext<Action>
187187
creators["guild leave"] = &ChatActionContext::guild_leave;
188188
creators["rtsc"] = &ChatActionContext::rtsc;
189189
creators["bwl chat shortcut"] = &ChatActionContext::bwl_chat_shortcut;
190+
creators["naxx chat shortcut"] = &ChatActionContext::naxx_chat_shortcut;
190191
creators["tell estimated dps"] = &ChatActionContext::tell_estimated_dps;
191192
creators["join"] = &ChatActionContext::join;
192193
creators["lfg"] = &ChatActionContext::lfg;
@@ -298,6 +299,7 @@ class ChatActionContext : public NamedObjectContext<Action>
298299
static Action* guild_remove(PlayerbotAI* botAI) { return new GuildRemoveAction(botAI); }
299300
static Action* guild_leave(PlayerbotAI* botAI) { return new GuildLeaveAction(botAI); }
300301
static Action* rtsc(PlayerbotAI* botAI) { return new RTSCAction(botAI); }
302+
static Action* naxx_chat_shortcut(PlayerbotAI* ai) { return new NaxxChatShortcutAction(ai); }
301303
static Action* bwl_chat_shortcut(PlayerbotAI* ai) { return new BwlChatShortcutAction(ai); }
302304
static Action* tell_estimated_dps(PlayerbotAI* ai) { return new TellEstimatedDpsAction(ai); }
303305
static Action* join(PlayerbotAI* ai) { return new JoinGroupAction(ai); }

src/Ai/Base/ChatTriggerContext.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
127127
creators["guild leave"] = &ChatTriggerContext::guild_leave;
128128
creators["rtsc"] = &ChatTriggerContext::rtsc;
129129
creators["drink"] = &ChatTriggerContext::drink;
130-
// creators["bwl"] = &ChatTriggerContext::bwl;
131130
creators["dps"] = &ChatTriggerContext::dps;
132131
creators["disperse"] = &ChatTriggerContext::disperse;
133132
creators["calc"] = &ChatTriggerContext::calc;
@@ -245,7 +244,6 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
245244
static Trigger* guild_leave(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "guild leave"); }
246245
static Trigger* rtsc(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "rtsc"); }
247246
static Trigger* drink(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "drink"); }
248-
// static Trigger* bwl(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "bwl"); }
249247
static Trigger* dps(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "dps"); }
250248
static Trigger* disperse(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "disperse"); }
251249
static Trigger* calc(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "calc"); }

src/Ai/Base/Strategy/ChatCommandHandlerStrategy.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
8383
new TriggerNode("target", { NextAction("tell target", relevance) }));
8484
triggers.push_back(
8585
new TriggerNode("ready", { NextAction("ready check", relevance) }));
86+
triggers.push_back(
87+
new TriggerNode("naxx", {NextAction("naxx chat shortcut", relevance)}));
8688
triggers.push_back(
8789
new TriggerNode("bwl", { NextAction("bwl chat shortcut", relevance) }));
8890
triggers.push_back(

0 commit comments

Comments
 (0)