One click to buff back whoever just buffed you — and nearby players missing yours.
A priest buffs you in passing. By the time you have picked them out of a dozen nameplates, they are gone.
Manners notices, works out what you owe them, and puts one button on screen. Click it, they get their buff, and your own target is handed straight back.
It also offers nearby players who are missing yours — not to optimise a raid, just so being the person who buffs strangers costs one click instead of a minute of squinting at names.
Languages: English, German, Spanish (Spain and Mexico), French, Italian, Korean, Brazilian Portuguese, Russian, Simplified and Traditional Chinese — whichever your client runs in. Slash commands are English in all of them.
Wago — and through WowUp, which reads Wago. Search Manners and install.
CurseForge — and the CurseForge app.
Both get the same build from the same tag. Wago is the one to use if you manage addons with WowUp: it dropped CurseForge support when Overwolf cut off third-party clients, so an addon published only to CurseForge never appears there.
To install by hand, take a release zip from
Releases and unzip it into
Interface/AddOns.
Do not install from a clone of this repository.
Libs/is deliberately not committed — the 14 libraries are fetched at build time — so a zip made from a checkout has none of them and will not load. Use a release.
This is a beta, and the reason is worth a sentence before you rely on it: the code is finished and the suites are green, but one class on one client has actually been played. Everything else is tested against a mock, and a mock agrees with whoever wrote it.
| How far it has been taken | |
|---|---|
| Mage, on WoW Forever | cast in game, repeatedly, against real players |
| Priest, Druid, Paladin, Warlock, Warrior — WoW Forever | spell data corroborated against other addons running on this client, every cast path exercised by the suite, never cast in game |
| Retail, Mists Classic, Classic Era — every class | implemented and exercised by the suite, spell data from the patch notes and the wiki — but nobody involved can launch those clients, so they are not shipped yet |
Getting one spell to cast here took ten attempts, on a client that documents none of its restrictions. Every class uses that same path and their macros are checked automatically — but "the tests pass" is not "somebody used it". Treat anything but Mage as unproven, and please say so either way: it worked is the more useful report, because it is what moves a class off this list.
If a buff is never offered, /manners debug names any spell id the client does
not actually have, and reports which client it decided it is on.
Hunters and rogues have nothing to cast on another player, and Manners says so plainly rather than sitting there looking broken.
- Somebody you targeted yourself → outranks everyone, including a favour owed, but only when the game will confirm they are missing it. A guess does not get to jump the queue, and with always offer chosen nothing is checked, so your target waits their turn like anybody else.
- Someone buffs you → they go to the top of the queue, tagged as a favour owed. It is spotted by watching your own buffs appear and reading who cast them, which works on strangers, but only while they are someone the game will still name for you. On Classic Era, Burning Crusade and Mists the combat log is read as well, and that one can name somebody who has no nameplate at all — Forever and retail do not hand addons a combat log, so there the buff watch is all there is. The debt is stored per character and survives a reload or a disconnect.
- Your party or raid → anyone missing your buff.
- Passers-by → nearby players missing your buff, seen through nameplates, your target, your focus and your mouseover.
Skips the dead, the out-of-range, anyone you just tried, and anyone the buff does nothing for — Arcane Intellect is wasted on a rogue. Right-click the prompt to skip somebody without marking their favour repaid.
Never offer. Shift-right-click the prompt to put the person on it on a list of people who are never offered anything, as a passer-by or as a member of your group. Chat says how to undo it; the list is also on the Who to buff tab, where names can be added, taken off one at a time or cleared. Somebody on the list who buffs you is still offered the favour back — returning a favour is the point — and shift-right-clicking them then lets that favour go as well.
Who comes first. A friend (Battle.net friends included) or guildmate passing by goes ahead of the other passers-by, and one in your group ahead of the rest of your group. It only changes the order: people who buffed you still come first, so does your target whenever Whoever I have targeted comes first puts them there, and somebody the game says is out of range stays behind somebody in range. Switch it off under Who comes first.
Passers-by only in cities and inns is a choice under Who to skip, off by default: out in the world, strangers walking past are left alone, while your group, anybody who buffed you and whoever you target are still offered.
How near a passer-by has to be is its own setting, because being in range is not the same as being near: Arcane Intellect reaches about thirty yards, which in a city is everybody on the screen. Choose anywhere I can cast (thirty yards, as it was), nearby (about ten, the default) or right beside me (about five). It applies to passers-by only — somebody who buffed you was close enough a moment ago, your group is your group, and whoever you have targeted or focused you picked on purpose.
The game will not say how far away a player is, so this is measured with
whatever the client offers — LibRangeCheck if it is there, the client's own
interact distance otherwise — and lands on the nearest step that has. Where
nothing can measure at all, everybody in casting range is offered as before.
/manners debug says which of those is in use and how often it answers.
If they already have it, you choose: leave them alone, offer a top-up once their timer drops below a threshold you set, or always offer regardless. Somebody who buffed you is offered the favour back either way, even if they already have it — recasting it only refreshes it.
Snooze hides the prompt for a while without switching Manners off:
/manners snooze for 15 minutes, /manners snooze 5 or snooze 1h for your
own length (up to four hours), snooze off to end it early. The minimap menu
and the General tab have it too. It lasts until the time is up or you reload.
Not while mounted, on the When tab and off by default, keeps the prompt
away while you ride. Press the key while either is hiding the prompt and chat
says which.
Which buffs each class offers, per client
Which spells exist depends on the client, so the tables do too. /manners debug
prints the set it chose, and the Diagnostics tab lists what your class has.
Vanilla content — Classic Era, Burning Crusade Classic, WoW Forever:
| Class | Buffs offered |
|---|---|
| Mage | Arcane Intellect |
| Priest | Power Word: Fortitude, Divine Spirit, Shadow Protection |
| Druid | Mark of the Wild, Thorns |
| Paladin | Wisdom, Might, Kings, Salvation, Light, Sanctuary |
| Warlock | Unending Breath |
| Warrior | Battle Shout (party only) |
Mists of Pandaria Classic — 5.0.4 deleted the duplicates within each class and folded the raid-wide versions in, so every class has one or two:
| Class | Buffs offered |
|---|---|
| Mage | Arcane Brilliance |
| Priest | Power Word: Fortitude |
| Druid | Mark of the Wild |
| Paladin | Kings, Might |
| Monk | Legacy of the Emperor, Legacy of the White Tiger |
| Warlock | Dark Intent (Unending Breath is offered only if you pin it) |
| Warrior | Battle Shout (party only) |
| Death Knight | Horn of Winter (party only) |
Retail — Midnight. Five class buffs are left in the game, and paladins, death knights, monks and warlocks have nothing they can put on a passer-by:
| Class | Buffs offered |
|---|---|
| Mage | Arcane Intellect |
| Priest | Power Word: Fortitude |
| Druid | Mark of the Wild |
| Shaman | Skyfury |
| Evoker | Blessing of the Bronze, Source of Magic (if talented) |
| Warrior | Battle Shout (party only) |
Where a class has more than one, the prompt offers whichever they are actually missing, in list order: a priest walks Fortitude, then Divine Spirit, then Shadow Protection. Somebody holding the first is still offered the second rather than dropping off the list. Individual buffs can be switched off, or one pinned so that is the only thing ever cast.
Paladins are the exception. Blessings overwrite one another, so holding any one of yours counts as covered and walking the list would mean replacing a blessing somebody already has. The automatic pick is Wisdom for anyone with a mana bar and Might for everyone else.
Battle Shout reaches your party and nobody else, so a warrior outside a group is offered nobody. That is deliberate rather than a fault.
Blizzard does not let an addon cast a spell on its own — CastSpellByName is
protected and only runs from a hardware event. This has been true since patch
2.0 and no addon gets around it.
So Manners does everything except the keypress. It decides who deserves the buff and writes that decision onto a secure button; the game casts when you click. That split is deliberate on Blizzard's part and it is why the prompt also freezes during combat.
Optionally say something when you buff somebody, with a randomised phrase list.
The line rides along in the macro the button runs rather than going through the
chat API — the game refuses addon-sent /say outside instances, which is
exactly where someone buffs you in passing. Through the macro it counts as you
talking.
Off by default, and when on it defaults to speaking only when returning a favour.
A small window listing who buffed you, with what and when, whether you returned it and with what, and who you buffed without being asked — newest first. Today's count ("Returned 12 of 14 favours today") and the all-time totals sit at the top, then tabs for everything, favours, and buffs you gave. A favour you did not return says why: the time ran out, nothing you cast helps them, or you put them on the never-offer list. A favour nothing you cast could return (a warrior's shout, to a mage) is listed but left out of today's count.
/manners ledger, a shift-click on the minimap button, or the button on the
General tab. It keeps the last 200 entries per character; Clear empties the
list but keeps favours still owed and the all-time counts. It opens in combat
and never says anything in chat.
Three looks — glass, framed and minimal — with full colour and font control and LibSharedMedia support. When a buff lands, a ring pops out of the icon and light crosses the panel; a refused one gives the text a small shake and turns the ring red. Somebody who buffs you makes the panel catch the light once, and after your last buff the prompt fades out rather than blinking off. The icon shows the global cooldown sweep, like an action bar.
Effects on the Prompt tab turns all that movement down to Calm, and the sweep has its own switch under Icon and queue. Stay quiet in combat keeps it still in a fight.
A click opens the options, a shift-click the favour ledger, and a middle click switches Manners on or off. Right-click it for a menu: on or off, snooze (5 minutes to an hour), preview, the ledger, who is waiting next (skip one, or never offer them anything), the prompt's lock, position, sound and effects, the chat lines, and your profiles (when you have more than one). In a fight the entries that would move the prompt wait until it ends.
The icon dims while Manners is snoozed and goes darker still while it is off, and a broker display shows how many people who buffed you are still waiting for one back. The same launcher is in the addon compartment under the minimap, and its line there says off, snoozed or waiting just as the button's text does, so hiding the button loses nothing.
/manners options (so does /manners options)
Everyday
/manners on | off switch it on or off
/manners snooze [min|off] hide the prompt for 15 minutes, or as long as you say
/manners test preview the prompt, for styling
/manners ledger the favour ledger
/manners never [name] who is never offered anything, or put somebody on it
/manners allow <name> take somebody off that list
Setting it up
/manners welcome what it does, and the one thing it needs from you
/manners macro make a /click macro for your action bar
/manners unlock drag the prompt; it locks again when you let go
/manners lock lock it again -- an unlocked prompt never casts
/manners restore switch handing your target back on or off
/manners verbose switch the chat lines about who buffed you on or off
Sharing settings
/manners export your settings as one line of text
/manners import <text> use a line somebody exported
/manners import undo put your own settings back
When something is wrong
/manners debug what your class and this build allow
/manners errors the last few things that broke, if any did
/manners clicks log what the button does when clicked
/manners try <macro> run any macro text from the prompt
/manners look [unit] every answer the game gives about a unit
/manners forms example macros to try
/manners help this list, grouped the same way
/mnr works in place of /manners in all of them. A word it does not
recognise suggests the closest command, or lists them all.
The first login on a character says what /manners welcome says by itself,
once, and puts the prompt on screen so you can see where it is. It is kept per
character rather than per profile: every character starts on the one shared
profile, so a flag there would greet whoever logged in first and nobody else —
and what it asks for (a macro on this character's bars, or a key bound) is per
character too.
Put it on a bar with a macro containing /click MannersPrompt LeftButton 1
(/manners macro makes one), or keybind under
Options → Keybindings → Manners ("Buff the prompted player"). The trailing 1 is the down flag: the
secure button only casts on the way down.
Sharing settings. /manners export puts your settings in a box on the
General tab as one line of text, to keep or to hand to somebody; paste one into
the box beside it, or after /manners import, to use it. Only what differs
from the defaults is written, a damaged line is refused before anything
changes, and /manners import undo puts your own settings back. A pasted line
never switches on speaking to other players, and never touches your on switch,
the prompt's lock or position, or the minimap button.
This client differs from other flavours in ways that are not documented anywhere, and each one took a live test to find.
Conditional targeting does not work. [@unit], [@Name], [@focus],
[@mouseover] and the secure unit attribute all fail, silently or with "You
have no target". A bare /cast with no target works fine, so this is
specifically about naming another unit. Two of those would not have worked
anywhere: [@Name] resolves only for somebody already in your party or raid on
every flavour, and [@nameplateN] resolves on none of them. Which is why the
macro is the same everywhere — targeting the person by name, casting, and
handing your target back is the only shape that reaches a passing stranger on
any client. The macro uses /target, which matches a name prefix, so
offering Mort could find Mortimer standing next to him. Where the client names
who received the spell, the addon notices the cast landed on somebody else and
says so; this client usually doesn't, and then the favour is counted as repaid
on the strength of the /target line alone. /targetexact is
detected (/manners debug reports it) but not used yet: it finds nobody at all
if the name is one character out, and the surname spelling the addon assembles
has not been checked against it in game.
Secure buttons must register for mouse down. Registering up only leaves the
click arriving and the attributes correct while the game casts nothing and
reports nothing. Every secure button that works here registers "AnyDown".
Unit power is a secret value for players outside your group, so "does this person have mana" cannot be read directly. Class is used instead, which is accurate for every vanilla class.
UnitName returns a surname, not a realm, in its second value. Joining
them with a hyphen produces names that no targeting call resolves. Surnames are
this client's alone: on the other four that second value is the realm, present
only for a cross-realm player, and there the two join with a hyphen — a space
would make a name nothing can find. The addon branches on the flavour for this,
because both values are plain strings and neither says which it is.
Nameplate unit tokens are secret when read off the frame via
C_NamePlate.GetNamePlates(). The token passed to NAME_PLATE_UNIT_ADDED is
not, so that is what to track.
There is no combat log. Registering COMBAT_LOG_EVENT_UNFILTERED is
refused here; Blizzard ships C_DamageMeter instead. That is not a Forever
quirk — retail 12.0+ refuses it too, and only Classic Era, Burning Crusade and
Mists still have one. So a favour is spotted by watching your own buffs appear
and reading aura.sourceUnit, which is a unit token: somebody with no
nameplate who is not your target cannot be identified at all. Nothing can be
done about that from an addon here. Where there is a log, Manners registers
it as a second source and that person can be named after all —
SPELL_AURA_APPLIED carries their GUID, and GetPlayerInfoByGUID turns a GUID
into a name and a class with no unit token. The aura scan stays the spine
either way; the log only ever adds.
Full checklist in RELEASING.md.
Libs/ is deliberately not in the repository: .pkgmeta declares all 14
libraries as build-time externals, so the packager fetches current upstream
copies under their own licences.
A zip built from a clone therefore has no libraries and will not load.
Write the notes under ## Unreleased in CHANGELOG.md, set the version, push
master, and once CI is green tag it and let the workflow build it:
python tests/setversion.py X.Y.Z-beta.N
git commit -am "Manners X.Y.Z-beta.N"
git push origin master
git tag vX.Y.Z-beta.N && git push origin vX.Y.Z-beta.N
A tag pushed without notes, or pushed together with master before CI has passed, fails its build and stays on origin; RELEASING.md says how to take it off.
.github/workflows/release.yml runs the test suites, fails the build if any
check has stopped being able to detect the fault it exists for, then packages
and publishes a GitHub release and uploads to CurseForge and Wago from the
one tag.
A destination needs both a token in the repository secrets (CF_API_KEY,
WAGO_API_TOKEN, WOWI_API_TOKEN) and a project id in the toc
(X-Curse-Project-ID, X-Wago-ID, X-WoWI-ID). Missing either skips that
upload in a way that reads exactly like success, so the build log names which
half is absent.
python tests/validate.py structure, syntax, and version consistency
python tests/runharness.py load the addon against a mock client
python tests/runscenarios.py adversarial scenarios
python tests/selftest.py confirm the suites can still go red
All four run on every push via .github/workflows/ci.yml, and again as a gate
before any release. See tests/README.md.
The CurseForge icon and the screenshots are generated, not captured — see
tools/README.md. They read the prompt's real defaults out of Core.lua and
its colours out of Prompt.lua, and CI fails if any of those can no longer be
found, so they cannot advertise a layout the addon does not draw.
MIT, see LICENSE. Bundled libraries keep their own terms — see
THIRD-PARTY-NOTICES.md. LibSharedMedia-3.0 is LGPL v2.1.

