From bec1ec36f70e36806c04077c2efee1eb456949cc Mon Sep 17 00:00:00 2001
From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com>
Date: Tue, 28 Apr 2026 16:56:50 +0200
Subject: [PATCH 1/3] Add RTI, Pull Control and Combat Strategy UI
---
Core/MultiBotEvery.lua | 52 ++
Locales/MultiBotAceLocale-deDE.lua | 13 +
Locales/MultiBotAceLocale-enGB.lua | 13 +
Locales/MultiBotAceLocale-enUS.lua | 13 +
Locales/MultiBotAceLocale-esES.lua | 13 +
Locales/MultiBotAceLocale-frFR.lua | 13 +
Locales/MultiBotAceLocale-koKR.lua | 13 +
Locales/MultiBotAceLocale-ruRU.lua | 13 +
Locales/MultiBotAceLocale-zhCN.lua | 13 +
README.md | 547 +++-------------------
Strategies/MultiBotDeathKnight.lua | 4 +
Strategies/MultiBotDruid.lua | 4 +
Strategies/MultiBotHunter.lua | 4 +
Strategies/MultiBotMage.lua | 4 +
Strategies/MultiBotPaladin.lua | 4 +
Strategies/MultiBotPriest.lua | 4 +
Strategies/MultiBotRogue.lua | 4 +
Strategies/MultiBotShaman.lua | 4 +
Strategies/MultiBotWarlock.lua | 6 +-
Strategies/MultiBotWarrior.lua | 4 +
UI/MultiBotMainUI.lua | 141 ++++++
docs/multibot_missing_commands_roadmap.md | 133 ++++--
22 files changed, 490 insertions(+), 529 deletions(-)
diff --git a/Core/MultiBotEvery.lua b/Core/MultiBotEvery.lua
index 6cf3d6c..eebcec9 100644
--- a/Core/MultiBotEvery.lua
+++ b/Core/MultiBotEvery.lua
@@ -331,4 +331,56 @@ MultiBot.addEvery = function(pFrame, pCombat, pNormal)
if(MultiBot.isInside(pNormal, "food")) then pFrame.getButton("Food").setEnable() end
if(MultiBot.isInside(pNormal, "loot")) then pFrame.getButton("Loot").setEnable() end
if(MultiBot.isInside(pNormal, "gather")) then pFrame.getButton("Gather").setEnable() end
+end
+
+local function sendCommonCombatStrategy(pButton, command)
+ local botName = pButton and pButton.getName and pButton.getName() or nil
+ if type(botName) ~= "string" or botName == "" then
+ return false
+ end
+
+ if MultiBot.Comm and type(MultiBot.Comm.RunCombatCommand) == "function" then
+ return MultiBot.Comm.RunCombatCommand("BOT", botName, command)
+ end
+
+ SendChatMessage(command, "WHISPER", nil, botName)
+ return true
+end
+
+local function addCommonCombatStrategyButton(pFrame, pCombat, tFrame, buttonName, y, icon, tipKey, strategyName)
+ if not pFrame or not tFrame or not tFrame.addButton then
+ return
+ end
+
+ local plusCommand = "co +" .. strategyName
+ local minusCommand = "co -" .. strategyName
+
+ local button = tFrame.addButton(
+ buttonName,
+ 0,
+ y,
+ "Interface\\Icons\\" .. icon,
+ MultiBot.L(tipKey)
+ ):setDisable()
+
+ button.doLeft = function(self)
+ if MultiBot.OnOffSwitch(self) then
+ sendCommonCombatStrategy(self, plusCommand)
+ else
+ sendCommonCombatStrategy(self, minusCommand)
+ end
+ end
+
+ if MultiBot.isInside(pCombat, strategyName) then
+ pFrame.getButton(buttonName).setEnable()
+ end
+end
+
+function MultiBot.AddCommonCombatStrategyButtons(pFrame, tFrame, pCombat, yOffset)
+ local y = tonumber(yOffset) or 0
+
+ addCommonCombatStrategyButton(pFrame, pCombat, tFrame, "AvoidAoe", y, "spell_shadow_antishadow.blp", "tips.every.strategy.avoidaoe", "avoid aoe")
+ addCommonCombatStrategyButton(pFrame, pCombat, tFrame, "SaveMana", y + 26, "spell_frost_manarecharge.blp", "tips.every.strategy.savemana", "save mana")
+ addCommonCombatStrategyButton(pFrame, pCombat, tFrame, "Threat", y + 52, "ability_warrior_challange.blp", "tips.every.strategy.threat", "threat")
+ addCommonCombatStrategyButton(pFrame, pCombat, tFrame, "Behind", y + 78, "ability_backstab.blp", "tips.every.strategy.behind", "behind")
end
\ No newline at end of file
diff --git a/Locales/MultiBotAceLocale-deDE.lua b/Locales/MultiBotAceLocale-deDE.lua
index 3997129..e11cbae 100644
--- a/Locales/MultiBotAceLocale-deDE.lua
+++ b/Locales/MultiBotAceLocale-deDE.lua
@@ -38,6 +38,19 @@ local deDEValues = {
["tips.rti.bot.action.attack.body"] = "Alle Bots mit gespeichertem persönlichem RTI-Symbol greifen ihr RTI-Ziel an.",
["tips.rti.bot.action.pull.title"] = "Pullen",
["tips.rti.bot.action.pull.body"] = "Alle Bots mit gespeichertem persönlichem RTI-Symbol pullen ihr RTI-Ziel.",
+ ["tips.main.combat"] = "Kampfstrategien",
+ ["tips.main.combat.party.avoidaoe"] = "Gruppe: Avoid AoE umschalten.",
+ ["tips.main.combat.raid.avoidaoe"] = "Raid: Avoid AoE umschalten.",
+ ["tips.main.combat.party.savemana"] = "Gruppe: Save Mana umschalten.",
+ ["tips.main.combat.raid.savemana"] = "Raid: Save Mana umschalten.",
+ ["tips.main.combat.party.threat"] = "Gruppe: Threat umschalten.",
+ ["tips.main.combat.raid.threat"] = "Raid: Threat umschalten.",
+ ["tips.main.combat.party.behind"] = "Gruppe: Behind umschalten.",
+ ["tips.main.combat.raid.behind"] = "Raid: Behind umschalten.",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "Möchtest du diesen Gegenstand WIRKLICH zerstören?\n%s",
["info.keydestroyalert"] = "Ich verkaufe keine Schlüssel.",
["info.itemsellalert"] = "Ich kann diesen Gegenstand nicht verkaufen.",
diff --git a/Locales/MultiBotAceLocale-enGB.lua b/Locales/MultiBotAceLocale-enGB.lua
index a0ac2ef..b56a3a9 100644
--- a/Locales/MultiBotAceLocale-enGB.lua
+++ b/Locales/MultiBotAceLocale-enGB.lua
@@ -38,6 +38,19 @@ local enGBValues = {
["tips.rti.bot.action.attack.body"] = "All bots with a stored personal RTI icon attack their RTI target.",
["tips.rti.bot.action.pull.title"] = "Pull",
["tips.rti.bot.action.pull.body"] = "All bots with a stored personal RTI icon pull their RTI target.",
+ ["tips.main.combat"] = "Combat strategies",
+ ["tips.main.combat.party.avoidaoe"] = "Party: toggle Avoid AoE.",
+ ["tips.main.combat.raid.avoidaoe"] = "Raid: toggle Avoid AoE.",
+ ["tips.main.combat.party.savemana"] = "Party: toggle Save Mana.",
+ ["tips.main.combat.raid.savemana"] = "Raid: toggle Save Mana.",
+ ["tips.main.combat.party.threat"] = "Party: toggle Threat.",
+ ["tips.main.combat.raid.threat"] = "Raid: toggle Threat.",
+ ["tips.main.combat.party.behind"] = "Party: toggle Behind.",
+ ["tips.main.combat.raid.behind"] = "Raid: toggle Behind.",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "Do you REALLY want to destroy this item?\n%s",
["info.keydestroyalert"] = "I will not sell Keys.",
["info.itemsellalert"] = "I cant sell this Item.",
diff --git a/Locales/MultiBotAceLocale-enUS.lua b/Locales/MultiBotAceLocale-enUS.lua
index 03a04b2..f595d59 100644
--- a/Locales/MultiBotAceLocale-enUS.lua
+++ b/Locales/MultiBotAceLocale-enUS.lua
@@ -38,6 +38,19 @@ local enUSValues = {
["tips.rti.bot.action.attack.body"] = "All bots with a stored personal RTI icon attack their RTI target.",
["tips.rti.bot.action.pull.title"] = "Pull",
["tips.rti.bot.action.pull.body"] = "All bots with a stored personal RTI icon pull their RTI target.",
+ ["tips.main.combat"] = "Combat strategies",
+ ["tips.main.combat.party.avoidaoe"] = "Party: toggle Avoid AoE.",
+ ["tips.main.combat.raid.avoidaoe"] = "Raid: toggle Avoid AoE.",
+ ["tips.main.combat.party.savemana"] = "Party: toggle Save Mana.",
+ ["tips.main.combat.raid.savemana"] = "Raid: toggle Save Mana.",
+ ["tips.main.combat.party.threat"] = "Party: toggle Threat.",
+ ["tips.main.combat.raid.threat"] = "Raid: toggle Threat.",
+ ["tips.main.combat.party.behind"] = "Party: toggle Behind.",
+ ["tips.main.combat.raid.behind"] = "Raid: toggle Behind.",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "Do you REALLY want to destroy this item?\n%s",
["info.keydestroyalert"] = "I will not sell Keys.",
["info.itemsellalert"] = "I cant sell this Item.",
diff --git a/Locales/MultiBotAceLocale-esES.lua b/Locales/MultiBotAceLocale-esES.lua
index e13239a..9a894a4 100644
--- a/Locales/MultiBotAceLocale-esES.lua
+++ b/Locales/MultiBotAceLocale-esES.lua
@@ -38,6 +38,19 @@ local esESValues = {
["tips.rti.bot.action.attack.body"] = "Todos los bots con un icono RTI personal guardado atacan su objetivo RTI.",
["tips.rti.bot.action.pull.title"] = "Pull",
["tips.rti.bot.action.pull.body"] = "Todos los bots con un icono RTI personal guardado hacen pull a su objetivo RTI.",
+ ["tips.main.combat"] = "Estrategias de combate",
+ ["tips.main.combat.party.avoidaoe"] = "Grupo: alternar Avoid AoE.",
+ ["tips.main.combat.raid.avoidaoe"] = "Banda: alternar Avoid AoE.",
+ ["tips.main.combat.party.savemana"] = "Grupo: alternar Save Mana.",
+ ["tips.main.combat.raid.savemana"] = "Banda: alternar Save Mana.",
+ ["tips.main.combat.party.threat"] = "Grupo: alternar Threat.",
+ ["tips.main.combat.raid.threat"] = "Banda: alternar Threat.",
+ ["tips.main.combat.party.behind"] = "Grupo: alternar Behind.",
+ ["tips.main.combat.raid.behind"] = "Banda: alternar Behind.",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "¿REALMENTE quieres destruir este objeto?\n%s",
["info.keydestroyalert"] = "No venderé llaves.",
["info.itemsellalert"] = "No puedo vender este objeto.",
diff --git a/Locales/MultiBotAceLocale-frFR.lua b/Locales/MultiBotAceLocale-frFR.lua
index a3b1963..21e576e 100644
--- a/Locales/MultiBotAceLocale-frFR.lua
+++ b/Locales/MultiBotAceLocale-frFR.lua
@@ -38,6 +38,19 @@ local frFRValues = {
["tips.rti.bot.action.attack.body"] = "Tous les bots avec une icône RTI personnelle mémorisée attaquent leur cible RTI.",
["tips.rti.bot.action.pull.title"] = "Pull",
["tips.rti.bot.action.pull.body"] = "Tous les bots avec une icône RTI personnelle mémorisée pull leur cible RTI.",
+ ["tips.main.combat"] = "Stratégies de combat",
+ ["tips.main.combat.party.avoidaoe"] = "Groupe : activer/désactiver Avoid AoE.",
+ ["tips.main.combat.raid.avoidaoe"] = "Raid : activer/désactiver Avoid AoE.",
+ ["tips.main.combat.party.savemana"] = "Groupe : activer/désactiver Save Mana.",
+ ["tips.main.combat.raid.savemana"] = "Raid : activer/désactiver Save Mana.",
+ ["tips.main.combat.party.threat"] = "Groupe : activer/désactiver Threat.",
+ ["tips.main.combat.raid.threat"] = "Raid : activer/désactiver Threat.",
+ ["tips.main.combat.party.behind"] = "Groupe : activer/désactiver Behind.",
+ ["tips.main.combat.raid.behind"] = "Raid : activer/désactiver Behind.",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "Voulez-vous VRAIMENT détruire cet objet ?\n%s",
["info.keydestroyalert"] = "Je ne peux pas vendre des clés.",
["info.itemsellalert"] = "Je ne peux pas vendre cet item.",
diff --git a/Locales/MultiBotAceLocale-koKR.lua b/Locales/MultiBotAceLocale-koKR.lua
index 3d5f1d9..ea7db72 100644
--- a/Locales/MultiBotAceLocale-koKR.lua
+++ b/Locales/MultiBotAceLocale-koKR.lua
@@ -38,6 +38,19 @@ local koKRValues = {
["tips.rti.bot.action.attack.body"] = "개인 RTI 아이콘이 저장된 모든 봇이 자신의 RTI 대상을 공격합니다.",
["tips.rti.bot.action.pull.title"] = "풀링",
["tips.rti.bot.action.pull.body"] = "개인 RTI 아이콘이 저장된 모든 봇이 자신의 RTI 대상을 풀링합니다.",
+ ["tips.main.combat"] = "전투 전략",
+ ["tips.main.combat.party.avoidaoe"] = "파티: Avoid AoE 전환.",
+ ["tips.main.combat.raid.avoidaoe"] = "레이드: Avoid AoE 전환.",
+ ["tips.main.combat.party.savemana"] = "파티: Save Mana 전환.",
+ ["tips.main.combat.raid.savemana"] = "레이드: Save Mana 전환.",
+ ["tips.main.combat.party.threat"] = "파티: Threat 전환.",
+ ["tips.main.combat.raid.threat"] = "레이드: Threat 전환.",
+ ["tips.main.combat.party.behind"] = "파티: Behind 전환.",
+ ["tips.main.combat.raid.behind"] = "레이드: Behind 전환.",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "이 아이템을 정말로 파기하시겠습니까?\n%s",
["info.keydestroyalert"] = "열쇠는 판매하지 않습니다.",
["info.itemsellalert"] = "이 아이템은 판매할 수 없습니다.",
diff --git a/Locales/MultiBotAceLocale-ruRU.lua b/Locales/MultiBotAceLocale-ruRU.lua
index 4b82e1b..a3f9b41 100644
--- a/Locales/MultiBotAceLocale-ruRU.lua
+++ b/Locales/MultiBotAceLocale-ruRU.lua
@@ -38,6 +38,19 @@ local ruRUValues = {
["tips.rti.bot.action.attack.body"] = "Все боты с сохранённой личной RTI-иконкой атакуют свою RTI-цель.",
["tips.rti.bot.action.pull.title"] = "Пулл",
["tips.rti.bot.action.pull.body"] = "Все боты с сохранённой личной RTI-иконкой пуллят свою RTI-цель.",
+ ["tips.main.combat"] = "Боевые стратегии",
+ ["tips.main.combat.party.avoidaoe"] = "Группа: переключить Avoid AoE.",
+ ["tips.main.combat.raid.avoidaoe"] = "Рейд: переключить Avoid AoE.",
+ ["tips.main.combat.party.savemana"] = "Группа: переключить Save Mana.",
+ ["tips.main.combat.raid.savemana"] = "Рейд: переключить Save Mana.",
+ ["tips.main.combat.party.threat"] = "Группа: переключить Threat.",
+ ["tips.main.combat.raid.threat"] = "Рейд: переключить Threat.",
+ ["tips.main.combat.party.behind"] = "Группа: переключить Behind.",
+ ["tips.main.combat.raid.behind"] = "Рейд: переключить Behind.",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "Вы ДЕЙСТВИТЕЛЬНО хотите уничтожить этот предмет?\n%s",
["info.keydestroyalert"] = "Я не продаю ключи.",
["info.itemsellalert"] = "Я не могу продать этот предмет.",
diff --git a/Locales/MultiBotAceLocale-zhCN.lua b/Locales/MultiBotAceLocale-zhCN.lua
index ea9866d..4fb7fed 100644
--- a/Locales/MultiBotAceLocale-zhCN.lua
+++ b/Locales/MultiBotAceLocale-zhCN.lua
@@ -38,6 +38,19 @@ local zhCNValues = {
["tips.rti.bot.action.attack.body"] = "所有保存了个人 RTI 图标的机器人攻击其 RTI 目标。",
["tips.rti.bot.action.pull.title"] = "拉怪",
["tips.rti.bot.action.pull.body"] = "所有保存了个人 RTI 图标的机器人拉取其 RTI 目标。",
+ ["tips.main.combat"] = "战斗策略",
+ ["tips.main.combat.party.avoidaoe"] = "小队:切换 Avoid AoE。",
+ ["tips.main.combat.raid.avoidaoe"] = "团队:切换 Avoid AoE。",
+ ["tips.main.combat.party.savemana"] = "小队:切换 Save Mana。",
+ ["tips.main.combat.raid.savemana"] = "团队:切换 Save Mana。",
+ ["tips.main.combat.party.threat"] = "小队:切换 Threat。",
+ ["tips.main.combat.raid.threat"] = "团队:切换 Threat。",
+ ["tips.main.combat.party.behind"] = "小队:切换 Behind。",
+ ["tips.main.combat.raid.behind"] = "团队:切换 Behind。",
+ ["tips.every.strategy.avoidaoe"] = "Avoid AoE",
+ ["tips.every.strategy.savemana"] = "Save Mana",
+ ["tips.every.strategy.threat"] = "Threat",
+ ["tips.every.strategy.behind"] = "Behind",
["info.itemdestroyalert"] = "你真的要销毁这个物品吗?\n%s",
["info.keydestroyalert"] = "我不会出售钥匙。",
["info.itemsellalert"] = "我无法出售该物品。",
diff --git a/README.md b/README.md
index de845e5..38102a3 100644
--- a/README.md
+++ b/README.md
@@ -1,221 +1,42 @@
-
-
-
-
-
-
-# MultiBot Chatless
-
-### Bridge-first client addon for AzerothCore `mod-playerbots`
-
-
MultiBot-Chatless is the client-side World of Warcraft 3.3.5a addon for controlling and inspecting Playerbots through a cleaner, mostly chatless UI workflow.
-
-
-
-
-
-
-
-
-
-

-

-
-
-
-
-
- | Component |
- Repository |
- Install Location |
-
-
- | Client Addon |
-
-
- MultiBot-Chatless
-
- |
-
- World of Warcraft/Interface/AddOns/MultiBot
- |
-
-
- | Server Bridge Module |
-
-
- mod-multibot-bridge
-
- |
-
- azerothcore/modules/mod-multibot-bridge
- |
-
-
-
-
+
----
-
-## Important Notice
-
-`MultiBot-Chatless` is the **addon-side repository only**.
-
-To get the new bridge-first / mostly chatless behavior, you also need the server-side AzerothCore module:
-
-
+# Breaking News
+MultiBot has been converted to a bridge-first, mostly chatless architecture.
-### 👉
mod-multibot-bridge
-
-
-
-Without the bridge module, the addon cannot use the new structured `MBOT GET~...` data flow.
-
----
+The addon now uses `mod-multibot-bridge` to request structured data from the server instead of relying on automatic legacy chat parsing for the main UI refresh paths. Roster, states, details, stats, inventory, spellbook, glyphs, outfits and related UI data are now refreshed through `MBOT GET~...` bridge requests when the bridge is available.
-# What is MultiBot Chatless?
+Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions. Commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar manual whispers still work so players can request information about a bot state when they explicitly want it.
-MultiBot is a user interface addon for the AzerothCore [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots) module.
+Outfits have also been moved to the bridge-first path. Listing, creating/updating, resetting, equipping and replacing outfit sets no longer require automatic chat parsing, and the bridge suppresses the old detailed `Equipping [item] ...` spam while keeping a single readable equip/replace confirmation.
-This fork focuses on removing automatic bot chat spam from the main UI refresh paths by using a dedicated AzerothCore bridge module instead of relying on legacy chat parsing.
+RTI, Pull Control and Combat Strategies have been added through whitelisted bridge commands. Target icon assignment, RTI attack/pull actions, pull timing, focus/assist/AoE pull presets, and selected combat strategy toggles can now be triggered from the UI without automatic chat parsing.
-The addon now requests structured data from the server through `mod-multibot-bridge`.
+Legacy automatic chat fallback is disabled by default:
-Examples of bridge requests:
-
-```text
-MBOT HELLO
-MBOT PING
-GET~ROSTER
-GET~STATES
-GET~DETAILS
-GET~STATS
-GET~INVENTORY
-GET~SPELLBOOK
-GET~GLYPHS
-GET~OUTFITS
-```
-
-Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions.
-
-Commands such as:
-
-```text
-who
-co ?
-nc ?
-ss ?
+```lua
+MultiBot.allowLegacyChatFallback = false
```
-still work when the player explicitly wants to inspect a bot state.
-
-The goal is not to remove useful manual commands.
-The goal is to remove automatic UI-refresh spam.
-
----
-
-# Features
-
-
-
- | Area |
- Status |
-
-
- | Bridge handshake |
- Implemented — HELLO, HELLO_ACK, PING, PONG |
-
-
- | Roster refresh |
- Bridge-first |
-
-
- | Bot states |
- Bridge-first |
-
-
- | Bot details |
- Bridge-first |
-
-
- | Stats |
- Bridge-first |
-
-
- | Inventory |
- Bridge-first with icons and item tooltips |
-
-
- | Spellbook |
- Bridge-first |
-
-
- | Glyphs |
- Bridge-first with glyph icons and tooltips |
-
-
- | Outfits |
- Bridge-first listing, create/update, reset, equip and replace |
-
-
- | Units / EveryBars |
- Improved login, reload and AddClass refresh behavior |
-
-
- | Legacy automatic chat fallback |
- Disabled by default |
-
-
-
----
-
-# Requirements
-
-## Client
-
-- World of Warcraft 3.3.5a / Wrath of the Lich King client.
-- Tested with:
- - English / US client
- - German client
- - French client
- - Spanish client
-
-## Server
+Set it to `true` only for temporary debugging if you need to test the old chat-based fallback behavior.
-- [`AzerothCore WotLK`](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot).
-- [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots).
-- [`mod-multibot-bridge`](https://github.com/Wishmaster117/mod-multibot-bridge).
+# MultiBot
+MultiBot is a user interface addon for the AzerothCore `mod-playerbots` module by the Playerbots team: https://github.com/mod-playerbots/mod-playerbots.
+Tested with American, German, French and Spanish 3.3.5 WotLK clients.
----
+This version also expects the companion server module `mod-multibot-bridge` to be installed if you want the new bridge-first/chatless UI behavior.
# Installation
-## 1. Install the server-side bridge module
-
-Clone the bridge module inside your AzerothCore `modules` directory:
-
-```bash
-cd /path/to/azerothcore/modules
-git clone https://github.com/Wishmaster117/mod-multibot-bridge.git mod-multibot-bridge
-```
-
-Expected structure:
+## 1. Server-side bridge module
+1. Copy the `mod-multibot-bridge` folder into your AzerothCore modules directory, next to `mod-playerbots`:
```text
-azerothcore/
-└── modules/
- └── mod-multibot-bridge/
- ├── conf/
- └── src/
+azerothcore-wotlk/modules/mod-multibot-bridge
```
-Then:
-
-1. Re-run CMake if required by your build workflow.
-2. Rebuild AzerothCore.
-3. Copy/install the generated configuration file if required.
-4. Start the server.
-5. Check that `mod-multibot-bridge` is loaded.
+2. Re-run CMake for your AzerothCore build if your workflow requires it.
+3. Rebuild the server.
+4. Start the server and check that `mod-multibot-bridge` is loaded.
When the addon connects successfully, the server console should show messages similar to:
@@ -229,149 +50,57 @@ GET~STATES
GET~DETAILS
```
----
-
-## 2. Install the client addon
-
-Clone this repository into your World of Warcraft AddOns directory.
-
-```bash
-cd "World of Warcraft/Interface/AddOns"
-git clone https://github.com/Wishmaster117/MultiBot-Chatless.git MultiBot
-```
-
-Expected structure:
+For UI actions that execute safe gameplay commands, the console may also show bridge requests such as:
```text
-World of Warcraft/
-└── Interface/
- └── AddOns/
- └── MultiBot/
- ├── MultiBot.toc
- ├── Core/
- ├── Data/
- ├── Features/
- ├── Icons/
- ├── Libs/
- ├── Locales/
- ├── Strategies/
- ├── Textures/
- └── UI/
+RUN~RTI~BOT~Sahkaal~~rti skull
+RUN~RTI~GROUP~1~~attack rti target
+RUN~COMBAT~BOT~Sahkaal~~co +focus
+RUN~COMBAT~ALL~~~co +avoid aoe
```
-> The GitHub repository is named `MultiBot-Chatless`, but the local addon folder must be named `MultiBot`.
+These commands are validated by the bridge whitelist before being routed to bots.
-Do not install it like this:
+## 2. Client-side addon
+1. Copy the addon files into a folder named `MultiBot` inside your World of Warcraft AddOns directory:
```text
-Interface/AddOns/MultiBot/MultiBot/MultiBot.toc
+World of Warcraft/Interface/AddOns/MultiBot
```
-The `.toc` file must be directly here:
+Example on Windows:
```text
-Interface/AddOns/MultiBot/MultiBot.toc
+DRIVE:\WowClientFolder\Interface\AddOns\MultiBot
```
----
-
-# Updating
-
-## Update the addon
-
-```bash
-cd "World of Warcraft/Interface/AddOns/MultiBot"
-git pull
-```
-
-## Update the bridge module
-
-```bash
-cd /path/to/azerothcore/modules/mod-multibot-bridge
-git pull
-```
-
-Then rebuild your AzerothCore server if the module code changed.
-
----
-
-# Recommended Configuration
+2. Make sure the `.toc` file is directly inside the `MultiBot` folder. The addon should not be nested inside an extra directory such as `MultiBot/MultiBot/...`.
+3. Start World of Warcraft.
+4. Enable the addon on the character selection screen if needed.
+5. Log in and use `/multibot`, `/mbot`, `/mb`, or the minimap button.
+## 3. Recommended configuration
For normal bridge-first usage, keep legacy automatic chat fallback disabled:
```lua
MultiBot.allowLegacyChatFallback = false
```
-Only enable it temporarily for debugging or compatibility testing:
+Only enable it temporarily for debugging:
```lua
MultiBot.allowLegacyChatFallback = true
```
----
-
-# Usage
-
-Start World of Warcraft and use one of the following commands:
-
-```text
-/multibot
-/mbot
-/mb
-```
-
-You can also use the minimap button.
+# Use
+Start World of Warcraft and enter `/multibot`, `/mbot`, or `/mb` in the chat, or use the minimap button.
-When the bridge is available, the addon automatically uses structured bridge messages for the main UI refresh paths instead of legacy chat replies.
+The addon will automatically try to connect to `mod-multibot-bridge`. If the bridge is connected, the main UI refresh paths use structured bridge messages instead of legacy chat replies.
-Manual commands are still available when you intentionally want them.
-
-Examples:
-
-```text
-/w BotName who
-/w BotName co ?
-/w BotName nc ?
-/w BotName ss ?
-```
-
----
-
-# Bridge-First Architecture
-
-
-
-
-
- | Old behavior |
- New behavior |
-
-
- | Addon triggers bot commands |
- Addon sends structured MBOT GET~... requests |
-
-
- | Bots answer with chat text |
- Bridge returns structured addon messages |
-
-
- | Addon parses localized chat lines |
- Addon consumes stable protocol payloads |
-
-
- | Automatic UI refresh creates chat spam |
- Main UI refresh paths are mostly chatless |
-
-
-
-
-
----
+Manual bot information commands remain available. You can still whisper/use commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar playerbot diagnostics when you explicitly want to inspect a bot state. The chatless conversion only removes the automatic UI-refresh spam; it does not remove voluntary status commands.
# Current Status
-
-Implemented bridge-first / chatless areas:
+Implemented bridge-first/chatless areas:
- Bridge handshake: `HELLO`, `HELLO_ACK`, `PING`, `PONG`.
- Roster refresh.
@@ -383,196 +112,34 @@ Implemented bridge-first / chatless areas:
- Glyph refresh with icons and glyph tooltips.
- Outfits refresh and actions through the bridge.
- Outfit equip/replace without detailed `Equipping [item] ...` chat spam.
-- Custom glyph socket mapping and apply order.
+- RTI / Target Icons through `RUN~RTI` with `BOT`, `GROUP` and `ALL` scopes.
+- Pull Control through `RUN~COMBAT`, including wait time, focus, DPS assist, DPS AoE, presets and RTI pull/attack actions.
+- Combat Strategies through `RUN~COMBAT`, including individual EveryBar toggles and Party/Raid strategy toggles for `avoid aoe`, `save mana`, `threat` and `behind`.
+- Custom Glyphs socket mapping and apply order.
- Talent tab navigation stability after switching between tabs.
- Automatic bot reconnect on login/reload for bots already present in the group or raid.
- Units bar refresh after adding a bot through AddClass.
Kept intentionally:
-- Manual whisper/playerbot commands for diagnostics.
-- Commands such as `who`, `co ?`, `nc ?`, `ss ?`.
-- Gameplay write actions that still rely on existing playerbot commands.
+- Manual whisper/playerbot commands for diagnostics, including `who`, `co ?`, `nc ?`, `ss ?` and similar state-inspection commands.
+- Manual gameplay commands for players who still want to control bots directly through whispers or party/raid chat.
+- Whitelisted bridge gameplay actions for UI buttons that do not need structured chat parsing.
- Optional legacy fallback behavior only for debugging or compatibility.
----
-
# Remaining Work
-
-The Outfits migration is complete. The next step is final stabilization and cleanup.
+The RTI, Pull Control and Combat Strategies passes are now implemented. The next step is final stabilization, followed by the next missing command block.
Planned follow-up work:
-- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs and Outfits.
+- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs, Outfits, RTI, Pull Control and Combat Strategies.
- Verify that `MultiBot.allowLegacyChatFallback = false` prevents automatic legacy refresh spam on all migrated UI paths.
-- Keep manual diagnostic commands documented and functional.
-- Remove obsolete debug prints.
-- Remove dead legacy parser paths once bridge-first behavior is fully stable.
+- Keep manual diagnostic commands documented and functional, especially `who`, `co ?`, `nc ?` and `ss ?`.
+- Keep `RUN~COMBAT` and `RUN~RTI` strictly whitelisted in the bridge; they must not become generic unrestricted command executors.
+- Remove obsolete debug prints and dead legacy parser paths once the bridge-first behavior is fully stable.
- Update screenshots and user documentation after wider testing.
+- Next command block to evaluate: `disperse set ` / `disperse disable`.
---
-# Troubleshooting
-
-
-The addon does not load
-
-Check that the folder is named exactly:
-
-```text
-Interface/AddOns/MultiBot
-```
-
-and that the `.toc` file is here:
-
-```text
-Interface/AddOns/MultiBot/MultiBot.toc
-```
-
-If the `.toc` file is inside another nested `MultiBot` folder, the addon is installed incorrectly.
-
-
-
-
-The addon loads but the bridge does not connect
-
-Check that:
-
-- `mod-multibot-bridge` is installed in the AzerothCore `modules` directory.
-- AzerothCore was rebuilt after installing the module.
-- The server was restarted after rebuilding.
-- The bridge module is visible in server logs.
-- Your client is logged into a character connected to the server.
-
-
-
-
-I still see some chat messages
-
-This project removes automatic UI-refresh spam where the bridge path has been implemented.
-
-Manual commands and gameplay actions may still produce intentional messages.
-
-Make sure this value is disabled unless you are debugging:
-
-```lua
-MultiBot.allowLegacyChatFallback = false
-```
-
-
-
-
-Inventory, spellbook, glyphs or outfits do not update
-
-Check the server console for bridge requests such as:
-
-```text
-GET~INVENTORY
-GET~SPELLBOOK
-GET~GLYPHS
-GET~OUTFITS
-```
-
-If these requests do not appear, the addon may not be connected to the bridge.
-
-
-
----
-
-# Repository Layout
-
-```text
-MultiBot-Chatless/
-├── Core/
-├── Data/
-├── Features/
-├── Icons/
-├── Libs/
-├── Locales/
-├── Strategies/
-├── Textures/
-├── UI/
-├── docs/
-└── MultiBot.toc
-```
-
----
-
-# Related Repositories
-
-
-
----
-
-# Credits
-
-MultiBot is built for use with AzerothCore `mod-playerbots`.
-
-Thanks to Macx-Lio for the original MultiBot Module.
-
-Thanks to the Playerbots team and the AzerothCore community.
-
----
-
-
+# Detailed Notice
diff --git a/Strategies/MultiBotDeathKnight.lua b/Strategies/MultiBotDeathKnight.lua
index 79c83dc..660f125 100644
--- a/Strategies/MultiBotDeathKnight.lua
+++ b/Strategies/MultiBotDeathKnight.lua
@@ -91,6 +91,10 @@ MultiBot.addDeathKnight = function(pFrame, pCombat, pNormal)
end
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, tDpsFrame, pCombat, 104)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -60, 0, "ability_warrior_innerrage", MultiBot.L("tips.deathknight.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotDruid.lua b/Strategies/MultiBotDruid.lua
index 733cc32..bee9517 100644
--- a/Strategies/MultiBotDruid.lua
+++ b/Strategies/MultiBotDruid.lua
@@ -163,6 +163,10 @@ MultiBot.addDruid = function(pFrame, pCombat, pNormal)
end
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, tDpsFrame, pCombat, 156)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -120, 0, "ability_warrior_innerrage", MultiBot.L("tips.druid.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotHunter.lua b/Strategies/MultiBotHunter.lua
index 190bbf9..aa76124 100644
--- a/Strategies/MultiBotHunter.lua
+++ b/Strategies/MultiBotHunter.lua
@@ -162,6 +162,10 @@ MultiBot.addHunter = function(pFrame, pCombat, pNormal)
MultiBot.OnOffActionToTarget(pButton, "co +trap weave,?", "co -trap weave,?", pButton.getName())
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, dpsFrame, pCombat, 130)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -90, 0, "ability_warrior_innerrage", MultiBot.L("tips.hunter.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotMage.lua b/Strategies/MultiBotMage.lua
index d0255fe..30302cc 100644
--- a/Strategies/MultiBotMage.lua
+++ b/Strategies/MultiBotMage.lua
@@ -141,6 +141,10 @@ MultiBot.addMage = function(pFrame, pCombat, pNormal)
end
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, dpsControlFrame, pCombat, 52)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -90, 0, "ability_warrior_innerrage", MultiBot.L("tips.mage.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotPaladin.lua b/Strategies/MultiBotPaladin.lua
index ca9a2ef..b59f244 100644
--- a/Strategies/MultiBotPaladin.lua
+++ b/Strategies/MultiBotPaladin.lua
@@ -322,6 +322,10 @@ MultiBot.addPaladin = function(pFrame, pCombat, pNormal)
end
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, dpsFrame, pCombat, 130)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -150, 0, "ability_warrior_innerrage", MultiBot.L("tips.paladin.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotPriest.lua b/Strategies/MultiBotPriest.lua
index ed326e6..30e442f 100644
--- a/Strategies/MultiBotPriest.lua
+++ b/Strategies/MultiBotPriest.lua
@@ -118,6 +118,10 @@ MultiBot.addPriest = function(pFrame, pCombat, pNormal)
end
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, dpsControlFrame, pCombat, 104)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -120, 0, "ability_warrior_innerrage", MultiBot.L("tips.priest.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotRogue.lua b/Strategies/MultiBotRogue.lua
index 8621c2b..d08d4ae 100644
--- a/Strategies/MultiBotRogue.lua
+++ b/Strategies/MultiBotRogue.lua
@@ -52,6 +52,10 @@ MultiBot.addRogue = function(pFrame, pCombat, pNormal)
MultiBot.OnOffActionToTarget(pButton, "co +boost,?", "co -boost,?", pButton.getName())
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, tFrame, pCombat, 156)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -30, 0, "ability_warrior_innerrage", MultiBot.L("tips.rogue.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotShaman.lua b/Strategies/MultiBotShaman.lua
index 9d5cadc..3ff453c 100644
--- a/Strategies/MultiBotShaman.lua
+++ b/Strategies/MultiBotShaman.lua
@@ -194,6 +194,10 @@ MultiBot.addShaman = function(pFrame, pCombat, pNormal)
end
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, dpsControlFrame, pCombat, 78)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -150, 0, "ability_warrior_innerrage", MultiBot.L("tips.shaman.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotWarlock.lua b/Strategies/MultiBotWarlock.lua
index c159919..61b7977 100644
--- a/Strategies/MultiBotWarlock.lua
+++ b/Strategies/MultiBotWarlock.lua
@@ -400,7 +400,7 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal)
-- META MELEE (Démonologie) --
local btnMeta = tFrame.addButton(
- "MetaMelee", 0, 104, "Spell_Shadow_DemonForm",
+ "MetaMelee", 0, 105, "Spell_Shadow_DemonForm",
(MultiBot.L("tips.warlock.dps.metamelee") ~= "tips.warlock.dps.metamelee" and MultiBot.L("tips.warlock.dps.metamelee") or "Meta Melee")
)
btnMeta.setDisable()
@@ -409,6 +409,10 @@ MultiBot.addWarlock = function(pFrame, pCombat, pNormal)
MultiBot.OnOffActionToTarget(pButton, "co +meta melee,?", "co -meta melee,?", pButton.getName())
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, tFrame, pCombat, 131)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -60, 0, "ability_warrior_innerrage", MultiBot.L("tips.warlock.tankAssist")).setDisable()
diff --git a/Strategies/MultiBotWarrior.lua b/Strategies/MultiBotWarrior.lua
index 4cb13c0..1ef87f3 100644
--- a/Strategies/MultiBotWarrior.lua
+++ b/Strategies/MultiBotWarrior.lua
@@ -23,6 +23,10 @@ MultiBot.addWarrior = function(pFrame, pCombat, pNormal)
end
end
+ if MultiBot.AddCommonCombatStrategyButtons then
+ MultiBot.AddCommonCombatStrategyButtons(pFrame, tFrame, pCombat, 52)
+ end
+
-- ASSIST --
pFrame.addButton("TankAssist", -30, 0, "ability_warrior_innerrage", MultiBot.L("tips.warrior.tankAssist")).setDisable()
diff --git a/UI/MultiBotMainUI.lua b/UI/MultiBotMainUI.lua
index d613cce..d06c3a8 100644
--- a/UI/MultiBotMainUI.lua
+++ b/UI/MultiBotMainUI.lua
@@ -718,6 +718,143 @@ local function createPullControlFrame(mainFrame, pullButton)
return frame
end
+local function sendMainCombatStrategy(scope, strategyName, enabled)
+ local command = "co " .. (enabled and "+" or "-") .. strategyName
+
+ if MultiBot.Comm and type(MultiBot.Comm.RunCombatCommand) == "function" then
+ return MultiBot.Comm.RunCombatCommand(scope, "", command)
+ end
+
+ if scope == "ALL" then
+ SendChatMessage(command, GetNumRaidMembers() > 0 and "RAID" or "PARTY")
+ else
+ SendChatMessage(command, "PARTY")
+ end
+
+ return true
+end
+
+local function showMainCombatStrategyTooltip(owner)
+ if not owner or not GameTooltip then
+ return
+ end
+
+ GameTooltip:SetOwner(owner, "ANCHOR_RIGHT")
+ GameTooltip:SetText(owner._mbTip or "", 1, 1, 1, true)
+ GameTooltip:Show()
+end
+
+local function hideMainCombatStrategyTooltip()
+ if GameTooltip then
+ GameTooltip:Hide()
+ end
+end
+
+local function addMainCombatStrategyButton(frame, name, x, y, icon, tipKey, scope, strategyName)
+ if not frame then
+ return nil
+ end
+
+ local button = CreateFrame("Button", "MultiBot" .. name, frame)
+ button:SetSize(28, 28)
+ button:SetPoint("TOPLEFT", frame, "TOPLEFT", x, y)
+ button:RegisterForClicks("LeftButtonDown")
+ button:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square", "ADD")
+ button:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress")
+ button._mbTip = MultiBot.L(tipKey)
+ button._mbScope = scope
+ button._mbStrategyName = strategyName
+
+ button.icon = button:CreateTexture(nil, "BACKGROUND")
+ button.icon:SetTexture(MultiBot.SafeTexturePath("Interface\\Icons\\" .. icon))
+ button.icon:SetAllPoints(button)
+
+ button.border = button:CreateTexture(nil, "ARTWORK")
+ button.border:SetTexture("Interface\\AddOns\\MultiBot\\Icons\\border.blp")
+ button.border:SetPoint("CENTER", button, "CENTER", 0, 0)
+ button.border:SetSize(34, 34)
+ button.border:Hide()
+
+ button:SetScript("OnEnter", showMainCombatStrategyTooltip)
+ button:SetScript("OnLeave", hideMainCombatStrategyTooltip)
+ button:SetScript("OnClick", function(self)
+ local enabled = not self.state
+ if sendMainCombatStrategy(self._mbScope, self._mbStrategyName, enabled) then
+ setPullControlButtonState(self, enabled)
+ end
+ end)
+
+ setPullControlButtonState(button, false)
+
+ frame.buttons = frame.buttons or {}
+ frame.buttons[name] = button
+ return button
+end
+
+local function createCombatStrategiesHeader(frame, text, x)
+ local label = frame:CreateFontString(nil, "ARTWORK")
+ label:SetFont("Fonts\\ARIALN.ttf", 10, "OUTLINE")
+ label:SetPoint("TOPLEFT", frame, "TOPLEFT", x, -8)
+ label:SetWidth(34)
+ label:SetJustifyH("CENTER")
+ label:SetText(text)
+ return label
+end
+
+local function createCombatStrategiesButton(mainFrame)
+ local controlFrame = CreateFrame("Frame", "MultiBotCombatStrategiesControl", mainFrame)
+ controlFrame:SetSize(92, 138)
+ controlFrame:SetFrameLevel((mainFrame:GetFrameLevel() or 0) + 20)
+ controlFrame:EnableMouse(true)
+ controlFrame._mbDropdownManaged = true
+ controlFrame:Hide()
+
+ controlFrame.bg = controlFrame:CreateTexture(nil, "BACKGROUND")
+ controlFrame.bg:SetTexture("Interface\\Buttons\\WHITE8X8")
+ controlFrame.bg:SetAllPoints(controlFrame)
+ controlFrame.bg:SetVertexColor(0, 0, 0, 0.78)
+
+ controlFrame.edge = CreateFrame("Frame", nil, controlFrame)
+ controlFrame.edge:SetPoint("TOPLEFT", controlFrame, "TOPLEFT", -1, 1)
+ controlFrame.edge:SetPoint("BOTTOMRIGHT", controlFrame, "BOTTOMRIGHT", 1, -1)
+ controlFrame.edge:SetBackdrop({
+ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+ edgeSize = 12,
+ })
+ controlFrame.edge:SetBackdropBorderColor(0.85, 0.85, 0.85, 0.85)
+
+ createCombatStrategiesHeader(controlFrame, "Party", 10)
+ createCombatStrategiesHeader(controlFrame, "Raid", 50)
+
+ addMainCombatStrategyButton(controlFrame, "CombatPartyAvoidAoe", 12, -26, "spell_shadow_antishadow", "tips.main.combat.party.avoidaoe", "GROUP", "avoid aoe")
+ addMainCombatStrategyButton(controlFrame, "CombatRaidAvoidAoe", 52, -26, "spell_shadow_antishadow.blp", "tips.main.combat.raid.avoidaoe", "ALL", "avoid aoe")
+ addMainCombatStrategyButton(controlFrame, "CombatPartySaveMana", 12, -54, "spell_frost_manarecharge.blp", "tips.main.combat.party.savemana", "GROUP", "save mana")
+ addMainCombatStrategyButton(controlFrame, "CombatRaidSaveMana", 52, -54, "spell_frost_manarecharge.blp", "tips.main.combat.raid.savemana", "ALL", "save mana")
+ addMainCombatStrategyButton(controlFrame, "CombatPartyThreat", 12, -82, "ability_warrior_challange.blp", "tips.main.combat.party.threat", "GROUP", "threat")
+ addMainCombatStrategyButton(controlFrame, "CombatRaidThreat", 52, -82, "ability_warrior_challange.blp", "tips.main.combat.raid.threat", "ALL", "threat")
+ addMainCombatStrategyButton(controlFrame, "CombatPartyBehind", 12, -110, "ability_backstab.blp", "tips.main.combat.party.behind", "GROUP", "behind")
+ addMainCombatStrategyButton(controlFrame, "CombatRaidBehind", 52, -110, "ability_backstab.blp", "tips.main.combat.raid.behind", "ALL", "behind")
+
+ return createMainActionButton(mainFrame, {
+ name = "CombatStrategies",
+ y = 340,
+ icon = "ability_warrior_battleshout",
+ tip = "tips.main.combat",
+ doLeft = function(button)
+ if controlFrame:IsShown() then
+ controlFrame:Hide()
+ button:setDisable()
+ return
+ end
+
+ controlFrame:ClearAllPoints()
+ controlFrame:SetPoint("RIGHT", button, "LEFT", -6, 0)
+ controlFrame:Show()
+ button:setEnable()
+ end,
+ })
+end
+
local function saveMultiBarPosition()
local multiBar = MultiBot.frames and MultiBot.frames["MultiBar"]
if not multiBar or not MultiBot.SetSavedLayoutValue or not MultiBot.toPoint then
@@ -1086,6 +1223,7 @@ function MultiBot.InitializeMainUI(tMultiBar)
"Release",
"Stats",
"Reward",
+ "CombatStrategies",
"PullControl",
"Reset",
"Actions",
@@ -1255,6 +1393,9 @@ function MultiBot.InitializeMainUI(tMultiBar)
local rewardButton = createRewardButton(mainFrame)
wireShiftRightSwap(rewardButton, "Reward")
+
+ local combatStrategiesButton = createCombatStrategiesButton(mainFrame)
+ wireShiftRightSwap(combatStrategiesButton, "CombatStrategies")
local pullControlButton = createMainActionButton(mainFrame, {
name = "PullControl",
diff --git a/docs/multibot_missing_commands_roadmap.md b/docs/multibot_missing_commands_roadmap.md
index 68c6570..79ae027 100644
--- a/docs/multibot_missing_commands_roadmap.md
+++ b/docs/multibot_missing_commands_roadmap.md
@@ -9,7 +9,7 @@ Ce document suit les commandes `mod-playerbots` encore intéressantes à intégr
- les commandes serveur/admin à ne pas intégrer dans l'addon ;
- les priorités d'intégration bridge-first/chatless.
-Le principe reste le même que pour Inventory, Spellbook, Glyphs, Talents, Stats, Quests, Outfits, RTI et Pull Control :
+Le principe reste le même que pour Inventory, Spellbook, Glyphs, Talents, Stats, Quests, Outfits, RTI, Pull Control et Combat Strategies :
**éviter le spam chat automatique**, utiliser le bridge quand c'est possible, et conserver les commandes manuelles utiles comme `who`, `co ?`, `nc ?`, `ss ?`.
---
@@ -31,10 +31,13 @@ Le principe reste le même que pour Inventory, Spellbook, Glyphs, Talents, Stats
| Outfits | Fait | Endpoint bridge + commandes outfits intégrées. |
| RTI / Target Icons | Fait | UI complète + bridge `RUN~RTI`, scopes `ALL`, `GROUP`, `BOT`. |
| Pull Control | Fait / à fignoler | Mini-frame MainBar + bridge `RUN~COMBAT`, séquences de commandes, scopes et presets. |
+| Combat Strategies | Fait / à tester large | Toggles individuels dans les EveryBars + mini-frame Party/Raid, via `RUN~COMBAT`. |
---
-## Dernier lot terminé : Pull Control
+## Derniers lots terminés : Pull Control + Combat Strategies
+
+### Pull Control
Le panneau `Pull Control` a été ajouté comme mini-frame ouverte depuis la MainBar. Il utilise le bridge et ne repose pas sur le parsing chat automatique.
@@ -71,11 +74,35 @@ Fonctionnalités terminées :
- vérification de chaque preset en conditions réelles donjon/raid ;
- éventuelle sauvegarde persistante du dernier scope et de la dernière valeur de wait.
+### Combat Strategies
+
+Le bloc `Combat Strategies` a été ajouté pour les stratégies permanentes ou semi-permanentes qui ne sont pas strictement liées au pull.
+
+Fonctionnalités terminées :
+
+- les stratégies déjà couvertes par des boutons dédiés n'ont pas été dupliquées inutilement ;
+- les nouvelles stratégies ajoutées sont :
+ - `co +avoid aoe` / `co -avoid aoe` ;
+ - `co +save mana` / `co -save mana` ;
+ - `co +threat` / `co -threat` ;
+ - `co +behind` / `co -behind` ;
+- côté individuel, les toggles sont ajoutés dans le menu/mini-frame déjà lié au bouton `Strategies DPS` de chaque EveryBar ;
+- côté groupe/raid, une mini-frame séparée depuis la MainBar permet d'appliquer les mêmes toggles en scope `GROUP` ou `ALL` ;
+- le bridge accepte maintenant ces commandes dans la whitelist `RUN~COMBAT` ;
+- les commandes sont routées sans parsing automatique du retour `co ?`.
+
+Choix volontaire :
+
+- `co +tank face` / `co -tank face` n'a pas été ajouté ici, car le comportement tank a déjà des boutons dédiés dans les EveryBars ;
+- `co +healer dps` / `co -healer dps` n'a pas été ajouté ici, car un contrôle dédié existe déjà côté EveryBar ;
+- `co +boost` / `co -boost` n'a pas été ajouté ici, car `Boost` est déjà exposé ailleurs.
+
Notes fonctionnelles importantes :
- Les commandes `co ?`, `nc ?`, `ss ?` restent manuelles et ne doivent pas devenir une source de parsing automatique.
-- Le fait qu'une stratégie apparaisse ou non dans `co ?` dépend du nom exact réellement reconnu côté playerbots. Pour le Pull Control, on garde les noms qui ont été validés via bridge/serveur.
+- Le fait qu'une stratégie apparaisse ou non dans `co ?` dépend du nom exact réellement reconnu côté playerbots.
- `wait for attack time X` n'est pas une stratégie `co`, donc il ne faut pas attendre qu'elle apparaisse forcément dans `co ?`.
+- Pour les nouvelles stratégies, le test principal est le comportement réel du bot et la présence d'un `COMBAT_ACK` côté bridge, pas uniquement l'affichage dans `co ?`.
---
@@ -139,7 +166,7 @@ RUN~RTI~BOT~Dollu~~attack rti target
- Le reset remet l'icône par défaut.
- `Attack` / `Pull` déclenchent les groupes configurés ou tous les bots selon le scope.
-#### Everybar de bot
+#### EveryBar de bot
```text
[RTI bot]
@@ -148,19 +175,21 @@ RUN~RTI~BOT~Dollu~~attack rti target
- Chaque bot peut recevoir son RTI personnel.
- Le choix est mémorisé visuellement pendant l'ouverture/fermeture des Units.
-- Le bouton batch de la main bar permet d'envoyer tous les bots personnels en même temps.
+- Le bouton batch de la MainBar permet d'envoyer tous les bots personnels en même temps.
-#### Main bar
+#### MainBar
```text
-[Bot RTI Action] [Pull Control] [Attaque Tank]
+[Bot RTI Action] [Pull Control] [Combat Strategies] [Attaque Tank]
└─ Bot RTI Action : Attaquer / Pull pour les bots ayant une RTI personnelle
└─ Pull Control : mini-frame de pull, wait, focus, assist, AoE et actions RTI
+ └─ Combat Strategies : mini-frame Party/Raid pour stratégies combat avancées
```
- `Attaquer` envoie `attack rti target` à tous les bots ayant une RTI personnelle mémorisée.
- `Pull` envoie `pull rti target` à tous les bots ayant une RTI personnelle mémorisée.
- `Pull Control` permet d'envoyer les mêmes actions RTI avec un scope choisi.
+- `Combat Strategies` permet d'appliquer les stratégies avancées au groupe ou au raid.
---
@@ -217,55 +246,77 @@ RUN~COMBAT~GROUP~~~wait for attack time 3
### Statut
-**Prochaine étape logique.**
+**Terminé côté MultiBot + bridge, à tester en conditions réelles.**
-Pull Control a posé la base technique : l'addon sait maintenant envoyer des commandes combat simples via `RUN~COMBAT`. La suite naturelle est donc d'exposer les stratégies combat utiles qui ne sont pas strictement liées au pull.
+Pull Control a posé la base technique avec `RUN~COMBAT`. Cette étape a été utilisée pour exposer les stratégies combat utiles qui ne sont pas strictement liées au pull.
### Pourquoi
-Ces stratégies existent côté playerbots mais ne sont pas toutes exposées clairement dans MultiBot. Elles ont une vraie utilité en raid/donjon, mais ne doivent pas encombrer la MainBar.
+Ces stratégies existent côté playerbots mais n'étaient pas toutes exposées clairement dans MultiBot. Elles ont une vraie utilité en raid/donjon, mais ne doivent pas encombrer la MainBar.
-### Commandes à couvrir
+### Commandes couvertes
| Stratégie | Commande | Statut MultiBot | Priorité | Intérêt |
|---|---|---:|---:|---|
-| Avoid AoE | `co +avoid aoe` / `co -avoid aoe` | À vérifier / probablement partiel | Haute | Évite les AoE dangereuses |
-| Save Mana | `co +save mana` / `co -save mana` | Manquant | Haute | Gestion mana healers/casters |
-| Threat | `co +threat` / `co -threat` | Manquant | Haute | Limite la prise d'aggro selon comportement playerbots |
-| Tank Face | `co +tank face` / `co -tank face` | Manquant | Moyenne | Gestion orientation tank, cleaves, breaths |
-| Behind | `co +behind` / `co -behind` | Manquant ou déjà visible selon states | Moyenne | Placement melee derrière la cible |
-| Healer DPS | `co +healer dps` / `co -healer dps` | À vérifier | Moyenne | Autorise/interdit le DPS des healers |
-| Boost | `co +boost` / `co -boost` | Probablement partiel | Moyenne | Burst cooldowns |
+| Avoid AoE | `co +avoid aoe` / `co -avoid aoe` | Fait | Haute | Évite les AoE dangereuses |
+| Save Mana | `co +save mana` / `co -save mana` | Fait | Haute | Gestion mana healers/casters |
+| Threat | `co +threat` / `co -threat` | Fait | Haute | Limite la prise d'aggro selon comportement playerbots |
+| Behind | `co +behind` / `co -behind` | Fait | Moyenne | Placement melee derrière la cible |
+| Tank Face | `co +tank face` / `co -tank face` | Non ajouté volontairement | Moyenne | Déjà couvert par boutons dédiés EveryBar |
+| Healer DPS | `co +healer dps` / `co -healer dps` | Non ajouté volontairement | Moyenne | Déjà couvert par boutons dédiés EveryBar |
+| Boost | `co +boost` / `co -boost` | Non ajouté volontairement | Moyenne | Déjà exposé ailleurs |
| Focus | `co +focus` / `co -focus` | Fait via Pull Control | Référence | Focus mono-cible |
| DPS Assist | `co +dps assist` / `co -dps assist` | Fait via Pull Control | Référence | Assist DPS |
| DPS AoE | `co +dps aoe` / `co -dps aoe` | Fait via Pull Control | Référence | Autorise AoE DPS |
| Wait for attack | `wait for attack time X` | Fait via Pull Control | Référence | Pull contrôlé |
-### Proposition UI
+### UX actuelle
-Créer une page ou mini-frame `Advanced Combat`, séparée de Pull Control :
+#### EveryBar / bot individuel
+
+Les stratégies individuelles sont ajoutées au menu existant `Strategies DPS` de chaque bot.
```text
-Combat Strategies
-├─ Scope: Selected / Party / Raid
-├─ Survivability: Avoid AoE, Threat
-├─ Positioning: Behind, Tank Face
-├─ Resource: Save Mana
-├─ Damage policy: Healer DPS, Boost
-└─ Apply toggles via RUN~COMBAT
+EveryBar bot
+└─ Strategies DPS
+ ├─ Avoid AoE
+ ├─ Save Mana
+ ├─ Threat
+ └─ Behind
```
-Recommandation UX :
+Ce choix évite d'ajouter une mini-frame globale pour du fine-tuning individuel : chaque bot reste configurable depuis sa propre barre.
+
+#### MainBar / groupe et raid
+
+Une mini-frame séparée sert uniquement aux scopes collectifs.
+
+```text
+MainBar
+└─ Combat Strategies
+ ├─ Scope: Party / Raid
+ ├─ Avoid AoE
+ ├─ Save Mana
+ ├─ Threat
+ └─ Behind
+```
+
+Recommandation UX conservée :
- ne pas ajouter ces toggles directement sur la MainBar ;
-- créer un panneau repliable ou une sous-page accessible depuis un bouton existant de stratégies/combat ;
-- réutiliser les scopes `BOT`, `GROUP`, `ALL` déjà validés par Pull Control ;
+- garder les actions individuelles dans les EveryBars ;
+- garder la frame MainBar pour les actions Party/Raid ;
+- réutiliser les scopes `GROUP` et `ALL` déjà validés par Pull Control ;
- garder `co ?` comme vérification manuelle, sans parser automatiquement son retour.
---
## Priorité 4 - Disperse
+### Statut
+
+**Prochaine étape logique.**
+
### Pourquoi
Très utile pour les mécaniques AoE ou les combats où les bots doivent s'espacer.
@@ -288,7 +339,7 @@ Disperse distance: [ 8 ] yards
### Note
-À faire après `Advanced Combat`, sauf si un besoin immédiat de mécaniques AoE impose de le passer avant.
+À faire après stabilisation RTI/Pull Control/Combat Strategies, sauf si un autre besoin gameplay devient prioritaire.
---
@@ -296,7 +347,7 @@ Disperse distance: [ 8 ] yards
### Pourquoi
-Le contrôle du loot est utile, mais moins prioritaire que RTI/pull/combat.
+Le contrôle du loot est utile, mais moins prioritaire que RTI/pull/combat/disperse.
### Commandes à couvrir
@@ -445,8 +496,8 @@ Ces commandes sont plutôt serveur/admin/debug ou trop dangereuses pour une UI u
|---:|---|---|---:|---:|
| 1 | RTI bridge-first | UI + bridge command | Haute | Fait |
| 2 | Pull Control avancé | Nouvelle UI + séquences commandes | Haute | Fait / à fignoler |
-| 3 | Advanced Combat Strategies | UI toggles réutilisant `RUN~COMBAT` | Haute/Moyenne | Prochaine étape |
-| 4 | Disperse | Petite UI + commande combat/mouvement | Moyenne | À faire |
+| 3 | Advanced Combat Strategies | EveryBars + mini-frame Party/Raid via `RUN~COMBAT` | Haute/Moyenne | Fait / à tester |
+| 4 | Disperse | Petite UI + commande combat/mouvement | Moyenne | Prochaine étape |
| 5 | Loot Rules | Petite UI profils | Moyenne | À faire |
| 6 | Trainer / Maintenance extras | UI maintenance | Moyenne/Basse | À faire |
| 7 | Items avancés | Extensions inventaire | Basse/Moyenne | À faire |
@@ -462,15 +513,21 @@ Ces commandes sont plutôt serveur/admin/debug ou trop dangereuses pour une UI u
- Pour les commandes qui doivent alimenter une frame, préférer un endpoint structuré dédié.
- Les commandes serveur/admin ne doivent pas être exposées dans l'addon utilisateur.
- Les boutons ajoutés dans les barres doivent conserver une position cohérente avec `MultiBotLeftCoreUI.lua` et la position par défaut de `MultiBar` dans `MultiBotInit.lua` / reset dans `MultiBotMainUI.lua`.
-- Les tooltips nouvellement ajoutés doivent passer par AceLocale, comme les tooltips RTI et Pull Control.
+- Les tooltips nouvellement ajoutés doivent passer par AceLocale, comme les tooltips RTI, Pull Control et Combat Strategies.
- `RUN~COMBAT` doit rester whitelisté côté bridge : ne pas en faire un exécuteur libre de n'importe quelle commande chat.
+- Éviter les doublons UI : si une stratégie dispose déjà d'un bouton EveryBar dédié, ne pas la rajouter dans une nouvelle frame sauf besoin UX clairement identifié.
---
## Point logique suivant
-Le prochain bloc logique est **Advanced Combat Strategies**.
+Le prochain bloc logique est **Disperse**.
+
+Raison : les blocs RTI, Pull Control et Combat Strategies couvrent maintenant le ciblage, le pull et les stratégies combat de base. `Disperse` complète naturellement ce trio en ajoutant un contrôle de positionnement collectif très utile contre les AoE et les mécaniques de donjon/raid.
-Raison : `RUN~COMBAT` existe maintenant, les scopes sont validés, et Pull Control a déjà prouvé que l'addon peut envoyer proprement des toggles de stratégie sans spam chat. Le plus rentable est donc d'ajouter une UI dédiée aux stratégies combat permanentes ou semi-permanentes : `avoid aoe`, `save mana`, `threat`, `behind`, `tank face`, `healer dps`, `boost`.
+Proposition de prochaine itération :
-Ce bloc doit rester séparé de Pull Control : Pull Control sert aux séquences de pull, tandis qu'Advanced Combat sert aux comportements généraux des bots pendant les combats.
+- vérifier d'abord la syntaxe exacte supportée par playerbots : `disperse set ` et `disperse disable` ;
+- décider si l'action doit passer par `RUN~COMBAT` ou par un endpoint plus neutre, par exemple `RUN~MOVE` / `RUN~POSITION` si on veut garder `RUN~COMBAT` réservé aux stratégies combat ;
+- ajouter une mini-frame simple avec distance configurable et bouton disable ;
+- garder le fonctionnement chatless, sans parsing automatique de réponse.
From 40ca9ca64481a099c44819f42da43299fe5970e9 Mon Sep 17 00:00:00 2001
From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com>
Date: Tue, 28 Apr 2026 16:59:40 +0200
Subject: [PATCH 2/3] Update README.md
---
README.md | 547 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 490 insertions(+), 57 deletions(-)
diff --git a/README.md b/README.md
index 38102a3..de845e5 100644
--- a/README.md
+++ b/README.md
@@ -1,42 +1,221 @@
-
+
+
+
+
+
+
+# MultiBot Chatless
+
+### Bridge-first client addon for AzerothCore `mod-playerbots`
+
+
MultiBot-Chatless is the client-side World of Warcraft 3.3.5a addon for controlling and inspecting Playerbots through a cleaner, mostly chatless UI workflow.
+
+
+
+
+
+
+
+
+
+

+

+
+
+
+
+
+ | Component |
+ Repository |
+ Install Location |
+
+
+ | Client Addon |
+
+
+ MultiBot-Chatless
+
+ |
+
+ World of Warcraft/Interface/AddOns/MultiBot
+ |
+
+
+ | Server Bridge Module |
+
+
+ mod-multibot-bridge
+
+ |
+
+ azerothcore/modules/mod-multibot-bridge
+ |
+
+
+
+
-# Breaking News
-MultiBot has been converted to a bridge-first, mostly chatless architecture.
+---
-The addon now uses `mod-multibot-bridge` to request structured data from the server instead of relying on automatic legacy chat parsing for the main UI refresh paths. Roster, states, details, stats, inventory, spellbook, glyphs, outfits and related UI data are now refreshed through `MBOT GET~...` bridge requests when the bridge is available.
+## Important Notice
-Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions. Commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar manual whispers still work so players can request information about a bot state when they explicitly want it.
+`MultiBot-Chatless` is the **addon-side repository only**.
-Outfits have also been moved to the bridge-first path. Listing, creating/updating, resetting, equipping and replacing outfit sets no longer require automatic chat parsing, and the bridge suppresses the old detailed `Equipping [item] ...` spam while keeping a single readable equip/replace confirmation.
+To get the new bridge-first / mostly chatless behavior, you also need the server-side AzerothCore module:
-RTI, Pull Control and Combat Strategies have been added through whitelisted bridge commands. Target icon assignment, RTI attack/pull actions, pull timing, focus/assist/AoE pull presets, and selected combat strategy toggles can now be triggered from the UI without automatic chat parsing.
+
-Legacy automatic chat fallback is disabled by default:
+### 👉
mod-multibot-bridge
-```lua
-MultiBot.allowLegacyChatFallback = false
+
+
+Without the bridge module, the addon cannot use the new structured `MBOT GET~...` data flow.
+
+---
+
+# What is MultiBot Chatless?
+
+MultiBot is a user interface addon for the AzerothCore [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots) module.
+
+This fork focuses on removing automatic bot chat spam from the main UI refresh paths by using a dedicated AzerothCore bridge module instead of relying on legacy chat parsing.
+
+The addon now requests structured data from the server through `mod-multibot-bridge`.
+
+Examples of bridge requests:
+
+```text
+MBOT HELLO
+MBOT PING
+GET~ROSTER
+GET~STATES
+GET~DETAILS
+GET~STATS
+GET~INVENTORY
+GET~SPELLBOOK
+GET~GLYPHS
+GET~OUTFITS
+```
+
+Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions.
+
+Commands such as:
+
+```text
+who
+co ?
+nc ?
+ss ?
```
-Set it to `true` only for temporary debugging if you need to test the old chat-based fallback behavior.
+still work when the player explicitly wants to inspect a bot state.
+
+The goal is not to remove useful manual commands.
+The goal is to remove automatic UI-refresh spam.
+
+---
+
+# Features
+
+
+
+ | Area |
+ Status |
+
+
+ | Bridge handshake |
+ Implemented — HELLO, HELLO_ACK, PING, PONG |
+
+
+ | Roster refresh |
+ Bridge-first |
+
+
+ | Bot states |
+ Bridge-first |
+
+
+ | Bot details |
+ Bridge-first |
+
+
+ | Stats |
+ Bridge-first |
+
+
+ | Inventory |
+ Bridge-first with icons and item tooltips |
+
+
+ | Spellbook |
+ Bridge-first |
+
+
+ | Glyphs |
+ Bridge-first with glyph icons and tooltips |
+
+
+ | Outfits |
+ Bridge-first listing, create/update, reset, equip and replace |
+
+
+ | Units / EveryBars |
+ Improved login, reload and AddClass refresh behavior |
+
+
+ | Legacy automatic chat fallback |
+ Disabled by default |
+
+
+
+---
+
+# Requirements
+
+## Client
+
+- World of Warcraft 3.3.5a / Wrath of the Lich King client.
+- Tested with:
+ - English / US client
+ - German client
+ - French client
+ - Spanish client
+
+## Server
-# MultiBot
-MultiBot is a user interface addon for the AzerothCore `mod-playerbots` module by the Playerbots team: https://github.com/mod-playerbots/mod-playerbots.
-Tested with American, German, French and Spanish 3.3.5 WotLK clients.
+- [`AzerothCore WotLK`](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot).
+- [`mod-playerbots`](https://github.com/mod-playerbots/mod-playerbots).
+- [`mod-multibot-bridge`](https://github.com/Wishmaster117/mod-multibot-bridge).
-This version also expects the companion server module `mod-multibot-bridge` to be installed if you want the new bridge-first/chatless UI behavior.
+---
# Installation
-## 1. Server-side bridge module
-1. Copy the `mod-multibot-bridge` folder into your AzerothCore modules directory, next to `mod-playerbots`:
+## 1. Install the server-side bridge module
+
+Clone the bridge module inside your AzerothCore `modules` directory:
+
+```bash
+cd /path/to/azerothcore/modules
+git clone https://github.com/Wishmaster117/mod-multibot-bridge.git mod-multibot-bridge
+```
+
+Expected structure:
```text
-azerothcore-wotlk/modules/mod-multibot-bridge
+azerothcore/
+└── modules/
+ └── mod-multibot-bridge/
+ ├── conf/
+ └── src/
```
-2. Re-run CMake for your AzerothCore build if your workflow requires it.
-3. Rebuild the server.
-4. Start the server and check that `mod-multibot-bridge` is loaded.
+Then:
+
+1. Re-run CMake if required by your build workflow.
+2. Rebuild AzerothCore.
+3. Copy/install the generated configuration file if required.
+4. Start the server.
+5. Check that `mod-multibot-bridge` is loaded.
When the addon connects successfully, the server console should show messages similar to:
@@ -50,57 +229,149 @@ GET~STATES
GET~DETAILS
```
-For UI actions that execute safe gameplay commands, the console may also show bridge requests such as:
+---
+
+## 2. Install the client addon
+
+Clone this repository into your World of Warcraft AddOns directory.
+
+```bash
+cd "World of Warcraft/Interface/AddOns"
+git clone https://github.com/Wishmaster117/MultiBot-Chatless.git MultiBot
+```
+
+Expected structure:
```text
-RUN~RTI~BOT~Sahkaal~~rti skull
-RUN~RTI~GROUP~1~~attack rti target
-RUN~COMBAT~BOT~Sahkaal~~co +focus
-RUN~COMBAT~ALL~~~co +avoid aoe
+World of Warcraft/
+└── Interface/
+ └── AddOns/
+ └── MultiBot/
+ ├── MultiBot.toc
+ ├── Core/
+ ├── Data/
+ ├── Features/
+ ├── Icons/
+ ├── Libs/
+ ├── Locales/
+ ├── Strategies/
+ ├── Textures/
+ └── UI/
```
-These commands are validated by the bridge whitelist before being routed to bots.
+> The GitHub repository is named `MultiBot-Chatless`, but the local addon folder must be named `MultiBot`.
-## 2. Client-side addon
-1. Copy the addon files into a folder named `MultiBot` inside your World of Warcraft AddOns directory:
+Do not install it like this:
```text
-World of Warcraft/Interface/AddOns/MultiBot
+Interface/AddOns/MultiBot/MultiBot/MultiBot.toc
```
-Example on Windows:
+The `.toc` file must be directly here:
```text
-DRIVE:\WowClientFolder\Interface\AddOns\MultiBot
+Interface/AddOns/MultiBot/MultiBot.toc
```
-2. Make sure the `.toc` file is directly inside the `MultiBot` folder. The addon should not be nested inside an extra directory such as `MultiBot/MultiBot/...`.
-3. Start World of Warcraft.
-4. Enable the addon on the character selection screen if needed.
-5. Log in and use `/multibot`, `/mbot`, `/mb`, or the minimap button.
+---
+
+# Updating
+
+## Update the addon
+
+```bash
+cd "World of Warcraft/Interface/AddOns/MultiBot"
+git pull
+```
+
+## Update the bridge module
+
+```bash
+cd /path/to/azerothcore/modules/mod-multibot-bridge
+git pull
+```
+
+Then rebuild your AzerothCore server if the module code changed.
+
+---
+
+# Recommended Configuration
-## 3. Recommended configuration
For normal bridge-first usage, keep legacy automatic chat fallback disabled:
```lua
MultiBot.allowLegacyChatFallback = false
```
-Only enable it temporarily for debugging:
+Only enable it temporarily for debugging or compatibility testing:
```lua
MultiBot.allowLegacyChatFallback = true
```
-# Use
-Start World of Warcraft and enter `/multibot`, `/mbot`, or `/mb` in the chat, or use the minimap button.
+---
+
+# Usage
+
+Start World of Warcraft and use one of the following commands:
+
+```text
+/multibot
+/mbot
+/mb
+```
+
+You can also use the minimap button.
-The addon will automatically try to connect to `mod-multibot-bridge`. If the bridge is connected, the main UI refresh paths use structured bridge messages instead of legacy chat replies.
+When the bridge is available, the addon automatically uses structured bridge messages for the main UI refresh paths instead of legacy chat replies.
-Manual bot information commands remain available. You can still whisper/use commands such as `who`, `co ?`, `nc ?`, `ss ?` and similar playerbot diagnostics when you explicitly want to inspect a bot state. The chatless conversion only removes the automatic UI-refresh spam; it does not remove voluntary status commands.
+Manual commands are still available when you intentionally want them.
+
+Examples:
+
+```text
+/w BotName who
+/w BotName co ?
+/w BotName nc ?
+/w BotName ss ?
+```
+
+---
+
+# Bridge-First Architecture
+
+
+
+
+
+ | Old behavior |
+ New behavior |
+
+
+ | Addon triggers bot commands |
+ Addon sends structured MBOT GET~... requests |
+
+
+ | Bots answer with chat text |
+ Bridge returns structured addon messages |
+
+
+ | Addon parses localized chat lines |
+ Addon consumes stable protocol payloads |
+
+
+ | Automatic UI refresh creates chat spam |
+ Main UI refresh paths are mostly chatless |
+
+
+
+
+
+---
# Current Status
-Implemented bridge-first/chatless areas:
+
+Implemented bridge-first / chatless areas:
- Bridge handshake: `HELLO`, `HELLO_ACK`, `PING`, `PONG`.
- Roster refresh.
@@ -112,34 +383,196 @@ Implemented bridge-first/chatless areas:
- Glyph refresh with icons and glyph tooltips.
- Outfits refresh and actions through the bridge.
- Outfit equip/replace without detailed `Equipping [item] ...` chat spam.
-- RTI / Target Icons through `RUN~RTI` with `BOT`, `GROUP` and `ALL` scopes.
-- Pull Control through `RUN~COMBAT`, including wait time, focus, DPS assist, DPS AoE, presets and RTI pull/attack actions.
-- Combat Strategies through `RUN~COMBAT`, including individual EveryBar toggles and Party/Raid strategy toggles for `avoid aoe`, `save mana`, `threat` and `behind`.
-- Custom Glyphs socket mapping and apply order.
+- Custom glyph socket mapping and apply order.
- Talent tab navigation stability after switching between tabs.
- Automatic bot reconnect on login/reload for bots already present in the group or raid.
- Units bar refresh after adding a bot through AddClass.
Kept intentionally:
-- Manual whisper/playerbot commands for diagnostics, including `who`, `co ?`, `nc ?`, `ss ?` and similar state-inspection commands.
-- Manual gameplay commands for players who still want to control bots directly through whispers or party/raid chat.
-- Whitelisted bridge gameplay actions for UI buttons that do not need structured chat parsing.
+- Manual whisper/playerbot commands for diagnostics.
+- Commands such as `who`, `co ?`, `nc ?`, `ss ?`.
+- Gameplay write actions that still rely on existing playerbot commands.
- Optional legacy fallback behavior only for debugging or compatibility.
+---
+
# Remaining Work
-The RTI, Pull Control and Combat Strategies passes are now implemented. The next step is final stabilization, followed by the next missing command block.
+
+The Outfits migration is complete. The next step is final stabilization and cleanup.
Planned follow-up work:
-- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs, Outfits, RTI, Pull Control and Combat Strategies.
+- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs and Outfits.
- Verify that `MultiBot.allowLegacyChatFallback = false` prevents automatic legacy refresh spam on all migrated UI paths.
-- Keep manual diagnostic commands documented and functional, especially `who`, `co ?`, `nc ?` and `ss ?`.
-- Keep `RUN~COMBAT` and `RUN~RTI` strictly whitelisted in the bridge; they must not become generic unrestricted command executors.
-- Remove obsolete debug prints and dead legacy parser paths once the bridge-first behavior is fully stable.
+- Keep manual diagnostic commands documented and functional.
+- Remove obsolete debug prints.
+- Remove dead legacy parser paths once bridge-first behavior is fully stable.
- Update screenshots and user documentation after wider testing.
-- Next command block to evaluate: `disperse set ` / `disperse disable`.
---
-# Detailed Notice
+# Troubleshooting
+
+
+The addon does not load
+
+Check that the folder is named exactly:
+
+```text
+Interface/AddOns/MultiBot
+```
+
+and that the `.toc` file is here:
+
+```text
+Interface/AddOns/MultiBot/MultiBot.toc
+```
+
+If the `.toc` file is inside another nested `MultiBot` folder, the addon is installed incorrectly.
+
+
+
+
+The addon loads but the bridge does not connect
+
+Check that:
+
+- `mod-multibot-bridge` is installed in the AzerothCore `modules` directory.
+- AzerothCore was rebuilt after installing the module.
+- The server was restarted after rebuilding.
+- The bridge module is visible in server logs.
+- Your client is logged into a character connected to the server.
+
+
+
+
+I still see some chat messages
+
+This project removes automatic UI-refresh spam where the bridge path has been implemented.
+
+Manual commands and gameplay actions may still produce intentional messages.
+
+Make sure this value is disabled unless you are debugging:
+
+```lua
+MultiBot.allowLegacyChatFallback = false
+```
+
+
+
+
+Inventory, spellbook, glyphs or outfits do not update
+
+Check the server console for bridge requests such as:
+
+```text
+GET~INVENTORY
+GET~SPELLBOOK
+GET~GLYPHS
+GET~OUTFITS
+```
+
+If these requests do not appear, the addon may not be connected to the bridge.
+
+
+
+---
+
+# Repository Layout
+
+```text
+MultiBot-Chatless/
+├── Core/
+├── Data/
+├── Features/
+├── Icons/
+├── Libs/
+├── Locales/
+├── Strategies/
+├── Textures/
+├── UI/
+├── docs/
+└── MultiBot.toc
+```
+
+---
+
+# Related Repositories
+
+
+
+---
+
+# Credits
+
+MultiBot is built for use with AzerothCore `mod-playerbots`.
+
+Thanks to Macx-Lio for the original MultiBot Module.
+
+Thanks to the Playerbots team and the AzerothCore community.
+
+---
+
+
From 20d2b16c24ea6d5f2eaee7964532e3513c182c9e Mon Sep 17 00:00:00 2001
From: Wishmaster117 <140754794+Wishmaster117@users.noreply.github.com>
Date: Tue, 28 Apr 2026 17:05:21 +0200
Subject: [PATCH 3/3] Update README.md
---
README.md | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index de845e5..cd796c3 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,8 @@ GET~INVENTORY
GET~SPELLBOOK
GET~GLYPHS
GET~OUTFITS
+RUN~RTI
+RUN~COMBAT
```
Manual playerbot commands are still intentionally preserved for diagnostics and gameplay actions.
@@ -157,6 +159,18 @@ The goal is to remove automatic UI-refresh spam.
Outfits |
Bridge-first listing, create/update, reset, equip and replace |
+
+ | RTI controls |
+ Bridge-first icon assignment and RTI target actions |
+
+
+ | Pull Control |
+ Bridge-first wait, focus, DPS assist, AoE and RTI pull/attack controls |
+
+
+ | Combat strategy fine tuning |
+ Bridge-first avoid AoE, save mana, threat and behind controls |
+
| Units / EveryBars |
Improved login, reload and AddClass refresh behavior |
@@ -383,6 +397,9 @@ Implemented bridge-first / chatless areas:
- Glyph refresh with icons and glyph tooltips.
- Outfits refresh and actions through the bridge.
- Outfit equip/replace without detailed `Equipping [item] ...` chat spam.
+- RTI controls through the bridge.
+- Pull Control frame through the bridge.
+- Combat strategy fine tuning through the bridge.
- Custom glyph socket mapping and apply order.
- Talent tab navigation stability after switching between tabs.
- Automatic bot reconnect on login/reload for bots already present in the group or raid.
@@ -399,11 +416,12 @@ Kept intentionally:
# Remaining Work
-The Outfits migration is complete. The next step is final stabilization and cleanup.
+The Outfits, RTI, Pull Control and Combat Strategy migrations are implemented. The next step is Disperse, followed by final stabilization and cleanup.
Planned follow-up work:
-- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs and Outfits.
+- Start the Disperse command migration.
+- Regression test login, `/reload`, large raid groups, Units, EveryBars, Stats, Inventory, Spellbook, Talents, Glyphs, Outfits, RTI, Pull Control and Combat Strategies.
- Verify that `MultiBot.allowLegacyChatFallback = false` prevents automatic legacy refresh spam on all migrated UI paths.
- Keep manual diagnostic commands documented and functional.
- Remove obsolete debug prints.