BuffBoard-0.31.0.zip
What's new
Changelog
0.31.0
Added
The discard threshold is now a choice. A charged item such as a mana gem can be offered for discard at one charge remaining or at two, with one as the default: a two charge gem is still worth two casts, and replacing it early wastes a conjure and a global.
The control sits in the assignment window beside the gem itself rather than in the settings panel, because "offer to discard at" means nothing without the thing it governs in view. It appears only on your own panel — it is a preference about your own bags, not an assignment somebody else can make for you.
Changed
- The threshold was previously fixed in the buff definition as a minimum charge count, which read backwards: "minimum 2" meant "fires at 1". Items now simply declare that they are charged, and the number the player picks is the number they see — pick 1 and it fires at one charge left.
- One shared test decides whether an item counts as spent, so the availability check, the discard task and the trace cannot drift apart.
Fixed
- The reactive announce button did not set its own width. It shares a widget pool with the new, narrower threshold buttons, so a recycled one would have kept their size and clipped its label.
0.30.4
Fixed
The charge scan reported zero for a full gem. ITEM_SPELL_CHARGES_P1 is a format string — "%d Charges" — and it was being concatenated straight into a Lua pattern. In a pattern %d means "one digit", so the result looked for digits, a space, a single digit, another space, then "Charges", which matches nothing. Execution fell through to a fallback that returned zero, and a gem that reads as zero charges was then ignored by both the discard and the availability tests, which required a count above zero.
The scan now extracts the literal wording from the format string rather than using it as a pattern, and finds the number anywhere in the line rather than anchored to the start, since the phrasing varies by client and locale.
Zero charges counts as spent rather than unknown. A gem normally disappears at zero, so seeing one means either a misread or a client that has not caught up. Treating it as full hid the problem; treating it as spent surfaces a discard button that at worst is a harmless suggestion.
The tooltip scanner takes ownership on every use. It claimed the owner frame once at creation, and a scanner that has been cleared or reparented since stops populating — silently, with an empty tooltip rather than an error.
Changed
/bb whydumps the item's full tooltip alongside the parsed charge count. The exact wording of the charge line is what has to be matched, and inferring it from outside the client has already cost a round.
0.30.3
Fixed
The discard button never appeared after spending a charge. Charges were read from the container API, which does not report them: GetContainerItemInfo returns the stack size — 1 for a mana gem no matter how much is left in it — and a locked flag, neither of which is a charge count. Every gem therefore looked either full or empty and the "fewer than two charges" test could never fire.
Charges live only in the item's tooltip text. They are now read by scanning a hidden tooltip, matching the count against the client's own charge wording where it is available so this does not break on a localised client.
Spending a charge now forces the bar to rebuild. The rebuild signature had no charge component, so it relied on the availability state happening to flip at the same moment. That worked only because the thresholds coincided. The charge count is part of the signature now, and refreshes compare charges separately from whether an item is held.
Changed
- The background poll still runs only while nothing is held. Spending a charge fires a bag event, which already triggers a refresh, so polling a carried gem would mean a tooltip scan every second for the whole raid and no new information.
0.30.2
Fixed
Mana gems produced no conjure button. The expected spell name was "Conjure Mana Gem", which is the Wrath name. In TBC each tier is its own spell — Conjure Mana Emerald, Conjure Mana Ruby, Conjure Mana Citrine, and so on — so no ID ever matched the expected name, the by-name fallback searched for a spell that does not exist, and detection returned nothing.
Creation entries can now list several acceptable names rather than one, tried best tier first. Soulstone and Healthstone keep a single name, which is correct: those really are ranks of one spell.
/bb why with no argument traced Soulstone regardless of class. A mage running it got a warlock report full of nils with no indication why. It now lists the buff keys for your own class, and flags plainly when you trace a buff belonging to another class so the nils are expected rather than alarming.
Changed
- The trace distinguishes an ID that names the wrong spell from one that names the right spell you have not learned yet. Both produced the same silence before.
0.30.1
Fixed
Mana gems and healthstones produced no button until the duty was ticked. Both live in a SELF section, and SELF duties are opt-in toggles that start off. Auto-assign deliberately skips them, so nothing ever switched them on and there was no prompt of any kind — the feature looked broken rather than dormant.
The reasoning for opt-in was sound where it came from: Righteous Fury is spec dependent and switching it on for a retribution paladin would be wrong. It does not hold for a mana gem. Every mage wants one; there is no spec where they do not.
Duties can now be marked on by default, and mana gems and healthstones are. The toggle became tri-state to make that safe: true and false are choices the player made and are honoured either way, and only an untouched duty falls back to its default. Storing nil for "off" would have made a deliberate off indistinguishable from untouched, so a default-on duty could never have been switched off. Explicit choices also survive the addon sync, which previously discarded them.
Changed
- Carried-item chips report what is actually in the bag: whether you have one, how many charges are left, and the difference between having none and having one too spent to count.
/bb whyreports the toggle state and its default, plus charge counts against the minimum. The switched-off toggle was invisible from outside — the chain looked healthy right up to "no task built".
0.30.0
Added
Mana gems are tracked for mages. A "Carrying" section on the mage panel, matching the warlock's stones: tick it and the bar asks for a gem whenever you have none. All tiers from Mana Agate through Mana Emerald are recognised, and Conjure Mana Gem is cast by name so it always produces the current one.
A partly-spent gem counts as no gem. Entries can declare a minimum charge count, and a gem below it is treated as not held — because it is not usable in the way that matters: a gem with one charge left blocks conjuring a full one, so the bar asks for a replacement before that becomes a problem rather than after the gem runs dry mid-fight.
Discarding a spent gem, out of combat only, and it appears before the conjure task since the old gem has to go first.
One honest limitation. An addon cannot delete an item. DeleteCursorItem is protected and callable only from a genuine keypress, so a one-click delete is not achievable by any addon and anything claiming otherwise would silently fail. What is unprotected is putting the item on the cursor, so the button does that and you press Delete — one keystroke, with Blizzard's own confirmation. The tooltip says so plainly rather than implying a delete it cannot perform.
The button is orange with a - badge, distinct from the blue + of a creation task, and it is hidden in combat both because it was asked for that way and because putting an item on the cursor mid-pull is the last thing anybody wants.
0.29.2
Changed
- The druid duties hint now suggests Innervate on a healer or mage. The picker already offered every mana class, so this only brings the wording in line with what the addon does.
0.29.1
Fixed
Fear Ward was described as a dwarf and draenei racial. It became available to every priest in TBC 2.4.3. The hint now says what actually makes it worth assigning: a single target on a three minute cooldown that somebody has to own before a fear-heavy pull.
Only the wording was wrong — nothing gated the buff on race, so behaviour is unchanged.
Trueshot Aura was measured against one subgroup. It became raid-wide in TBC 2.1, so a hunter's own party was checked and everybody else was ignored, both in the coverage count and in the hint.
Entries can now be marked raid-wide, and there is a RAID axis that measures against the whole raid rather than borrowing one arbitrary class or subgroup. One hunter with the talent now correctly covers everybody.
0.29.0
Fixed
The Soulstone button was creating healthstones. The trace showed it plainly: create id 27230 -> Create Healthstone. That ID was listed as rank 6 Create Soulstone and tried first, so every press made the wrong item — which also explains why the bar never switched to applying one. It was waiting for a soulstone that was never going to appear.
This ID has now been wrong twice: 27239 is the aura, 27230 is a different spell entirely. Rather than guess a third time, the rank 6 entry is simply absent and the addon derives it instead.
Creation spells are validated against their expected name. Every entry now carries the spell's base name, and an ID is only trusted if it resolves to exactly that. A wrong ID is discarded rather than cast. If no ID validates, the spell is cast by name, which uses the highest rank the player knows — the behaviour wanted anyway, and it makes the ID list an optimisation rather than a correctness requirement.
An ID that resolves to the wrong spell is worse than one that does not resolve at all: the first silently does something else, the second fails visibly.
Added
Healthstones are tracked. A new "Carrying" section on the warlock panel: tick it and the bar asks for a healthstone whenever you have none, and stops once you are carrying one.
It is a self duty rather than a target assignment, because a healthstone is made for yourself and consumed by whoever holds it — there is no target and nothing lands on anybody. The only question is whether you have one, which needed a new task type: the usual coverage test measures auras and would never have produced a task at all. All ranks from Minor through Master are recognised, including the Fel variants.
Changed
/bb whyflags any creation ID that resolves to the wrong spell, in red. That one line would have caught this immediately.
0.28.3
Fixed
The bar did not switch from "create a soulstone" to "apply it" once one was made. Two independent causes, either of which was enough on its own.
Detection depended on a single event. BAG_UPDATE_DELAYED was the only signal that bag contents had changed, and a conjured item does not reliably produce it at a moment when GetItemCount already reports the new stone. Item state is now refreshed on several signals — both bag events, a completed cast, and leaving combat — plus a one-second backstop poll.
The poll only runs while an item-applied buff is in its "create" state, which is exactly the window where a stone might appear. It stops the moment one is held, so it is not a permanent ticker: six GetItemCount calls a second, warlocks only, and only while they genuinely have no stone.
The bar would not have rebuilt even so. The rebuild signature was built from each task's buff key and target unit, but creating and applying write completely different attributes — a spell cast on yourself versus a macro using an item on someone else. The signature now records which of the two a task is, along with the spell name, so the change forces a rebuild on its own account.
A related bug in combat: a button's identity for the stale check was keyed on its cast target, which changes when a soulstone task goes from "create one" to "apply it to Weross". The button was marked stale at that moment and greyed out as finished, when the real work had only just begun. It is now keyed on the buff and its label, neither of which moves.
Changed
/bb whyreports which item ranks are actually held, and whether bag watching was registered.
0.28.2
Fixed
The Soulstone creation button finally appears. The task was being built correctly all along — /bb why confirmed create=true, spell=Create Soulstone, unit=player — but the bar then set no attributes on the button at all, leaving it blank.
The branch in setAction that handles a creation cast was never actually present. An edit that was meant to add it did not apply, and the retry that followed fixed the surrounding lines without re-checking that one. Soulstone carries both useItem and createSpell, so every creation task fell into the item branch instead, found no item to use, and returned having written nothing.
The creation branch is now tested first, and the item branch reports when it finds nothing to use rather than returning silently. A no-op there is what hid this through three releases.
Rank 6 Create Soulstone had the wrong spell ID. 27239 is Soulstone Resurrection, the aura; the creation spell is 27230. The trace output showed it resolving to the wrong name — it would have been offered as the best rank and cast the wrong thing.
Changed
/bb whynow reads the attributes back off the bar button as well as reporting the task, so "no task was built" and "a task was built but the button is blank" are distinguishable. Those are different bugs and this release was the second.
0.28.1
Changed
Creation-spell detection is more forgiving. CreateSpellFor required a spell ID to resolve and the spellbook lookup to confirm it. Either can fail independently, so it now tries three ways in order: ID to name with a spellbook confirmation, then any rank whose name resolves at all, then the English base name. A warlock with Create Soulstone on their bar should never be told they cannot make one.
Added
/bb why <BUFFKEY> walks the exact decision chain the action bar uses and prints where it stops — the buff's class, its section and axis, each creation spell ID and whether it resolves, what CreateSpellFor and HeldItem return, the recorded availability state, the castable name, who it is assigned to, and whether a task was built.
This exists because the Soulstone button has now failed three times for three different reasons, and each round has been me guessing from a screenshot. The command reports the answer from the client instead.
/bb items also reports the creation spell alongside the item ranks.
0.28.0
Added
Creating a soulstone is now a tracked step, not an assumption. BuffBoard modelled applying the stone but never making one, so a warlock who had not created a stone yet saw an assignment on the board and nothing at all on the bar. There was no way to start.
The creation spell is now part of the buff definition, and the bar asks for it first:
- No stone in bags — the button casts Create Soulstone on you. Blue, with a
+badge and the creation spell's own cooldown, so you can see why another cannot be made yet. - Stone in bags — the button reverts to applying it to the assigned player, as before.
Creation sits in its own priority phase above everything else, since nothing downstream can happen until the item exists. It appears even when the assigned player already has the buff, because a spare stone is worth having before the next pull rather than after someone dies.
All six Create Soulstone ranks are recognised, best known rank first. The board chip says plainly when you hold none, and /bb items reports the creation spell alongside the item ranks.
Fixed
- A tooltip was assembled with a conditional entry in the middle of a table constructor. A nil there makes
ipairsstop at that point, which would have silently dropped every line after it.
0.27.2
Fixed
Soulstone still produced no button on the action bar. The 0.26.4 change added an item-applied path but three things kept it from working.
The macro was built from the item's name, and GetItemInfo returns nil until the client has cached an item — which it often has not after a fresh login. That nil propagated: CastNameFor returned nothing, task generation bailed out before the bar was reached, and setAction had already cleared the button's attributes, so it ended up with no action at all. Silently, in both cases.
Macros are now built from the item ID — /use [@target] item:22116 — which is always valid and never waits on a cache. The name is used only for display.
The item list also omitted the two lowest Soulstone ranks, so a warlock carrying only a Minor or Lesser stone was told they had none. All six ranks are recognised.
Finally, bag contents are not reliably queryable at PLAYER_LOGIN, so a warlock who already had a stone could scan as holding none and see nothing until they happened to loot something. A deferred recheck a few seconds after login covers that.
A declaration-order bug was fixed alongside: the deferred recheck referenced a local function declared further down the file, which would have been nil when the timer fired.
Added
/bb itemsreports every item-applied buff: which ranks you hold, whether the client has cached each name, and what the addon believes is castable. Enough to tell a missing item from a detection failure without another round trip.
0.27.1
Fixed
The safety-net rescan interval is adaptive rather than fixed. Raising it to eight seconds in 0.27.0 slowed down one case that genuinely needed the timer: walking back into range is not an aura change, so no event announces it, and only a full pass resolves a returning member from "unknown" to their real state.
It now runs every eight seconds while everybody is readable — where it discovers nothing UNIT_AURA has not already reported — and every two seconds while somebody is unreadable, which is faster than the three seconds it used before 0.27.0.
Detection latency for a buff falling off is unaffected either way: that path runs on UNIT_AURA, not on the timer.
0.27.0
Changed
Performance pass over the event handlers and tickers. No behaviour changes, but the addon does considerably less work in a raid.
UNIT_AURA does a table lookup instead of a search. This is the addon's highest-frequency event — it fires for targets, focus, nameplates and every group member, many times a second in combat. The handler searched the roster linearly for a matching unit, then rescanned all twenty-five members when one had changed. It now looks the unit up in a new index and rescans only that member, so each event does roughly a twenty-fifth of the work and units outside the group exit immediately.
The safety-net rescan is now adaptive. UNIT_AURA covers everyone in range, so the periodic full pass only matters for members who are out of range and cannot report their own changes.
With everybody readable it runs every eight seconds rather than three, since it discovers nothing UNIT_AURA has not already reported. While somebody is unreadable it runs every two seconds — faster than the old fixed three — because walking back into range is not an aura change and no event announces it, so only a pass can resolve their state. It also runs only while the board or bar is on screen, and catches up with a full scan whenever it restarts.
Detection latency for a buff falling off is unchanged: that path runs on UNIT_AURA, not on the timer, and still surfaces in about a third of a second.
The ticker stops when nothing is watching. Its frame was never hidden, so the handler ran every frame for the whole session — returning early, but still executing sixty times a second while solo with no window open. WoW stops calling OnUpdate on a hidden frame, so it is now hidden unless the board or bar is visible and you are in a group.
Bag scanning is class-gated and targeted. The handler added in 0.26.4 ran a full spellbook scan on every bag change and broadcast capabilities over the addon channel — for every class, though only warlocks have an item-applied buff. Bag events fire constantly while looting or vendoring. It is now registered only for classes that need it, rechecks only the item-applied buffs, and fires nothing unless the answer actually changed.
0.26.4
Fixed
Soulstone never produced a cast button. A warlock could assign it to a player, but nothing appeared on the action bar to apply it.
Soulstone carries three different names for one thing: the spellbook holds "Create Soulstone", which makes an item; the item is what gets used on a target; and the aura left behind is "Soulstone Resurrection". The addon stored the aura name as the castable spell, so the spellbook lookup found nothing, the buff was never marked as known, and task generation bailed out before reaching the bar.
Buffs applied by an item now have a path of their own. Availability depends on holding the item rather than knowing a spell, all four Soulstone ranks are recognised with the best one used first, and the bar issues /use on the item rather than /cast on a spell. Bags are rescanned when they change, so a stone created mid-raid enables its button without a reload.
A warlock carrying no soulstone still gets no button, which is correct — there is nothing to apply until one is made.
Warlock panel text ran past the chip edge. Slot chips show "<label> <buff>", and "Summoned" paired with "Fel Intelligence" was wider than the chip. Slot chips now use the abbreviated buff name as the other chips already did, the pet slot label is "Pet" rather than "Summoned", and Soulstone displays as "Soulstone" rather than "Soulstone Resurrection".
The warrior's shout slot had the same problem with "Maintaining" and is now "Running". Chip labels are also clipped at the chip edge as a safety net, so a future long pairing degrades to a clean cut rather than spilling over whatever sits alongside.
0.26.3
Fixed
Class taglines ran past the right edge of the board. The druid tagline was the longest in the addon and overflowed by roughly eighty pixels.
Two causes. The header line was anchored only on its left, so a font string extends as far as its text needs rather than wrapping. And the window sized itself purely from body content — a druid has a single group column, so the board sat at its 380 pixel minimum while carrying a header far wider than that.
The subtitle is now anchored on both sides and wraps. The window measures it and widens to fit, capped at 620 pixels so one long sentence cannot stretch the board across the screen; past the cap it wraps to a second line. The header height is measured each layout rather than fixed at 34 pixels, so a wrapped tagline no longer runs under the rule and into the body.
The druid tagline was also shortened. Every class tagline now fits the minimum window width, with the wrapping kept as a safety net — the "[no addon]" suffix shown when viewing someone without BuffBoard can still push a line over.
This mod has no additional files

