Repository navigation
Releases: SokratisV/Unbuffed
Releases · SokratisV/Unbuffed
Release list
v1.4.0
Unbuffed
v1.4.0 (2026-10-16)
Full Changelog Previous Releases
- Release 1.4.0
Adds a class browser for choosing buffs, with a list of everything being tracked, and a
tooltip for each buff showing the spell rank that suits the character's level.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com - Show each buff's tooltip, for the rank that suits the character's level
Hovering a buff in the class list or the Active list now shows the game's own tooltip for
the spell, using the highest rank learned at or below the character's level. A character
below the first rank sees that rank with a note saying when it is learned; a level above
the client's cap gets the top rank. The tooltip also says which level it is showing and
what the buff is matched by.
The level data is a table in Buffs.lua, generated from TrainerSpells' trainer data for
Forever and for TBC: 38 buffs, with the TBC list given only where it differs (extra high
ranks). Every family was checked to run through consecutive rank numbers at increasing
levels, and every buff's icon id is one of its own ranks. Blessing of Sanctuary and Blood
Pact are talent and pet spells, in no trainer list, and Blessing of Kings is a talent on
TBC, so those have no level-based rank and show a plain tooltip rather than a guessed one.
A buff added by spell id shows exactly that spell. If the client will not describe a
spell, the tooltip falls back to the buff's name.
RankFor is written out as an explicit if, nota and b or c: that idiom fell through to
the TBC list on Forever for a TBC-only buff, which the new tests caught.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com - Browse buffs by class, with a list of everything being tracked
The Buffs to flag section is now a Class dropdown plus the buffs that class casts on
other players, instead of nine fixed ticks. Choices accumulate across classes, and an
Active buffs list underneath shows everything currently tracked, from any class or added
by name, each with a button to drop it. Unticking in the class view does the same. The
dropdown opens on the player's own class and remembers the last one chosen.
The data lives in a new Buffs.lua: forty buffs across the nine classes (the Paladin's
blessings and auras, the Shaman's totem buffs, the Hunter's auras, the Warlock's
Soulstone and Blood Pact, and so on). Buffs are matched by name as before, and the
names are the ones the buff shows on a player, not the spell's. Icons come from the
client by spell id, so no icon file name has to be right by hand, and a lookup that
fails falls back to the question mark. Every id that appears in TrainerSpells' data for
the class was checked against it: 38 of 40 are confirmed under their own class and none
belongs to another; Blessing of Sanctuary (a talent) and Blood Pact (a pet spell) are in
no trainer list, so those two ids are unconfirmed. Buffs that exist only on the TBC
clients are hidden on Forever.
The nine buffs that existed before keep their keys, exact names and icons, because saved
profiles refer to them. ns.PRESETS is replaced by ns.CLASS_BUFFS with FindPreset and
PresetEntry helpers; seeding Fortitude goes through them.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
v1.3.0
Unbuffed
v1.3.0 (2026-10-16)
Full Changelog Previous Releases
- Release 1.3.0
Removes the Enabled toggle (the addon can be disabled from the AddOns list), adds a
Faded icon option for buffs about to expire alongside Amber tint, and fixes the options
panel stopping at the preview.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com - Fix the options panel stopping at the preview
The preview's timer label was created with no font and given text straight away. A
FontString with no font raises "Font not set" when it is given text, and that error
aborted building the panel at that point, so every section after the preview (anchor,
custom position, look, expiring, general) never existed.
The label now inherits a font template. The local test stubs had been too forgiving to
catch this; they now enforce the same rule, and fail on the previous code.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com - Remove the Enabled toggle; let expiring icons fade instead of turning amber
The Enabled checkbox, /ub on|off and the two runtime checks behind them are gone:
disabling the addon from the AddOns list does the same job. A profile saved with
enabled = false simply draws now, and the stale key is ignored.
Expiring icons gain a choice of look. "Amber tint" is the existing behaviour and stays
the default. "Faded icon" keeps the icon's colour and lowers its opacity instead, by a
Faded opacity setting (10-100%, default 50%) that multiplies the general opacity
setting. Only the icon fades: its gold ring fades with it, but the minutes-left label is
a separate region and is explicitly kept fully opaque. The fade applies only to an icon
that is about to expire, never to one for a buff that is missing outright.
The options preview gains a third demo icon, with a timer, showing the expiring look;
it appears only while expiry flagging is on. The new controls grey out when they do not
apply (everything under the flag toggle, and the opacity slider unless Faded is chosen).
Reset covers the new settings.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
v1.2.0
Unbuffed
v1.2.0 (2026-10-12)
Full Changelog Previous Releases
- Default to the gold ring at 0% zoom, remove the diagnostics, release 1.2.0
The defaults for a profile that has not chosen are now the Gold ring style and 0% zoom
(the whole icon). Square and the old 7% crop remain available. Defaults only fill in
settings a profile does not already have, so anyone on 1.1.0 who never touched either
setting will see the new look after updating.
The diagnostics are gone: the Run diagnostics button, /ub check and ns.RunDiagnostics.
They were written to chase the SavedVariables bug on the beta client, which has been
fixed, and a nameplate conflict that turned out to be another addon. The load-time
snapshot that only they read goes with them; first-run detection now looks at the
saved table directly. An unknown subcommand shows the help line as before. The
README's "When icons don't appear" section now points at the nameplate setting and at
conflicting nameplate addons instead.
A missing or invalid zoom falls back to the default rather than a hard-coded value.
Version 1.2.0.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com - Add an icon zoom setting
Zoom crops the icon art by a percentage from each edge: 0 shows the whole texture,
Blizzard's own border included, and higher values magnify the middle. It is a crop of
the art, not a resize, so it sits alongside the size slider rather than replacing it.
The default is 7, which is exactly the crop the addon already applied, so existing
plates look the same until someone moves the slider. The value is clamped to 0-40%
where the icons are drawn, so a bad saved value can never invert the crop. It applies
to every icon style and to the options preview, which share one StyleIcon function.
Reset puts it back to 7.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com - Add a choice of icon style: square, round or gold ring
Square is the stock icon and stays the default, so nobody's plates change on
upgrade. Round clips the icon to a circle and Gold ring adds a ring around that.
They use Blizzard's own circle mask and ring atlases (the ones FlareUI uses for its
round aura icons), so no art of ours ships.
A style is offered, and drawn, only when the client confirms it has the atlases;
otherwise the dropdown lists just Square and a saved Round or Ring draws as a plain
icon. The Forever atlases are known to exist, but the addon also runs on TBC
Classic, where they may not.
The real icons and the options preview are built through the same NewIcon and
StyleIcon functions, so the preview cannot drift from what the plates show. Hiding
an icon hides its ring too, since the ring is a separate region. Reset puts the
style back to Square.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
v1.1.0
Unbuffed
v1.1.0 (2026-10-09)
Full Changelog Previous Releases
- Choose where the icons attach, and rework the settings panel
The icon row can now sit right of the level text (the default), left of the health
bar, centered under the health bar, or at a custom X/Y from the plate's centre. The
three presets follow the plate's own parts, found the way FlareUI finds them on
Forever (UnitFrame.HealthBarsContainer.healthBar and UnitFrame.PlayerLevelDiffFrame),
and fall back level box -> health bar -> plate when a plate lacks one. The X/Y
sliders appear only for Custom. Profiles saved with the old side setting are
migrated: RIGHT and LEFT map to the nearest preset, and CENTER to Custom with its
offsets unchanged.
The settings panel is now grouped into sections inside a scroll frame, with a live
mock-nameplate preview drawn by the same placement code the real plates use, a
greyed-out expiry threshold when its toggle is off, an icon spacing slider, and a
two-click Reset for position and look. Reset is not a popup, because a StaticPopup
shown from addon code can hang the client in Gamepad mode.
Also:- Fortitude is tracked on a brand-new profile, seeded once rather than through
copyDefaults, which merges the tracked list by index. - SavedVariables are adopted once, at ADDON_LOADED. The VARIABLES_LOADED and login
re-adoption was written for a beta client bug that has since been fixed. - /ub check prints the settings state first, without needing a target.
- The options panel's build now sits inside the refreshing guard.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
- Fortitude is tracked on a brand-new profile, seeded once rather than through
- Add the logo and the CurseForge project ID
The logo (512 and 256 px PNGs, plus the SVG it was drawn from) matches the tile
style of the other addons. It lives under .github, which .pkgmeta already keeps
out of the packaged zip.
X-Curse-Project-ID points the packager's CurseForge upload at the project page.
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com - Re-adopt SavedVariables at login, and report when they never arrive
The instrumentation answered it, and it was neither of the things I had been
fixing: at ADDON_LOADED UnbuffedDB is empty. The settings are not being clobbered
after loading -- they never load. Every session starts from defaults, saves the
session's edits on the way out, and discards them on the way back in, which is
exactly "loses its settings on every reload".
So ADDON_LOADED is no longer the only chance to pick them up. Adopting the global
is now a function, and PLAYER_LOGIN calls it again if the global is no longer the
table we adopted -- i.e. if the real saved values landed after us. This client has
already been caught resolving things later than the Classic ones do; the key
binding set was unavailable at login for the same reason.
If they genuinely never arrive, that is not something the addon can fix, so /ub
check now says which it is: it snapshots UnbuffedDB at both ADDON_LOADED and
PLAYER_LOGIN, prints the type and key count at each, and states plainly whether
the values turned up late or not at all.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Stop the options panel writing defaults back over loaded settings
Settings were still being lost, though not all of them -- side and yOffset came
back fine while iconSize and xOffset reverted to defaults. That pattern rules out
the save path and points at something writing over individual values after they
load.
Two ways that could happen, both now closed:
A widget resync is a READ, but it triggers writes. A slider's SetValue fires
OnValueChanged, and a dropdown's GenerateMenu can re-invoke its setter; both then
call set() with whatever the widget was showing. Refreshes now run under a flag
that makes those setters no-ops, so resyncing can never write.
And the panel could still be built before the real db existed. ns.db is a stand-in
full of defaults until ADDON_LOADED, and the Settings frame may call OnRefresh
during registration -- which would build every widget against that stand-in and
bake defaults in. refreshPanel now refuses to do anything until ns.dbReady.
If it somehow persists, /ub check now settles it in one line: ADDON_LOADED
snapshots what arrived from disk before anything touches it, and check prints that
next to the live values, flagging any that differ.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Flag buffs that are about to expire
A tracked buff with less than the warning threshold left (5 minutes by default)
now draws too: the same icon, tinted amber with the minutes remaining on it, so
"running out" reads differently at a glance from "never cast".
HasBuff returns the aura record alongside its verdict, and ns.AuraRemaining turns
that into seconds left. It returns nil for a permanent buff (expirationTime 0) and
for any client that won't hand the number over -- and nil is never treated as
"about to expire", the same rule that keeps an unreadable buff from being drawn as
missing.
Threshold is a slider (1-30 minutes) rather than a hardcoded 5.
Presets moved to three columns. Nine of them in five rows wasted enough height
that the new controls would have pushed the bottom of the panel under the Close
button again.
/ub check now reports the remaining time per buff, and whether ns.db is actually
the SavedVariables table -- see the next commit for why that matters.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Build the options panel on first show, not at load
Saved settings looked lost after /reload. They were not: SavedVariables on disk
held every tuned value (side=CENTER, iconSize=23, yOffset=-25). The panel was the
problem, and the stand-in ns.db was the cause.
A Settings canvas category needs a frame at registration, so the whole panel was
built during load -- before ADDON_LOADED, so against the stand-in defaults rather
than the loaded values. Widgets that evaluate a callback while being constructed
therefore captured defaults, and MenuUtil's dropdown, which generates its menu at
setup and again on GenerateMenu, can write its remembered selection back: the
saved "CENTER" overwritten by the stand-in's "RIGHT".
A canvas category needs a frame up front, not a populated one. The layout now
lives in buildPanel(), run once from the panel's first show, by which point ns.db
is the real SavedVariables table. That removes the whole class rather than the one
widget -- the same lazy-build shape GaruCombatText's options already use, which is
why they never had this.
Also defines OnRefresh/OnCommit/OnDefault: the modern Settings frame drives canvas
panels through those rather than the legacyrefreshfield.
The stand-in ns.db stays as a guard against indexing nil early, but nothing
depends on its values now.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Add a centered icon-row position
Third option beside left and right: the row anchors CENTER-to-CENTER on the
nameplate, so at offset 0, 0 it sits over the player's name.
The offsets mean something slightly different per position, deliberately. Beside
the plate, xOffset is a GAP -- "distance away from the plate" -- so its sign is
flipped for LEFT and a negative value pulls the row back over the plate on either
side. Centered there is no gap to describe, so xOffset is a plain nudge, positive
right and negative left. A hint under the dropdown says so.
The db key stays "side" even though CENTER isn't one; renaming it would orphan
every saved setting for the sake of a word.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Tighten the options layout and allow a negative horizontal offset
The panel reserved room for four custom-buff rows whether or not any existed,
leaving a hole under "No custom buffs added" and pushing the bottom controls --
the position dropdown and Run diagnostics -- down behind the Close button.
Everything below the custom list now lives in a container frame that
rebuildCustomList repositions to sit just under the list, however long it is. The
widget helpers take an optional parent so they can be built into it. With an empty
list the block starts 68px higher and the last control lands at -576 instead of
-642, well clear of the bottom edge.
Horizontal offset now runs -60..60 rather than 0..60. Negative pulls the icon row
back over the nameplate instead of away from it, and since anchorRow flips the
sign with the chosen side, it reads the same whichever side the row is on.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Don't overwrite the Settings category ID with the addon name
Settings.OpenToCategory forwards to C_SettingsUtil.OpenSettingsPanel on 12.x,
which takes a numeric category id and throws on a string. Overwriting category.ID
with "Unbuffed" made category:GetID() return that string, so /unbuffed raised
"bad argument #1 to 'OpenSettingsPanel'" and never opened the panel.
The override is a widespread idiom (Ace3 still ships it) and exists so other
addons can open a panel by name, which worked back when OpenToC...