v4.11.2
What's new
GearMatic Changelog
[v4.11.2-release] - 07/22/2026
In-Game
- Tooltip text outside GearMatic's own lines keeps your font: the bold outline GearMatic uses for its lines no longer bleeds onto other lines of later tooltips (the "half my tooltip changed font" report).
- Healers and damage specs now get a real verdict on wrong-role proc trinkets instead of "has an effect, not scored": a damage proc counts as zero for a healer (and a heal proc as zero for a damage spec), so the stat comparison decides. A Restoration Shaman's auto-equip now correctly swaps a low-level Intellect trinket in over a much higher-level damage-proc epic (the Fetid Dartfrog Idol vs Gloom-Spattered Dreadscale report).
Fixed
ItemTooltipHook.lua:addLineBoldpermanently mutated the recycledGameTooltipTextLeftNfont strings withTHICKOUTLINEand never restored them, so the outline leaked onto Blizzard's and other addons' left-side lines on every later tooltip. The original font flags are now recorded per line and restored onOnTooltipCleared/OnHide(GameTooltip, both ShoppingTooltips, ItemRefTooltip).AutoEquip.lua+Scoring/V2/Compare.lua: sim data now actually drives the trinket auto-equip verdict._trinketScoreTrustedrequired a non-nilprocEff/setEff, so plain-stat pairs and scored-zero procs were never trusted and every such swap fell to the hard 13-ilvlTR.AllowsUpgradeveto, which blocked a +394% stat upgrade (frog vs Dreadscale, both unranked on the tier list). Trust is now "sim coverage exists (eval.procCoverage) and nothing on either side is un-modeled"; unsimmed flavors/specs keep the conservative ilvl/tier allowance.
Added
Scales/proc_values.lua(accessor tail, survives regen): wrong-role zero inference. An item simmed for other specs of the flavor but absent for this spec resolves to a scoredeff = 0when every known kind belongs to the other role (dps/tank-only procs for healer specs, heal/absorb-only procs for non-healers).kind="stat"procs, same-role gaps, and never-simmed items stay genuinely unknown. Closes the 249-of-274 retail (487-of-488 MoP) healer coverage hole the stat-buff-only healer pass left behind.
[v4.11.1-release] - 07/21/2026
In-Game
- Updated for the latest World of Warcraft Classic Era and Season of Discovery patch (1.15.9).
Changed
GearMatic_Vanilla.toc:## Interfacebumped from 11508 to 11509 to match the current Classic Era / Anniversary / Season of Discovery client build.
[v4.11.0-release] - 07/19/2026
In-Game
- Healers now get real values for stat-buff trinket effects instead of a "not scored" line: Gaze of the Alnseer, Diamantine Voidcore, Locus-Walker's Ribbon, and Telluric Leyblossom count their effect for all seven healer specs. The values are conservative on purpose, so a healer's Gaze scores its worth without overstating it.
Added
tools/proc-values-generate/healer_stat_procs.py: healer formula path for STAT-BUFF equip procs (SimC ships no healer profiles, so nothing can be simmed). avgStat = spell_query magnitude at ref ilvl x ICD-capped proc rate x buff duration, capped at max stacks; eff = avgStat x the spec's own weight fromScales/logic_retail.lua(primary 6.0, secondaries per power map). RPPM procs use their real rate; percent-chance procs use a documented conservative CAST_INTERVAL = 2.0 s cast cadence. Two-stage Gaze of the Alnseer (249343) is special-cased with all values from spell_query and the same single documented assumption, landing eff 490.22 (deliberately below the 938-1090 the DPS sims reach by exploiting the ICD-refresh quirk). Cross-validated: the three single-stage items land inside the 665-810 range their caster-DPS sims produced independently. 28 new healer entries; damage-triggered and damage-proc items stay honestly omitted (a healer cannot drive or use them).
[v4.10.3-release] - 07/19/2026
In-Game
- Fixed several strong trinkets, rings, necks, and cloaks being under-scored for some specs because their equip effect carried no value: 811 spec-and-item combinations now score their real simulated effect. The reported case: Balance Druids saw a Champion Crucible of Erratic Energies beat a Heroic Gaze of the Alnseer; Gaze's effect now counts (it is worth roughly seven times Crucible's) and the Heroic Gaze wins as it should. The same repair covers Light Company Guidon, Vaelgor's Final Stare, Rotmire's Sporeheart, Sporecaller's Blooming Loop, and dozens more across every spec.
- The FAQ answers a new question on every game version: how to see exactly why an item scored the way it did, and how to copy what it prints.
Changed
- The FAQ answer and
/gm helpdocument/gm score [link]and/gm audit [link](shift-click the item to add its link to the command) plus/gmc [lines], the copyable window of recent chat, for grabbing their output.
Fixed
tools/proc-values-generate/generate.py: baseline contamination in the retail proc-detection gate. The SimC MID BiS profiles equip current proc trinkets (Gaze of the Alnseer sat in many profiles' trinket2), so the item-vs-slot-empty effect-name diff came back empty for exactly the specs where the item is BiS, and the item was falsely omitted asproc_not_modeled(10 specs for Gaze alone). Detection now clears every other accessory slot in both arms, and valuation clears the paired slot on both profileset arms when the baseline profile wears the candidate item itself (a double-equip would corrupt the twin delta). The wowsims leg already stripped duplicate test items (swap_item); the SimC leg now matches.Scales/proc_values.lua: full per-spec asymmetry re-sim across all 32 non-healer retail specs, 1890 (spec, item) pairs attempted: 811 new values merged (94 modern universal-slot items plus 13 legacy Shadowlands/Dragonflight accessories that had only ever been valued for one spec), 1079 pairs confirmed unmodelable with generator-diagnostics reasons recorded in the newexclusions.retail.perspec.json. MoP audited clean (misses are role mismatches plus the known-broken Feral profile); era/tbc already protected.
Added
tools/proc-values-generate/asymmetry_check.py: per-spec coverage gate.coverage_check.pyonly asks "is the item valued somewhere"; the new gate requires every universal-slot item valued for one non-healer retail spec to be valued or diagnostics-excluded for every other one, and exits 1 per unexplained gap. Wired into the proc-values skill's mandatory validation.- FAQ key pair
faq_q_debug/faq_a_debugin all 12 locales.
[v4.10.2-release] - 07/16/2026
In-Game
- Fixed weapon upgrades in your bags being ignored:
/gm equipsaid "no upgrades to equip from bags" and auto-equip stopped swapping in strictly better weapons (a weapon looted during combat was never picked up by the after-combat check). Both now evaluate weapons again.
Fixed
AutoEquip.lua: the v4.3.x weapon-plan perf gate (_needsWeaponPlan, commit 0b663ce) skipped the weapon rescan on every full sweep once the session's first sweep clearedweaponsDirty. Two real flows fell through: (1) manual/gm equipruns as a full sweep, so weapons were never re-evaluated ("no upgrades to equip from bags" with a +42% dagger in the bag); (2) a weapon looted mid-combat queued its bag inpendingBags, but the combat-exit sweep runs full (pendingFull) and wipedpendingBagswithout scanning them, silently dropping the pending weapon. Fix: manual sweeps always replan weapons, and queued bags are captured asqueuedBagsbefore the wipe so full sweeps still run the cheap has-a-weapon scan over them. The P3 perf win is preserved (combat exits with nothing queued still skip the plan).tools/autoequip-weapon-dirty-selftest.lua: rewritten to drive the real frame event handler and the two user-visible flows (manual/gm equip, BAG_UPDATE-in-combat then PLAYER_REGEN_ENABLED full sweep) instead of only unit-testing the pure gate with hand-picked inputs; the old test asserted the broken full-sweep skip as correct behavior, which is why it never caught the regression. 16 checks, red-then-green against the fix.
[v4.10.1-release] - 07/15/2026
In-Game
- Small bug fixes.
Fixed
Scales/proc_values.lua: Drum of Renewed Bonds (248583) was excluded from the 2026-07-14 retail sweep asproc_not_modeled(SimC builds no action for its Dummy loa-picker Use effect, so all 30 sim specs returned noise), which left every ilvl variant showing the honest not-scored verdict with the stat percent suppressed. Valued via the real-data formula path (apply_248583_formula.py, same no-guesswork approach as 256326): the four loa drivers (RPPM 1.5) proc a 401.168 secondary-rating buff for 12s at the 289 reference, an average of 120.35 rating of the player-aligned secondary, folded asavg * best secondary weightfrom each spec'slogic_retail.luapower map,eff = 60.18under all 39 retail spec keys (kind matched per role: dps/tank/heal). Exclusion row removed fromexclusions.retail.json; coverage gate green (retail 153 valued + 32 excluded, 0 unexplained), full Lua suite 106/106 and all repo selftests green.
[v4.10.0-release] - 07/15/2026
In-Game
- Items with a "Use:" effect now count that effect in upgrade scores when its value is known, on every game version. This adds real scores for on-use trinkets, weapons, and necks that previously only showed their raw stats, including PvP Badges and Emblems, engineering gadgets, and TBC's enchanted pendants for warlocks.
- Items whose Use effect can't be measured now say "(use effect not counted in the score)" on their tooltip instead of the equip-effect wording, in every language.
- Fixed trinket and ring tooltips sometimes comparing a new item against your STRONGER equipped one instead of the weaker one, which could label a real upgrade as a downgrade. The comparison now accounts for each equipped item's special-effect value when picking which one you'd replace.
- Fixed the "(effect not counted in the score)" tooltip note sometimes missing for the rest of the session when an item was inspected right after logging in.
- Items whose special effect can't be measured now show a neutral "? not scored, could be better or worse" verdict instead of an upgrade or downgrade percentage, everywhere a verdict appears (tooltip rows, tooltip border, loot rolls). A stats-only percentage read like a full verdict when the item's main effect was unknown.
- Items whose effect WAS measured and found worthless keep their normal percentage: the data now records an explicit zero for them instead of leaving them unmeasured.
Fixed
Compare.luabaselineForCurrentChar: the displace-slot loop ranked two-slot candidates (trinkets, rings, weapons) by raw stat score only; a low-stat, high-proc trinket in the other slot was chosen as the "worst" baseline, so the candidate was compared against the effectively stronger item (Drum of Renewed Bonds read -33% vs the keeper instead of +25% vs the replaceable trinket). Slots are now ranked by stats plus simmed proc value; the returned baseline stays raw and the caller's proc fold is unchanged.proc_values.luaaccessor tail:ItemHasEquipEffect/ItemHasSpecialEffectcached a negative tooltip scan permanently even when the item's streamed Equip:/Use: lines had not arrived yet (cold login), suppressingprocNotScoredfor the session. Negative results are now cached only onceC_Item.IsItemDataCachedByIDconfirms the data was loaded; positives always cache.- New regression test
test_trinket_baseline_and_cold_scan.luacovers both (proc-aware displace-slot ranking, no negative caching on cold scans). - Not-scored verdict:
DisplayUpgradePctreturns 0 for evals flaggedprocNotScored/setNotScored;formatLinerenders the new localizednotscored_for_current/notscored_for_altverdict (12 locales); flagged rows still appear in the tooltip. Covered bytest_notscored_verdict.lua. - Measured-zero entries:
generate.pyandgenerate_wowsims.pynow emit expliciteff = 0rows for below-floor effects (measured worthless is scored, not unknown); era/tbc backfilled from the sweep diagnostics (+1050 vanilla, +1037 tbc zero rows, all prior entries byte-preserved).generate_mop.pydeliberately does not (its fork cannot distinguish not-modeled from measured-tiny). Coverage gate after backfill: vanilla 188 valued + 4 excluded, tbc 207 valued + 0 excluded, still zero unexplained everywhere.
Added
enumerate.pyadmits pure on-use items (only effect row is type 0) at current-expansion ids on every equippable slot, tagging pool entrieshas_use. Previously such items were undiscoverable by re-enumeration and only entered via hand-built fill configs (root cause of Drum of Renewed Bonds showing "not counted").generate.pysims any slot batch containing an on-use item against a temp press profile (use_press_profile), a copy of the spec profile withactions+=/use_item,slot=<slot>inserted directly after the firstactions=line; the stat twin never presses. The old non-trinketomitted: on_usegate is removed.generate_wowsims.pypresses on-use in every slot (era: all rows, castSpell is a no-op on proc-only items; tbc: rows withnumOnUseEffects), not just trinkets.tools/proc-values-generate/coverage_check.py: committed coverage gate. Every source-data effect item per flavor must be valued inScales/proc_values.luaor listed inexclusions.<flavor>.jsonwith a sim-measured reason; unexplained ids exit 1 item-by-item. Current state: retail 152 valued + 33 excluded, mists 484 + 6, vanilla 108 + 84, tbc 144 + 63, zero unexplained on all four flavors.- Runtime:
procNotScoredUseeval flag (Compare.lua flags entry-less candidates viaItemHasSpecialEffect),use_not_scoredlocale key in all 12 locales, use-aware wording in ItemTooltipHook.lua and/gm scoredebug output.
Changed
Scales/proc_values.luaregenerated for the missing-id sweeps: +160 retail rows (16 of 49 stale-pool ids modeled, incl. Galactic PvP trinkets, Cinch/Clasp of Unity-style DISC belts, Miniature Roulette Wheel rings), +15 tbc rows (enchanted Pendants 24092-24098 valued for warlock specs). All pre-existing entries across all four flavors preserved byte-identical at entry level (14352 -> 14527 rows).- Committed pools (
pool.full.json,candidates.dps.json,candidates.healer.json) re-enumerated from live 12.x DBC data. - Refreshed the RepMatic roster icon in the addon-family list to its new art.
[v4.9.0-release] - 07/13/2026
In-Game
- The minimap button is now on by default on every game version, Classic Era (including Season of Discovery and Hardcore), Burning Crusade, Wrath, Cataclysm, Mists, and Retail, with the same clicks everywhere: left-click opens the gear map, right-click opens settings, drag moves it around the minimap ring. You can still hide it with the "Show minimap button" toggle in General settings.
- The minimap button's hover tooltip is now translated into all supported languages.
Changed
showMinimapButtonprofile default flippedfalse->true(Core.lua). The button, its libraries (embeds.xml), and Minimap.lua load identically on all six flavors; it only appeared retail-only because that client's profile had the toggle manually enabled while every other client sat on the hidden default.
Fixed
- Minimap button tooltip lines were hardcoded English in Minimap.lua, invisible to the locale parity gate; moved to locale keys (
minimap_tip_left/minimap_tip_right/minimap_tip_drag) and translated in all 12 locales.
[v4.8.0-release] - 07/13/2026
In-Game
- Druids on Classic Era and TBC can now pick their Feral role: a new "Feral role" dropdown in the Detection settings (or
/gm feral dps//gm feral tank) tells GearMatic whether to score you as cat DPS or bear tank. The chosen role's line is marked "(current)" in item tooltips, and every surface (bags, tooltips, quest rewards, gear map) scores with the matching weights. - Fixed the Feral DPS and Feral Tank tooltip lines showing another spec's icon (for example the Balance icon); they now show the Feral tree icon.
- Fixed spec icons and the "(current)" marker missing from tooltips on non-English clients.
- Fixed a brand-new character with no talent points being treated as the first talent tree (for example Balance or Holy) in tooltips; with no points spent, no spec is marked "(current)".
- Fixed feral druids being scored with roughly-right generic weights instead of the real Feral DPS / Feral Tank stat priorities.
Added
Scales/spec_tokens.lua:ROLE_SPLITtable (vanilla/tbc DRUID tab 2 ->Feral_DPS/Feral_Tank), role-awarens.ResolveSpecToken(flavor, class, index, role), locale-independent reverse lookupns.SpecIndexForToken,ns.RoleSplitInfo,ns.RoleSplitDisplayName,ns.NormSpecToken.ScaleImport.lua: per-char Feral role store (GearMaticDB.feralRoleByChar, default "dps") behindns.GetFeralRole/ns.SetFeralRole(invalidates SpecLogic cache, BestItems, gear map scores, bag overlays on change);SI.IsCurrentSpecScale(scale, activeIdx)disambiguates role-split tabs for the "(current)" marker.- Settings: "Feral role" select in the Detection tab, hidden unless the character's class/flavor is role-split;
/gm feral [dps|tank]slash command; 7 new locale keys in all 12 locales. tools/feral-role-selftest.lua: offline coverage for specID resolution, role disambiguation, the no-points classic gate, SpecLogic role routing, and the deterministic defaults fallback.
Fixed
ScaleImport.resolveSpecIndexnow resolves through the English token table first (locale-independent); matching English scale names against localizedGetSpecializationInfoForClassIDnames never matched on non-enUS clients, so no scale ever got aspecIDthere (no spec icons, no "(current)" marker). The API-name loop remains as the wrath/cata fallback.ScaleImport.getCurrentSpecIndexno longer falls back to the rawC_SpecializationInfo.GetSpecializationshim on classic talent flavors: the shim reports tab 1 for characters with no talent points, resurrecting the v4.2.4 wrong-spec bug through the "(current)" marker path.ItemTooltipHookformatLine/formatBadge: rows for a spec with no resolvablespecIDno longer borrow the CURRENT spec's icon (the Feral-rows-with-Balance-icon bug); only the current spec's own row may, everything else falls back to the class icon.ScaleImport.findDefaultForCharpicks deterministically when several defaults substring-match the detected spec (both Feral scales match "Feral Combat"): exact spec-name match wins, then alphabetical; previously the winner waspairs()hash order. Wildcard resolution no longer misreportsresolvedSpecwhen the exact match wins.GearMap/Engine.selectScaleAndOwned: an explicit gear-map spec override now drives the scoring lens even when the current spec is unknown (no talent points spent) instead of silently falling back to the active scale.GearMap/Engine.currentSpecIDandPawnIntegration.currentSpecIndexnow route through the hardened talent-count detector instead of the rawGetSpecializationshim, which misreports leveling characters on classic flavors (Ret reads as Holy, Feral as Balance); the gear map keeps the shim as a last resort so a no-points character still gets a default lens.- Feral druid scoring on vanilla/tbc now reaches the real
DRUID_Feral_DPS/DRUID_Feral_TankSpecLogic weights: the detected role-split tab resolves a role-qualified spec token, where previously the localized tab name ("Feral Combat") matched no SpecLogic/crawled key and fell through to the legacy defaults.
[v4.7.0-release] - 07/12/2026
In-Game
- Pick your marker style. General settings has a new "Indicator style" dropdown: classic double chevrons (the default) or the up/down arrows, applied everywhere GearMatic marks gear, tooltips, bags, quest rewards, loot rolls, and alerts. Switching takes effect instantly.
- Brand-new chevron icons: green upgrade, red downgrade, and a dedicated yellow icon for gear another of your characters can use, in both styles.
- Alert icons now cast a soft drop shadow, and loadout alerts show the marker in its true colors.
- The minimap button now sits properly on the minimap ring, keeps its position, and drags smoothly around the rim, including on square or reskinned minimaps.
Added
- Per-profile
indicatorStylesetting ("chevron" default, "arrow") with a General-tab AceConfig select; new locale keys in all 12 locales.UpgradeArrow.luais the single style authority (ns.IndicatorTexture(direction)resolving up/down/alt, markup cache keyed by style). Textures/UpgradeChevron.tga,DowngradeChevron.tga,UpgradeChevronALT.tga(converted from PNG sources through the de-matte + black-shadow + margin pipeline) andUpgradeArrowALTIcon.tga.LibDataBroker-1.1+LibDBIcon-1.0embedded for the minimap button.
Changed
- BagOverlay, BuildChevronStack consumers (quest rewards, loot roll, AtlasLoot overlay), and alerts resolve indicator textures through the style API; the alt marker uses dedicated ALT icons instead of a yellow-tinted green chevron; BuildChevronStack draws square 24x24.
- Alert indicator icons get LibMatic-AlertShadow
ApplyIconShadow(black, 2/-2, strength from the font shadow setting); loadout/peer alerts dropped their cyan/steel-blue vertex tints. Minimap.luarewritten as a LibDataBroker launcher registered through LibDBIcon: correct ring placement from real minimap dimensions, square-minimap support, drag handled by the lib; saved angle migrates fromGearMaticDB.minimap.angletominimapPos.
Removed
Textures/upgrade-chevron.tga,chevron-up-green.tga,chevron-down-red.tga,Sidebar.tga(all unreferenced after the swap); the hand-rolled minimap placement math.
[v4.6.0-release] - 07/12/2026
In-Game
- Fresh new arrows. The green upgrade arrow and red downgrade arrow have brand-new custom icons with crisp black-shadowed edges, no white glow around them.
- Classic players now see the green upgrade arrow too. It previously only appeared on Retail; every flavor now shows the same arrows.
- Upgrade and downgrade percentages now match their arrow's color: bright green +% next to the green arrow, bright red -% next to the red arrow, on every tooltip line including the "2nd best" tag and other characters' lines.
Added
Textures/UpgradeArrowIcon.tgaandTextures/Downgrade-arrow-icon.tga: custom full-bleed 256x256 arrow icons, de-matted (white halo replaced with black shadow edges, black RGB under all transparent texels so mip/bilinear filtering cannot bleed white back in) and shrunk onto a 14px transparent margin so the shadow never clips at the canvas border.
Changed
UpgradeArrow.luarewritten around the new art: both directions are plain full-canvas|Tescapes /SetTexture+ fullSetTexCoord, dropping the retail-onlybags-greenarrowatlas (the up arrow now renders on classic flavors) and the old texel-crop plumbing; arrows render square at 20x20.- Tooltip percent colors now sample the arrow art itself: upgrades
42ff00, downgradesff0000in all 12 locales (was33ff33/ff5555); the alt-character upgrade percent moves from yellowffea4dto the same green; the 2nd-best badge percent moves from66c93fto42ff00(ItemTooltipHook.lua).
Removed
Textures/arrow-down-red.tgaand its crop constants;tests/lua/test_upgrade_arrow.luare-pinned to the new paths, markup, and sizes.- Hoverable gear alerts (unreleased 67d9a8e reverted in a4526e6 before shipping): alerts stay display-only.
[v4.5.2-release] - 07/11/2026
In-Game
- Fixed an error that appeared the moment you swapped a piece of equipped gear. The swap alert now shows its upgrade or downgrade verdict again instead of erroring.
- The description at the top of GearMatic's Settings window got a refresh: tighter wording that now mentions quest-reward advice, in every supported language.
Fixed
Alert.luascoreLinkcrashed on every equip swap ("bad argument #2 to 'tonumber' (number expected, got boolean)"):Score.ScoreItemreturns(score, fellBack, kind)and the open call was passed straight intotonumber, so Lua's multi-return expansion fed the booleanfellBackin as the base argument. The call is now truncated to its first return. Thealert-swap-richscoreselftest'sScoreItemmock returned a single value, which is why it never caught this; the mock now matches the real(score, fellBack, kind)shape and reproduces the crash before the fix. Audited every other -Matic repo for the sametonumber(<multi-return call>)shape: Alert.lua:631 was the only instance.
Changed
- Settings-panel description blurb refreshed (LibMatic-Settings-1.0 commit eee723a, packaged in via the LibMatic external): now mentions quest rewards, tighter copy, all 11 locales retranslated.
[v4.5.1-release] - 07/11/2026
In-Game
- Fixed a taint issue where, with GearMatic loaded, macros from other addons could get blocked by the game when they tried protected actions like setting a raid target marker (for example a RareScanner targeting macro). GearMatic no longer touches the game's slash-command table in the way that caused those "action was blocked" errors.
- Fixed an error that could appear while GearMatic captured your character's stats for its character pages ("attempt to perform arithmetic on a secret number value"). When the game hides a stat from addons, GearMatic now keeps the last value it could read instead of erroring, and picks up the real number again on the next scan where it is readable.
Fixed
Core.luareassigned the globalSlashCmdList(SlashCmdList = SlashCmdList or {}), tainting the global slot; Blizzard'sChatFrameUtil.ImportAllListsToHashreads that global inside the secure macro path on every send, so any protected call downstream (e.g.SetRaidTargetfrom a RareScanner macro click) was blocked with "action was blocked because of taint from GearMatic". The reassignment is removed; key adds intoSlashCmdListremain (that is the sanctioned taint-safe path via Blizzard's proxy import). New static regression testtests/lua/test_taint_global_reassign.luascans all shipped Lua for reassignment of taint-sensitive Blizzard globals (SlashCmdList,hash_SlashCmdList,SecureCmdList,ChatTypeInfo,StaticPopupDialogs,UISpecialFrames). Verified in-game: target-marker macro sets the skull with no taint block.Scanner.luacrashed indetectStatswhen retail's secret-values system returned secret numbers from stat APIs (UnitAttackPoweret al):type(secret)=="number"passed the guard, then thebase + pos + negarithmetic threw ("secret number value, while execution tainted by 'GearMatic'");pick()could also have stored a secret into SavedVariables. All stat readers now route through areadable()guard (issecretvalue, nil-safe on classic flavors); a secret read marks the key hidden-this-scan andScanCurrentCharacterkeeps the previous snapshot for exactly the hidden keys while readable stats still refresh (spellpower counts as hidden if any school is secret, since the hidden school could be the max). Regression testtests/lua/test_scanner_secret_stats.luasimulates secret numbers (type "number", throwing metamethods).
[v4.5.0-release] - 07/10/2026
In-Game
- Low durability now triggers a real alert instead of a chat line: an on-screen warning with the skull raid icon, a sound (defaults to Heroism Cast, changeable on the Sound tab), and your character performs a skull emote other players can see. It fires when you log in with damaged gear and again the moment your gear drops below your chosen threshold while playing, then stays quiet until you repair. Alts with 3 or more damaged items still get flagged at login, now at most once per character per day; repairing on that character resets its daily limit.
- The character-sheet pages for your other characters now show the character, not a placeholder: on Retail and Mists of Pandaria the page renders a real dressed model wearing that character's actual transmog appearance (weapons follow the same rule as the game's own dressing room, so a weapon only appears if the character you are playing could hold it), and the view starts pulled back with mouse-wheel zoom and drag-to-rotate. Classic clients try the items on a dress-up body, with a new setting to show the other character's true race and body instead (undressed, since the game cannot dress that body). Each character refreshes its saved look whenever you log in or out on it.
- Alt pages got the full Blizzard treatment: the character's name sits in the sheet header, stats show under Blizzard's category art, durability bars use Blizzard's status-bar art with a green-to-red ramp, and the page-turn arrows use Blizzard's own art (and no longer overlap the ammo slot on Classic). The floating item-level number over the header is gone.
- Equipment sets on Classic Era, Hardcore, Season of Discovery, and Burning Crusade Anniversary are now saved per character by GearMatic itself, so every character keeps its own list. Equipping a set refuses during combat like loadouts do, and hovering a set row shows what is in it.
- Characters you ignore in Settings no longer appear in the character pages or the alt browser, and the equipment set manager hides while you are viewing another character's page (sets can only apply to the character you are playing).
- New FAQ entry explaining exactly what the character preview can and cannot show on each game version.
- Changing your active stat scale now refreshes an open Browser window immediately.
Added
Durability.lua: durability trigger module. Current character is edge-triggered on the threshold crossing (re-armed by repairing, which also clears that character's once-per-day stamp inGearMaticDB.durabilityNags); alts gate on session (ns.naggedThisSession) plus a persisted per-day stamp. Outputs:Alert.ShowDurabilityWarning(createMessage path, so it lands in the LibMatic-AlertStack shared position stack with the other ILA addons),soundSettings.durabilityLow(default "Heroism Cast", new Sound-tab row), andSocial.EmitDurabilityEmote({rt8}EMOTE sharing the 25s upgrade-emote cooldown, gated by the social emote toggle; alt emote text carries theGearMatic:brand right after the skull). Test:tests/lua/test_durability_alerts.lua.PaperdollModels.lua: cached alt-model pool with backend detection. Scene backend (retail/mists): overlayModelScenefromPanningModelSceneMixinTemplate, cameras from scene 595 (SetFromModelSceneID(595, true, true), actor pool addon-owned), camera range extended one span past stock max with the start distance past the old maximum, race/sex-tagged sheet actor layout resolved fromC_ModelInfoactor infos. DressUp backend (classic):DressUpModelwithUndressSlotstrip (bareUndressinert on 2.5.6) and cold-dress passes never cached; failed dress passes never mark the fingerprint clean; LRU cap with holder reuse; per-slot cold-item retries onGET_ITEM_INFO_RECEIVEDvalidated against the dress generation.- Scanner captures the per-slot transmog look (
GetItemTransmogInfoListoff the paperdoll actor) and body display info on retail/mists; replay runs ascending slots 1-19 withignoreChildItems=falseonly on the main hand (Blizzard'sDressUpItemTransmogInfoListcontract), which fixed off-hand weapons vanishing. Classic true-body opt-in setting (localized, all 12 locales) renders the alt's real race/sex undressed. - Per-character equipment sets (
EquipSets/CharSets.luastore): the vanilla/TBC set manager pivoted from the nativeC_EquipmentSetengine (which shares sets account-wide on those clients) to a per-character GearMatic store; engine layer removed,ApplyEntryshared between loadouts and sets, combat guard on equip, row tooltips from per-char data, nil-charKey refusal and unified item equality in the store. - Equipment-manager alt-view gate: GearMatic's Era/TBC panel and Blizzard's MoP/retail sidebar manager both suppress while the paperdoll shows an alt and restore on the self page (
tests/lua/test_paperdoll_equipmanager_gate.lua). - FAQ: per-mode
faq_q_altmodelentry (scene/dressup/classic answer variants) in all 12 locales. /gm pdbgprints scale/layout/zoom state and per-slot transmog replay results for the live alt page.
Fixed
- MoP/retail alt pages rendered only a giant weapon from a default camera: the overlay scene now carries
ModelSceneMixinvia the sheet template and pulls the character-sheet cameras. Two follow-up camera fixes:ZoomByPercentnudges cannot pass the stock maximum (the sheet camera boots at max distance), so the range itself is extended. - Alt browser and character pages honor
GearMaticDB.altUpgradeIgnores(the Settings ignore list); the deadGearMaticDB.ignoredtable is no longer consulted. - Transmog replay order was hash-order (
pairs), which reset the weapon complement when the main hand applied after the off hand; now deterministic ascending with the Blizzard child-items rule. - Alt stats overlay classic's
CharacterAttributesFrame; scale activation refreshes the Browser window; next-page arrow anchors after the classic ammo slot.
Changed
Scanner.RunLoginNag(chat print) removed; login alt warnings route throughDurability.CheckAlts. Locale keyslogin_nagandsettings_show_login_nagreplaced bydura_alert_self/dura_alert_other/dura_emote_selfandsettings_durability_alerts(+_desc)/settings_sound_durabilityin all 12 locales.
[v4.4.0-release] - 07/10/2026
In-Game
- Classic Era, Hardcore, Season of Discovery, and Burning Crusade Anniversary characters get a real Equipment Manager: a gear button on the right side of the character sheet, above the gloves slot, opens an equipment sets panel just like the one Mists of Pandaria has. Save your current gear as a named set with an icon, equip a whole set in one click (or double-click), edit its name and icon, and delete sets you no longer need. While the panel is open, arrows next to each equipment slot let you exclude that slot from the set you are saving. Sets are stored by the game itself, so they survive reloads and even work with macros other tools create. Shirts and tabards are left out of new sets by default, and a set that is missing items shows its name in red.
- Gear you already have equipped that ranks best or second best for a spec now shows just the "best in slot" / "second best" label, with no upgrade percent next to it. Off-spec upgrade percents on equipped gear are unchanged.
Added
- EquipSets module (vanilla + tbc TOCs only):
EquipSets/NativeSets.luadata layer over the nativeC_EquipmentSetengine API that Era/HC/SoD (1.15) and TBC Anniversary (2.5.6) clients ship WITHOUT any Blizzard UI (verified against the classic_era and classic_anniversary wow-ui-source branches plus an in-game probe);EquipSets/Panel.luaMoP-style side panel (row list with equipped check, missing-items red, zebra stripes, hover delete/edit, add-new row under the 10-set cap, Equip/Save enable rules, swap-finished auto-select, coalesced repaints);EquipSets/EditDialog.luacreate/edit popup on the client's IconSelectorPopupFrameTemplate with native commit rules and a GearMatic-owned overwrite confirm (the client's own overwrite dialog OnAccept references a Wrath-only frame and would error on these flavors);EquipSets/Toggle.luapaper-doll button at Blizzard's own gear-button anchor (TOPRIGHT -44,-39, above the hands slot);EquipSets/EquipSets.xmlrow template (Char-Paperdoll-Parts caps, Char-Stat-Middle fill, zebra, hover/chosen bars, equipped check). The panel pins Blizzard's Mists pane geometry exactly (172x331 list, 87x22 buttons, 169x44 rows, WowScrollBoxList + MinimalScrollBar) inside a DialogBorderTemplate + InsetFrameTemplate shell with its own header band, no close-button socket. The edit dialog parents to PaperDollFrame (the icon-selector template anchors TOPLEFT to its parent's TOPRIGHT) and rebinds OnShow/OnHide after installing instance-method overrides so the icon grid actually receives its IconDataProvider. On these flavors the native manager replaces the GearMatic Loadouts sidebar entirely (Loadouts/Toggle.lua,Loadouts/Sidebar.lua), and the per-slot flyout (Loadouts/SlotFlyout.lua) routes ignore-slot state to the engine's save mask (IsSlotIgnoredForSave/IgnoreSlotForSave). Set IDs are zero-based; all selection state is nil-checked. Selftests:tools/equipsets-nativeapi-selftest.lua,equipsets-panel-selftest.lua,equipsets-editdialog-selftest.lua,equipsets-flavorgate-selftest.lua,equipsets-mop-geometry-selftest.lua,equipsets-supersedes-loadouts-selftest.lua,equipsets-slotflyout-gate-selftest.lua.
Fixed
- Tooltip badge rows (
ItemTooltipHook.luaformatBadge): suppress the chevron and+N%suffix when the hovered item is currently equipped; the percent came from the weaker twin baseline in dual slots (rings/trinkets/weapons) and read as a phantom upgrade on gear already worn. Non-equipped badge rows keep their percent. Covered bytools/tooltip-equipped-badge-nopct-selftest.lua.
[v4.3.0-release] - 07/10/2026
In-Game
- GearMatic now tells you in chat when a newer version is available on CurseForge, spotted automatically from other players running a newer build.
- Loadout safety: applying a loadout now correctly removes gear from slots the loadout saved as empty (and honestly reports it), clicking a gear swap or "Place In Bags" while you are already holding an item no longer risks equipping the held item into that slot, a failed ring or weapon swap now retries instead of timing out the whole apply, and the loadout sidebar comes back after combat instead of staying hidden.
- Pasting a corrupted loadout import string now shows the normal import-failed message instead of a Lua error.
- The upgrade/downgrade alert when you equip an item now uses the same full scoring as the tooltip (procs, trinket tiers, set bonuses included), so it no longer contradicts what the tooltip just told you.
- The Baganator upgrade badge now actually works (it had never fired due to a wiring mismatch with Baganator's API).
- Quest reward upgrade chevrons now appear even for items your game client has never seen before.
- Best-in-slot skulls on the character sheet now update immediately when you change specialization.
- Mousing over a player whose name matches one of your characters on another realm no longer risks showing the wrong character's item level and durability.
- The gear map no longer takes over your open Adventure Guide window while it scans; it politely waits until you close it.
- Deleting your active stat-weight profile now immediately refreshes all recommendations instead of leaving stale scores.
- The "Show other characters in tooltip" checkbox now correctly greys out when tooltip detection is off.
- Auto-repair with guild funds now verifies the repair actually happened before reporting success.
- Upgrade chevrons and best-in-slot skulls now work reliably in every actively maintained bag addon: Bagnon, Bagnonium, Baganator, ArkInventory, BetterBags, ElvUI bags, Inventorian, Sorted, and LiteBag. Bag windows that open without going through the standard Blizzard bag functions (BetterBags, Inventorian) previously never got their items marked.
- Bank markers now also appear on modern Retail clients where the bank window signals its opening differently than classic clients.
- Changing specialization now immediately repaints the bag markers (including inside Baganator) instead of waiting for the next bag change.
- Low-level characters with no talent points spent now see their class name in tooltip upgrade lines instead of a question mark where the spec would be.
- Fresh characters with no talents get upgrade markers again: with no spec to detect, GearMatic now scores against your class's standard leveling spec (for example Retribution for a new Paladin, Frost for a new Mage) on every game version, instead of showing nothing until your first talent point. Your real spec takes over automatically the moment it is detected.
- Plain white leveling armor (no stats, just armor) now gets upgrade verdicts: an armor piece for an empty or weaker slot is marked as an upgrade, a slot already covered by equal armor is not, and when choosing between plain armor quest rewards the piece that actually improves its own slot wins, with more armor breaking ties. Previously these items all scored zero and fresh characters saw no chevrons on early quest rewards at all.
- Fixed GearMatic not loading at all on Burning Crusade Anniversary realms after the 2.5.6 client patch (the addon was flagged out of date).
Fixed
Loadout apply plan (
Loadouts/Equip.lua): unequip-to-empty generalized beyond the two-hander case with summary counting; ClearCursor before all pickup sequences (alsoLoadouts/SlotFlyout.lua); C_Timer retry driver for slot-to-slot step failures; PLAYER_REGEN_ENABLED sidebar restore (Loadouts/Sidebar.lua); Store.Import field-shape validation (Loadouts/Store.lua).Alert scoring parity (
Alert.lua): scoreLink routes through Score.ScoreItem plus ProcValues/SetBonusValues via the exported EquippedSetCount helper.Audit parity (
Debug/Score.lua): remapped Attack Power shown as contributing with its redirected weight; Wrath overcap halving applied to per-stat contributions (audit's overcap check skips the post-swap projection, conservative by design).Baganator upgrade callback signature (
BaganatorIntegration.lua): Baganator passes a bare item link, not a details table; the badge had never functioned. Test updated to the real contract.Quest reward retry (
QuestRewardHook.lua): GET_ITEM_INFO_RECEIVED registered during quest UI display, mirroring LootHook.BiS marker (
BiSMarker.lua): talent/spec-change events drive a debounced RefreshEquipped; CANCEL_ALL_LOOT_ROLLS wipes roll state.Unit tooltip realm safety (
UnitTooltipHook.lua): name collisions prefer the player's realm and show nothing when ambiguous.Encounter Journal respect (
GearMap/Providers/Journal.lua): scans pause while the player's EJ window is shown and resume on close via an OnHide nudge; empty instance/difficulty combos memoize once confirmed empty after loot data arrived; per-key loot generation counter replaces the shared dirty flag so no cached view starves another (GearMap/Loot.lua); AtlasLoot overlay installs on late ADDON_LOADED (GearMap/AtlasLootOverlay.lua).Settings (
Settings.lua,Browser.lua): deleting the active profile invalidates all score caches; showOtherCharsInTooltip disabled-state matches its runtime gate; duplicate AceConfig order resolved; Browser.Refresh empty branch updates nav buttons.Release gates (
release.sh): aborts without an in-game popup entry for the shipping version, aborts when the TOC version is already tagged, aborts if the locale-parity gate extracts implausibly few enUS keys; new --check-only mode runs all gates without packaging.Bag-addon discovery (
BagOverlay.lua), source-audited against every active bag addon: toggle hooks self-heal when a bag addon destructively replaces the Blizzard bag globals (Inventorian's RawHook, ArkInventory load order); banker interactions arm bank discovery via PLAYER_INTERACTION_MANAGER_FRAME_SHOW/HIDE alongside the legacy BANKFRAME events; the 2s poll runs an incremental frame-discovery heartbeat (combat-skipped) so windows opened through override keybindings (BetterBags) are still found; buttons created hidden in frame pools are registered structurally and decorated when shown; the poll keeps refreshing while only a third-party bag window is visible. Test:tools/bagoverlay-thirdparty-discovery-selftest.lua.Spec-change nudge (
Core.lua,Settings.lua): talent/spec events invalidate bag verdicts and request BagOverlay plus Baganator refreshes; the alt-ignore surface refresh nudges Baganator too.Weapon-type rules now work on every language client. On French, German, Spanish, Italian, Korean, Russian, Portuguese, and Chinese clients, GearMatic could recommend or auto-equip a weapon type your spec should never use (for example a two-hander on a Protection Paladin), because the rule lookup only understood English spec names. All clients now enforce the same weapon rules.
Fixed the wrong specialization being used in three more places on Classic Era, Burning Crusade, Wrath, and Cataclysm realms for non-max-level characters: off-spec item gating, the spec icon shown in item tooltips, and Pawn scale targeting now all read your real talent spec, matching the v4.2.4 scanner fix.
Restored stat caps and haste targets that had gone missing from several specs' gear advice: Mists Frost Mage crit (28%) and haste (14,242) targets, Balance Druid, Restoration Druid, Mistweaver, and Brewmaster haste breakpoints, Guardian Druid and Brewmaster tank expertise (15%), Classic Era Enhancement crit, and Retail Outlaw Rogue, Protection Paladin, Blood Death Knight, Elemental Shaman, and Frost Mage caps.
Hit and expertise gear is no longer undervalued on Mists, Burning Crusade, and Classic Era realms. A rating threshold meant only for Wrath was being applied everywhere, so characters far below the real hit cap had hit items scored as if the stat were nearly worthless.
An item that would fix an over-capped stat is now scored correctly. Previously a replacement with less hit rating was still penalized as "over cap" because the check counted the very item it would replace.
Checking a gear upgrade during combat no longer briefly inflates hit or expertise weights when the game protects combat data.
Reforge advice now counts the full benefit of reforging away from a stat your spec actively avoids.
Items with a flat Attack Power bonus (old-expansion and Timewalking gear) now score their Attack Power on Retail instead of ignoring it.
Empty meta sockets no longer inflate an item's score as if they were regular gem sockets.
Fixed huge nonsense percentages (thousands of percent) on upgrade comparisons for low-stat items in any slot, not just trinkets.
The "switch to loadout?" popup no longer appears out of nowhere right after logging in or reloading. It now only offers when your spec actually changes.
Gear data saved at logout no longer keeps a stale snapshot of a just-equipped item, so alt gear comparisons at login are accurate.
Performance: much less work while your bags sit open (the addon no longer rescans the whole interface every few seconds), less CPU after every fight (weapons are only re-evaluated when a weapon actually changed), faster repeated item tooltips, and an idle check that no longer grows more expensive the longer you play.
Fixed
- Locale-independent weapon rules (
Scales/spec_weapon_rules.lua):WeaponRuleForScaleresolves rules byscale.specTokenfirst (with the localized-name lookup kept for legacy saved scales), andActiveWeaponRulederives the token vians.ResolveSpecToken. Regression testtools/weapon-rule-locale-selftest.lua. - Spec detection reuse (
Scoring/V2/Gate.lua,ScaleImport.lua,PawnIntegration.lua,ItemTooltipHook.lua): all four sites route throughns.DetectSpecName(talent-point-hardened in v4.2.4) instead of the rawGetSpecializationshim. Regression teststools/spec-detect-reuse-selftest.lua,tools/tooltip-spec-icon-classic-selftest.lua. - Restored crawl-verified caps/breakpoints lost in the v3.3.0 power-map re-author (
Scales/logic_vanilla.lua,logic_retail.lua,logic_mists.lua), validated per spec againsttools/speclogic/data/*.json; Guardian/Brewmaster repointed from MHIT to THIT per the guide data.tools/speclogic-softcap-selftest.luapasses again. - Flavor-gated rating ceilings (
Scoring/V2/Score.lua): the flatns.RatingCeilingsnumbers (Wrath-authored) now apply only on Wrath; percent-based SpecLogic caps own the other flavors. Testtools/ratingceiling-flavor-gate-selftest.lua. - Overcap projection (
Scoring/V2/Score.lua):isStatPastCapsubtracts the replaced item's stat contribution (exact for single-slot locations, conservative minimum for rings/trinkets/1H). Testtools/statpastcap-swap-projection-selftest.lua. - Secret-value cap reads (
Scales/speclogic_weights.lua): a failed/protected rating read reuses the last successfully-read cap state instead of always assigning the max under-cap weight; the never-read fallback keeps the historical under-cap assumption so offline gearcheck profiles are unchanged. Testtools/speclogic-cap-secret-fallback-selftest.lua. - Reforge negative-weight clamp removed (
Scoring/V2/Score.lua);tests/lua/test_gearmap_reforge_clamp.luaupdated to the true unclamped values. - Retail Attack Power extraction (
Scoring/V2/StatExtract.lua): the blanket post-merge AP deletion is gone, soScore.lua's AP-to-primary-stat remap actually runs. Testtools/statextract-retail-ap-remap-selftest.lua. - Meta sockets (
Scoring/V2/Sockets.lua): excluded from the best-colored-gem valuation pool. Testtools/sockets-meta-value-selftest.lua. - Percent-delta explosion (
Scoring/V2/Compare.lua): denominator floor inpercentDeltaplus a generic small-baseline display cap at everystatDeltasite, replacing the trinket-only clamp (closes the long-open armor percentDelta case). Testtools/statdelta-small-baseline-cap-selftest.lua. - Login popup guard (
Loadouts/SpecHook.lua): first spec detection each session primes silently; the switch offer fires only on a real in-session spec change. Testtools/spechook-login-selftest.lua. - Logout scan (
Core.lua,Scanner.lua): the PLAYER_LOGOUT scan runs synchronously, schedules no dead retry timer, and failed slot reads keep last-known-good data. Testtools/logout-scan-selftest.lua.
Added
- Cross-player update notices via LibMatic-VersionCheck (
Core.lua,update_availablekey in all 12 locales).
Changed
- Performance:
BagOverlay.luaframe discovery is incremental viaEnumerateFrames(lastSeenFrame); the idle poll skips the button registry when no container is shown and prunes orphaned buttons;AutoEquip.luagates weapon replanning on a weapon-dirty flag;ItemTooltipHook.luamemoizes link fingerprints (capped, wiped on equipment change). - Consolidation: item-link-to-itemID extraction unified on
Compat.ItemIDFromLink(~29 hand-rolled copies removed, two of which silently dropped negative Classic item IDs);stripEnchant/pawnUnenchantedScorenow live once inScoring/V2/Init.lua; class colors unified onns.ClassColorHex; the three hand-rolled refresh debouncers now shareCompat.NewDebounce(pending flag can no longer wedge on error); the three/gm clearhandlers share one predicate helper; the near-max-level ceiling rule isCompat.NearMaxLevelHeadroom; BiS suppression is folded into pick finalization; both gear-map ilvl ceilings derive from one shared function. - Dead code removed:
Scales/logic.lua(superseded by the per-flavorlogic_*.luafiles; all offline tests repointed and green) andGearMap/LootIndex.lua(no production callers). AutoEquip.lua's upgrade-decision pyramid refactored into guard-clause helpers; behavior verified unchanged by the full selftest battery.- Docs and changelog cleaned of em/en dashes.
[v4.2.5-release] - 07/09/2026
In-Game
- Fixed auto-equip repeatedly swapping your first trinket back and forth instead of settling. When both of your trinkets were proc or on-use trinkets, GearMatic could not tell them apart and kept targeting the left trinket slot over and over. It now compares both trinkets by their real value (including their proc) and replaces the genuinely weaker one, or fills an empty trinket slot first.
Fixed
- Trinket slot selection (
AutoEquip.luafindBestSwapForLink): the picker ranked trinket slots byGetEquippedScoreForChar, which is passive-stat only, so two proc/on-use trinkets both scored ~0, tied, and slot 13 always won, GearMatic kept evicting the left trinket (the "swaps slot 1 over and over" report). It now values each equipped trinket by passive score plus its proc value (ProcValues.Eff), treats an empty slot as the best target, and breaks ties by worseTrinketRankthen lower item level. Non-trinket slotting is unchanged. Regression testtools/trinket-slot-picker-selftest.luaruns the real picker via upvalue extraction.
[v4.2.4-release] - 07/08/2026
In-Game
- Fixed GearMatic reading the wrong specialization on non-max-level characters on Classic Era, Burning Crusade, Wrath, and Cataclysm realms, for example a Retribution Paladin showing as Holy, an Enhancement Shaman as Elemental, or a Fury Warrior as Arms. It now reads your talent spec correctly at every level, so gear recommendations and auto-equip match your real spec on your leveling alts too. Each character corrects itself the next time you log into it.
Fixed
- Spec detection order (
Scanner.lua): on classic flavors (vanilla/tbc/wrath/cata) the talent-point count is now authoritative andC_SpecializationInfo.GetSpecializationis not consulted. On TBC Anniversary that shim exists but returns tab index 1 for non-max characters, sodetectSpecName(which tried it first) mis-detected every non-max alt as its class's first tab (Retribution read as Holy, Enhancement as Elemental, Fury as Arms); the correct point count never ran. Retail/MoP still use the specialization API, and the talent-first path is flavor-gated so MoP is never misrouted. This is the actual root cause behind the v4.2.3 reports; the locale/token work from v4.2.3 was correct but sat downstream of this. Regression testtools/spec-detect-order-selftest.luareplays the live paladin dump (fails before, passes after).
[v4.2.3-release] - 07/08/2026
In-Game
- Fixed GearMatic sometimes reading the wrong specialization on Burning Crusade, Wrath, Cataclysm, and Classic Era realms, for example treating a Retribution Paladin as Holy and auto-equipping Intellect gear. It now reads your talent spec correctly.
- Non-English game clients now get the correct spec-specific stat weights instead of a generic fallback, so French, German, Spanish, Italian, Korean, Russian, Portuguese, and Chinese players get the same tailored gear advice as English players. This also covers trinket-proc value and tier-set bonus scoring for your spec.
- A saved gear profile from a different specialization no longer overrides your current spec's recommendations. A profile you picked by hand for the current spec still sticks.
Fixed
- Spec detection on classic talent-tab clients (
Scanner.lua):GetTalentTabInfois read positionally and coerced withtonumber, since Anniversary/Classic servers can returnpointsSpentas a string, which the old type-sniffing scan silently rejected, leaving the spec stuck on a stale value (the reported Retribution-as-Holy case). Handles both the legacy name-first and the modern id-first return shapes. - Locale-independent spec keying (
Scales/spec_tokens.lua,Scanner.lua,ScaleImport.lua): detection now stores a canonical EnglishspecToken(from the talent-tab/spec index) alongside the localizedspec;findSpecLogicForChar/findCrawledForCharprefer the token so non-enUS clients resolve the sameCLASS_Specweights as enUS. Covered bytools/spec-tokens-selftest.lua(262 assertions verifying every token against real keys). - Proc and set-bonus keying (
Scales/proc_values.lua,Scales/set_bonus_values.lua,Scoring/V2/Compare.lua):PV.SpecKeyFor/SB.SpecKeyForpreferspecToken, so the sim-derived proc and tier-set values also resolve on non-enUS clients. - Spec-aware active scale (
ScaleImport.lua,PawnIntegration.lua):GetActiveScalegates every bag-scale return onscaleAllowedForSpec, so a stale off-spec pinned/auto scale no longer masks a confidently-detected spec; tokenless manual pins remain honored, and Pawn/plugin scales now stampspecToken.
[v4.2.2-release] - 07/07/2026
In-Game
- Set bonus scoring is more accurate on weapons and rings. Wearing two pieces of a weapon set, or comparing a two-hander against a matched set weapon, no longer double-counts or misreads the set bonus, and hovering one of your own set rings no longer shows a fake upgrade over your other ring.
- Items marked best or 2nd best now show their upgrade percentage and the green upgrade border again when they are also an upgrade over what you have equipped.
- Auto-equip no longer swaps in a lower-value trinket or bounces back and forth between two trinkets. It keeps the one that actually scores highest for your spec, and it will not pull a strong on-use trinket for a lower one it cannot fully measure.
- Auto-equip reliably catches a freshly looted or mailed upgrade even hours into a session, and no longer gets stuck ignoring new upgrades because of one item whose data never finished loading.
- The on-screen equip alert now shows a capped percentage for a big upgrade over weak gear, instead of just saying equipped. A truly worthless previous item still shows a plain equipped line.
- The yellow "another character can use this" marker no longer shows on a bound item sitting in your bank, and it now correctly hides on bound items on Burning Crusade, Wrath, and Cataclysm realms.
- Smoother performance while looting with your bags open and right after login.
Fixed
- Set-bonus fold (
Scoring/V2/Compare.lua): replaced the per-item marginal with a jointSetFoldDeltavaluation that empties the swapped slot(s) and holds all other slots as one shared baseline. Fixes the two-hander off-hand counting itself (slot 16 vs 17 exclusion), a dual-wield same-set pair double-counting the 2pc, and a two-slot (ring/trinket) candidate crediting itself a phantom marginal via its sibling slot. - Tooltip badges (
ItemTooltipHook.lua): best/2nd-best rows now compute their eval, so a badged item that is also an upgrade shows its percent again and re-triggers the green upgrade border (both were silently lost when the badge branch skipped the evaluation). - Trinket auto-equip (
AutoEquip.lua,Scoring/V2/Compare.lua,Scales/proc_values.lua):_trinketScoreTrustedis now two-sided (candidate or equipped modeled), the swap decision runs on the proc/set-inclusiveeval.delta, and a newPV.ItemHasSpecialEffect(Equip:/Use: detection) drives abaseProcNotScoredflag so the ilvl/tier veto is only bypassed when both trinkets are fully measured. Stops equipping a worse trinket, the two-trinket ping-pong, and displacing an unmeasured on-use trinket. - Auto-equip cold-cache retry (
AutoEquip.lua): the retry budget resets when a full sweep sees more uncached items than before, so a permanently-unresolving item can no longer pin the counter and starve later cold-cache upgrades of retries. - Equip alert (
Alert.lua): the junk-baseline suppression now also requires a near-zero baseline score, and the non-trinket display ceiling dropped from 999 to 200, so a real but weak previous item shows a capped percentage instead of a bare equipped line. - Alt (yellow) marker (
BagOverlay.lua,Scoring/V2/Gate.lua): bank/warband buttons now resolve their bag/slot so the bound-item demotion runs there, a shared gate closes theMarkerVerdictalt leak, and a newGate.SlotShowsSoulboundtooltip-scan fallback aligns the bag marker with the item tooltip on flavors withoutC_Item.IsBound(Burning Crusade, Wrath, Cataclysm).
Changed
- Performance: the equipped set-piece scan is built once per evaluation and gated behind set-bonus support (
Compare.lua); cold-cache retries re-check only the bags that held uncached items (AutoEquip.lua); oneGetItemInfoper bag slot per sweep instead of three; the tooltip soulbound scan is now lazy; andGate.CanSendToAltAtno longer duplicates its own bind lookups.
Internal (tooling, not shipped)
- Set-bonus coverage proofs (
tools/set-bonus-generate/coverage_*.py) now exit non-zero when any threshold is missing-with-no-reason, and their docstrings/reason labels were de-drifted (coverage_tbc.pyno longer says "Vanilla"). tools/proc-values-generate/parse_existing.pyasserts its parse count matches the file's entry-line count, so a future emit-format change can no longer silently truncate the preloaded baseline;merge_retail.pymembership test is now O(1);AutoEquip.itemInfoInstantis pcall/type-guarded.- Removed duplicate/orphan set-bonus artifacts (
_diff_tbc.py,sets.tbc.new.json,sets.tbc.healers.json,entries.tbc.healers.json) after verifying their data was preserved in the canonical files. - Full findings in
docs/code-reviews/2026-07-07-sim-tooling-v4.1-v4.2.1-review.md. Proc and set-bonus value tables are unchanged (no re-sim).
[v4.2.1-release] - 07/07/2026
In-Game
- Auto-equip is now more reliable at catching an upgrade right after you log in or reload, including cases where it could previously miss one while your bags were still loading.
Fixed
- Auto-equip's post-login/reload cold-cache retry is now self-healing: it re-arms instead of being silently dropped when a sweep is already running, it retries after partial bag updates too (not only full sweeps), and it only retries for genuinely equippable items (checked via
C_Item.GetItemInfoInstant, which reads the slot without waiting on the item cache), so a bag of uncached consumables or reagents no longer triggers needless re-sweeps. Retry budget resets on each login. (AutoEquip.lua.)
Internal (tooling, not shipped)
- Set-bonus completeness proof (
tools/set-bonus-generate/coverage_*.py) no longer fabricates a reason for a set or threshold with zero evidence; it now reports it as missing, so a genuinely dropped set can actually fail the proof instead of always reading "0 missing." tools/proc-values-generate/run_retail_chunks.shnow fails loud (exit 3) on a missing or empty order file instead of printing "ALL CHUNKS PRESENT" and exiting 0.
[v4.2.0-release] - 07/07/2026
In-Game
- Trinkets are now equipped by their real value, not just item level. Auto-equip picks the trinket that actually scores highest for your spec, so if a trinket's Equip effect makes it better, GearMatic will equip it even at a slightly lower item level (for example the Fetid Dartfrog Idol over a higher item level stat trinket). Trinkets whose effect cannot be measured still follow the guide's tier list to stay safe.
- More items with an Equip effect now count in your scores, including current-season trinkets that used to show "effect not counted."
- Set bonuses on Mists of Pandaria, Burning Crusade, and Classic Era are fully scored now, and a set bonus is never credited to the wrong class or armor type.
- The yellow "another character can use this" bag marker no longer shows on a bound item you cannot actually send to an alt.
- Auto-equip now reliably checks for upgrades right after you log in or reload, even before your bags finish loading.
Added
- Item 256326 "Fetid Dartfrog Idol" plus 485 other current-content (Midnight) equip-proc items are now valued and folded into scores. 256326's proc is a Create-Area-Trigger that SimulationCraft cannot model, so it is valued via a real-spell formula (per-hit scaled damage x RPPM-derived rate through each rogue spec's Agi damage anchor) instead of a twin sim.
- Set-bonus threshold completeness across all four flavors: every set and every piece-count threshold is now valued or reason-omitted (retail 26/26 valued; mists, tbc, vanilla proven with 0 missing-with-no-reason). Coverage proofs committed under
tools/set-bonus-generate/threshold_coverage.<flavor>.json.
Changed
- Auto-equip now trusts the simmed, proc- and set-inclusive score for trinkets. A lower-item-level trinket whose modeled proc or set bonus makes it clearly score higher (>= your minimum-upgrade percent) now clears the
TrinketRankilvl/tier veto and auto-equips. Trinkets whose effect is not modeled (on-use actives, unscored/area-trigger procs, or any stat-only fallback) still defer to the conservative ilvl/tier rule, so an unmeasured trinket never drives a bad swap. (AutoEquip._trinketScoreTrusted/_trinketScoreClearsinAutoEquip.lua; locked bytools/autoequip-trinket-guard-selftest.lua.)
Fixed
- The bag alt-upgrade (yellow) chevron no longer appears on a Bind-on-Equip item that has actually bound in the slot. The item template still reads BoE, so the link-only
CanSendToAltkept lighting it yellow while the tooltip correctly hid the alt rows; the bag overlay now checks the real instance viaC_Item.IsBound(Warband binds stay sendable). NewGate.CanSendToAltAt+ bag-slot resolver, locked bytools/gate-send-to-alt-selftest.lua. - Auto-equip no longer silently misses upgrades on a cold login or reload: the sweep now retries (bounded) while bag item data is still uncached, requesting the data as it goes, so an upgrade sitting in your bags is caught once its data loads.
- Set-bonus data corrections: removed cross-class / wrong-armor healer pollution (vanilla 14 bogus entries; TBC Holy Paladin dropped, armor-type gate added to the generator); Cryptstalker Armor (setID 530) 6pc/8pc are now attempted with a full-slot Hunter carrier and correctly reason-omitted as measured noise.
[v4.1.0-release] - 07/07/2026
In-Game
- Tier set bonuses and other multi-piece set bonuses now add real value to an item's rating. GearMatic sims each set bonus for your class and spec ahead of time and folds it into the score, so a piece that completes or extends a set bonus is judged on what the bonus is actually worth, not just its own stats. Works on retail and on Mists of Pandaria, Burning Crusade, and Classic Era realms.
- When a set bonus cannot be valued reliably, the item's tooltip says the set bonus is not scored instead of guessing. A new FAQ entry in Settings explains set-bonus scoring.
- The on-screen equip alert no longer flashes a broken number when you equip something over weak or empty gear; it shows the item as equipped instead. When the new item scores about the same as what you had, it now says similar. Real upgrades and downgrades still show their percentage.
- Fixed the best and 2nd-best markers not showing on rings, trinkets, and dual-wield weapons.
- Soulbound items no longer show other-character comparison lines or an other-character upgrade marker they should not.
Added
- Simulated set-bonus scoring. Set piece bonuses (tier 2pc/4pc and other multi-piece set bonuses) are valued and folded into item scores as a contextual marginal, the same way equip procs and trinkets are. Each set bonus is simmed ahead of time per class/spec (retail via SimulationCraft's native
set_bonustoggle; Classic Era, TBC, and Mists via WoWSims twin-pair valuation), converted to weighted score points, and stored per flavor inScales/set_bonus_values.lua. Runtime fold inScoring/V2/Compare.luacounts equipped set pieces excluding the evaluated slot and adds the marginal unlocked-bonus delta to both candidate and baseline, likeprocEff. Healer set bonuses a dps sim cannot measure use a deterministic stat-delta (Classic) or throughput proxy (retail); ones that still cannot be measured are honestly omitted. SBruntime module and accessor API (SB.data,SB.itemSet,SB.UnlockedValue,SB.EquippedSetCountsupport), TOC registration.- Honest
set_bonus_not_scoredtooltip line (all 12 locales) for a set piece whose set is not modeled for the current spec. - FAQ entry explaining set-bonus scoring (all 12 locales).
alert_similarstring (all 12 locales) for the new "similar" equip alert.- Offline set-bonus generation toolchain under
tools/set-bonus-generate/(retail SimC toggle generator, WoWSims twin-pair generator, enumeration, emit, coverage), plusset-bonus-values-selftest.luaandset-fold-selftest.lua.
Changed
- The on-screen equip alert no longer shows a bogus percentage on any slot. When the item you had scored almost nothing (an empty or vendor-tier baseline), the alert shows the item plainly with an up arrow instead of the clamped 999% sentinel; the earlier fix only covered trinket slots, so weapons and other slots still blew up. A swap that scores about the same now reads "similar" instead of "+0%". Real upgrades and downgrades still show their percent. (
Alert.SwapPct,Alert.OnEquipSwap,Alert.ShowGearSimilarinAlert.lua; locked bytools/alert-swap-pct-cap-selftest.lua.)
Fixed
- Best/2nd-best badge no longer missing on rings, trinkets, and dual-wield weapons; it was over-removed in the v4.0.0 tooltip overhaul and is now restored gated to
BestItems.RankAppliesToSlot. - Soulbound items no longer show alt-character comparison rows (
ItemTooltipHook) or a bag alt-upgrade marker (BagOverlay); a bound BoE previously leaked past the type-only gate. Fixed via a live-tooltip Soulbound-line scan (Gate.TooltipShowsSoulbound) and aGate.CanSendToAltgate on the bag marker. - The new "similar" equip alert passed its chevron tint as a color-code string instead of a color table, which errored in
SetVertexColor; it now passes the raw color table.
[v4.0.1-release] - 07/06/2026
In-Game
- Fixed the on-screen upgrade alert sometimes flashing a wildly wrong number, like tens of thousands of percent, when you equipped a big upgrade over weak or best-in-slot gear. It now shows the correct upgrade percentage.
Fixed
- The on-screen equip alert computed its percent from
Scoring2.ScoreItem, which for a best-in-slot item returns the synthetic BiS ranking score (a large sorting number, not stats), so equipping a BiS or much-stronger piece produced an absurd percent (the "60000%" blowup). It now scores prior vs new gear withScore.StatScore(the real weighted stat score, no synthetic leak) and clamps the result to 999 as a safety net (Alert.SwapPct,Alert.OnEquipSwapinAlert.lua). Locked bytools/alert-swap-pct-cap-selftest.lua.
[v4.0.0-release] - 07/06/2026
In-Game
- Items with an Equip effect, like a proc that deals damage, heals, or shields you, now carry real value in GearMatic's scores. Each proc's worth is simmed ahead of time with SimulationCraft and WoWSims for your exact class and spec, so a proc item is no longer judged on its raw stats alone.
- Weapon and shield procs are valued too, matched to what your spec can actually use. A proc that does nothing for your spec no longer inflates a weapon's score.
- Healing and absorb procs count for every healer spec, so a shield proc on a ring is real score for your Discipline Priest instead of ignored text.
- On Mists of Pandaria Classic, the legendary back cloaks' procs are now valued for every damage and healer spec, simmed with SimulationCraft's Mists engine.
- On Classic Era (including Season of Discovery and Hardcore), weapon and armor procs like Ironfoe, Thunderfury, and Eskhandar's Right Claw carry real per-spec value, simmed with WoWSims.
- On Burning Crusade realms, weapon procs like Dragonstrike, Blinkstrike, and Rod of the Sun King are valued per spec as well, simmed with WoWSims.
- Trinkets are scored by simulation now, on every supported version: each trinket's on-use and proc throughput is simmed for your exact spec and folded into its score, so an off-list trinket with a strong effect can correctly beat a listed one. The guide tier list now only marks the best-in-slot pick, it no longer decides a trinket's rank.
- When a proc cannot be measured reliably, the item's tooltip says the Equip effect is not scored instead of guessing, so a coverage gap is never mistaken for a real downgrade.
- Item tooltips are clearer: for each of your specs you now see a simple green up arrow or red down arrow and a percent comparing the item to what you have equipped right now, instead of labels like best, lower tier, or similar. An item about the same as what you already wear adds no line.
- Every spec an item would upgrade is now listed, for you and for your other characters, so a weapon that helps two of your specs shows both instead of only one.
- Fixed a case where a two-handed weapon (or other gear) that upgrades one of your other characters, like a plate wearer, would not show as an upgrade on the tooltip while you were playing a character who cannot use it.
- Gear you can mail or send through the Warband bank to your other characters is now included in those suggestions; only truly soulbound gear is left out.
- A new FAQ entry in Settings explains how proc and trinket scoring works, and the tooltip FAQ was updated to describe the new upgrade and downgrade lines.
Added
- Equip-proc-aware scoring (retail): an item's "Equip:" proc now carries real value in GearMatic's score instead of being invisible. Values live in a static
Scales/proc_values.luatable generated offline bytools/proc-values-generate/from SimC 12.0.7 (MID1 baseline profiles, every item encoded at reference ilvl 289), keyed[specKey][itemID] = { eff, kind, scenario }, folded into candidate and equipped scores byScoring/V2/Compare.lua, all slots including trinkets.effis in primary-stat-equivalent score points: proc DPS divided by the spec's primary scale factor times the runtime primary weight 6.0. - Generation methodology, two stages, both real data (
tools/proc-values-generate/generate.py): (1) a DETECTION GATE proves SimC actually models the item's proc for the spec (a low-iteration sim with the item must introduce a buff/proc/action/pet absent from the baseline sim), items SimC does not model are omitted to the honest "not scored" surface; (2) TWIN VALUATION sims each modeled item against a proc-less stat twin (a custom no-id item carrying the identical stat block viastats=, verified to round-trip through SimC's gear parser), soproc_dps = item - twinwith zero static-stat estimation. The earlier subtract-scale-factor-static approach was measured at roughly +-300 DPS of linearization bias and was discarded. - Weapons are valued too: a weapon twin carries SimC's own decoded
weapon=<type>_<speed>speed_<min>min_<max>max(parsed from adebug=1init log so parity is by construction), shields keeptype=shieldso shield-gated abilities survive in both sims, and class-unusable weapons auto-skip per spec via the sim error itself. - All 7 healer specs (Disc, Holy Priest, Holy Paladin, Resto Druid, Resto Shaman, Mistweaver, Preservation) value heal and absorb procs by formula from real spell data: magnitude via
spell_queryat the same reference ilvl 289, rate from Real PPM, times the documentedABSORB_EFFICIENCY = 0.75, converted through the class's DPS-caster intellect scale factor (HEALER_THROUGHPUT_PROXY, a named documented assumption). The healer classifier is description-driven and rejects stat/mana/damage procs, magnitudes that do not scale with casting item level, thorns-style "shield that deals damage" effects, and$sNplaceholders buried in composite${...}formulas. - Honest "not scored" surface: an equip-proc item with no value entry for your spec gets a tooltip line saying the proc is not scored (
ItemTooltipHook.lua,proc_not_scoredin all 12 locales), so a coverage gap is never mistaken for a real downgrade. On-use (active) items are excluded by design, the runtime cannot model when a player presses them. /gm scoreprints the proc valuation line for the hovered item (debug surface).- FAQ entry (
faq_q_proc/faq_a_proc, all 12 locales) explaining what is valued (armor and weapon procs per spec, damage/tank/healing/absorb), that trinkets are now simmed and the tier list only marks the guide best-in-slot pick, and what "not scored" means. - Four-flavor coverage in
Scales/proc_values.lua: equip-proc and heal/absorb values for retail, Mists of Pandaria Classic, Classic Era (shared with Season of Discovery and Hardcore), and Burning Crusade, generated per flavor (SimulationCraft for retail and Mists, WoWSims for Era and TBC), keyed[flavor][specKey][itemID]and gated at runtime byns.Compat.Flavor. Trinkets are simmed and folded like any other slot on all four. Entry counts: retail 4160, Mists 7857, Era 723, TBC 1126. MoP trinkets were deduped by effect token (484 ilvl variants collapsing to 155 unique sims, then fanned back to every ilvl sibling).
Changed
- The item tooltip's current-character lines now compare against your currently-equipped item via
Compare.EvaluateVsEquipped(matching/gm score), instead of against your best owned item, so a genuine upgrade over what you are wearing always shows its true percent. The best / 2nd best / lower tier / similar tooltip labels were removed; every spec that moves the needle shows a green up or red down arrow and a percent, and an item within ~0.5% of equipped adds no line (ItemTooltipHook.lua,Scoring/V2/Compare.lua).faq_q_labels/faq_a_labelsrewritten to match in all 12 locales. Compare.AltUpgradeRowsnow emits one row per upgrading spec of each other character (sorted by percent, largest first) instead of collapsing each character to a single best spec; the tooltip row cap was raised from 7 to 15 so the extra spec rows are not truncated.
Fixed
- A two-handed weapon (or any item) that upgrades a character of a different armor class no longer scores 0 when viewed from a character who cannot use it: weapon usability now checks the target scale's class instead of the played character's class (
Scoring/V2/Score.lua), and each character's equipped-gear stats are cached at scan time so a cross-character comparison has real stats to score against even when the raw item link is uncached in the current session (Scanner.lua, threaded throughScoring/V2/Compare.luaandScoring/V2/Score.lua). - Alt-upgrade suggestions no longer exclude Bind-on-Equip or Warband-bound gear you can actually send to your other characters; only truly soulbound gear is gated out (
Scoring/V2/Gate.luaCanSendToAlt, warband-until-equipped detected viaC_Item.IsItemBindToAccountUntilEquip). - The gear scanner no longer wipes a character's cached gear when an inventory read races empty on login (
Scanner.luaanyRead guard), and a one-time cache migration (GearMaticDB.versionbumped to 2,Core.lua/Scanner.MigrateSlotCaches) clears stale malformed slot caches so the fix reaches existing users, not only fresh installs.
[v3.20.1-release] - 07/04/2026
Fixed
- A max-level character whose equipped gear stayed static could keep being served a stale, crafted-only gear map (built at an earlier gear state, with no dungeon or raid drops) indefinitely, because the gear-map cache fingerprint only changes when the character's equipped items, spec, or level change. The current build logic already produces the correct map; bumping the gear-map cache fingerprint token (
gm22->gm23inEngine.GearMapFingerprint) invalidates every existing cached map so it rebuilds on update, no manual/gm gear clearcacherequired (GearMap/Engine.lua; guard test updated intests/lua/test_gearmap_source_display.lua).
In-Game
- Fixed the gear map sometimes getting stuck showing only crafted gear, with no dungeon or raid drops, for a character whose gear had not changed in a while. It now refreshes to show your real upgrades again.
[v3.20.0-release] - 07/03/2026
Added
- Characters tab in the settings panel (order 7, between Stat Import and Loadouts): one class-colored checkbox row per tracked character, checked = excluded from alt-upgrade suggestions. Backed by the account-wide
GearMaticDB.altUpgradeIgnorestable (separate from the scanner-rewrittencharsrecords so the flags survive relogs), withCompat.IsAltUpgradeIgnored/Compat.SetAltUpgradeIgnoredhelpers. Ignored characters are skipped byCompare.BestAltUpgrade(bags, loot rolls, quest rewards) and the tooltip alt rows; their gear snapshots stay tracked for the Browser and durability nag./gm scorenow prints anignored=flag per alt. Locked bytools/alt-ignore-selftest.lua; all five new strings localized in all 12 locales. - Upgrade markers and GearMatic tooltip lines now work on items sitting in your bank and Warband (account) bank, not just your bags. The bank item buttons expose
GetBankTabID/GetContainerSlotIDinstead of the bag/slot methods the overlay looked for, so it never recognized them and never refreshed while the bank was open. The overlay now reads the bank button's link viaC_Container.GetContainerItemLink(bankTabID, containerSlotID), recognizes bank buttons, and refreshes onBANKFRAME_OPENEDplus the bank slot-change events while the bank is showing (BagOverlay.lua; button structure confirmed against the liveBankPanelItemButtonMixinin Blizzard'sBlizzard_UIPanels_Game/Mainline/BankFrame.lua; locked bytools/bagoverlay-bank-button-selftest.lua). The bank tooltip lines ride the sameGameTooltip:SetBagItemhook the bags use, now that the unwearable-item early return above is gone. - Upgrade markers now also draw on the BankMatic bank/Warband viewer, which uses its own
BankMaticItem*item buttons that store the link on abutton.itemLinkfield (its own tooltip already worked because it feeds that link toGameTooltip:SetHyperlink, which GearMatic hooks).getButtonItemLinknow reads that field,looksLikeBagItemButtonrecognizes theBankMatic*Item*buttons, and the overlay treats theBankMaticReplicaFrameas a live container so it discovers and refreshes its buttons while it is open (including when opened remotely away from a banker), with a one-timeOnShowhook for an immediate first paint (BagOverlay.lua; covered bytools/bagoverlay-bank-button-selftest.lua).
Changed
- The settings tab that lists your characters is renamed Ignore Characters and gains a one-click Ignore all except current server button:
Compat.KeepOnlyCurrentRealmmarks every tracked character not on the current realm as ignored and un-ignores the ones on this realm (realm compared with spacing/case stripped; records with no stored realm are treated as not-current and ignored). The button and each control carry a hover tooltip explaining what the tab does, and toggling anything now also callsSettings.Refresh()so the checkboxes and the live markers update together. Three new strings (settings_tab_ignore_characters,settings_alt_ignore_others,settings_alt_ignore_others_desc) added to all 12 locales (Settings.lua,Compat.lua,Locales/*;Compat.IsPlayerRealm/KeepOnlyCurrentRealmlocked bytools/alt-keep-current-realm-selftest.lua). - Alt upgrade suggestions are now suppressed for characters the item cannot actually reach.
Compare.AltUpgradeRowsskips an alt unless it is reachable viaCompat.AltIsReachable: either this client has the Warband (account) bank (C_Bank+Enum.BankType.Account, so any account character can retrieve the non-BoP items this feature already limits itself to), or the alt is mailable, on the same or a connected realm (GetAutoCompleteRealms, realm names compared with spacing/case stripped) and the same faction. Net effect: retail is unchanged (Warband reaches every alt), while on clients without a Warband bank (Classic/Anniversary/etc.) alts on unconnected realms or the opposite faction no longer clutter the suggestions. Missing faction data on an old alt record is treated permissively (not used to exclude)./gm scoreprints areach=flag per alt (Compat.lua,Scoring/V2/Compare.lua,Debug/Score.lua; locked bytools/alt-reachable-selftest.lua). - Alt upgrade verdicts now consider every spec that alt can play, not just its active spec.
Compare.BestAltEvalAcrossSpecsscores the item against each scale fromScaleImport.GetScalesForClass(altKey)(the alt's imported scales plus the bundled class defaults) and keeps the highest displayed percent, so a weapon that is a wash for a warrior alt's active Protection but a big gain for Fury now marks yellow and the tooltip//gm scorenames the spec that wants it (Fury). Specs that cannot use the item (weapon-rule blocked, returning no eval) are skipped, and the empty-slot baseline guard still applies per spec (Scoring/V2/Compare.lua,Debug/Score.lua; locked bytools/alt-allspecs-selftest.lua). - Alt BoE verdicts no longer cap on the alt's current level. New
Compat.CanClassEverWearItemignores the item's required level and judges armor/weapon proficiency at the level the alt will be when it can first equip the item, so a level-30 warrior is treated as plate-preferred for a level-60 BoE (mail correctly rejected) while a mail piece the same warrior can use at 30 still passes. Wired intoCompare.BestAltUpgrade, the tooltip alt rows (ItemTooltipHook.lua), and the/gm scorealt-comparison section (Debug/Score.lua). Current-character green verdicts keep the level cap unchanged. - Bag icons, loot rolls, and quest rewards now fall through to the alt check when the item is wearable by the current character but is not their upgrade; a green current-character verdict still wins over the yellow alt verdict (
BagOverlay.lua,LootHook.lua,QuestRewardHook.lua). The current-spec weapon-rule block in the bag overlay now only guards the green path so it cannot suppress an alt verdict.
Fixed
- The yellow alt-upgrade chevrons on bag icons and loot roll frames never rendered:
Gate.ShouldEvaluateForAltrequiredShouldEvaluateForCurrentChar, whoseCompat.CanWearItemcheck fails for exactly the items those surfaces route to the alt path (items the current character cannot wear), soCompare.BestAltUpgradealways bailed before scoring a single alt. Only the tooltip alt rows, which bypass that gate, ever worked. The alt gate now stands alone: has an equip slot, not quest-bound, not locked, not Bind-on-Pickup (Scoring/V2/Gate.lua; locked bytools/alt-levelcap-selftest.lua). - Yellow chevron with a silent tooltip: bag/loot yellow fired on the synthetic rank delta (
eval.delta >= 1) while the tooltip alt rows require the displayed percent (DisplayUpgradePct: rank and real-stat deltas agreeing in sign, >= 1), so an item could carry a yellow marker whose tooltip named nobody.Compare.BestAltUpgradenow gates and ranks alts onns.DisplayUpgradePct, the exact metric the tooltip renders, and the loot-roll indicator prints that same displayed percent instead of the raw rank delta (Scoring/V2/Compare.lua,LootHook.lua; locked bytools/alt-display-agreement-selftest.lua). - Two more chevron-vs-tooltip divergences closed by making both surfaces consume ONE decision: new
Compare.AltUpgradeRows(eligibility + displayed pct, sorted best-first) now feeds bothBestAltUpgrade(chevrons) and the tooltip alt section. The tooltip previously required the alt to have an active scale before evaluating (a fallback-scored chevron alt rendered no row) and iterated chars in arbitrarypairs()order under the 7-row cap (the chevron's alt could be crowded out); now the best alt row always renders, additional alts fill remaining cap space in descending percent order (Scoring/V2/Compare.lua,ItemTooltipHook.lua). - Toggling a character in the Characters tab now clears the bag-overlay verdict cache and the quest-reward eval cache, so stale yellow markers vanish immediately instead of waiting for an unrelated event (
Settings.lua,QuestRewardHook.lua). - The real reason a yellow chevron showed with no character named in its tooltip:
appendUpgradeLinesImplreturned early onnot canWear and not equipped, the exact condition that routes an item to the yellow alt path, so the tooltip never reached the alt-row section. The current-character scale loop and the rogue off-hand block are now guarded by acurrentUsableflag while the alt-row section always runs, so an item the current character cannot wear still lists the alt(s) it upgrades. Locked by a real tooltip harness that drives the actual impl (tools/tooltip-altrow-unwearable-selftest.lua, fails when the early return is restored).
In-Game
- Bags, loot rolls, and quest rewards now show the yellow alt marker on tradeable gear one of your other characters wants, even when the character you are playing could wear it too.
- Alt suggestions no longer skip gear your alt is too low level to equip yet. A tradeable drop that needs level 60 now gets the yellow marker for your level-40 alt when it beats what they have, so you can bank it for them.
- New Characters tab in the settings: check any of your characters to leave them out of the yellow alt suggestions. Handy for bank alts and characters you no longer play.
- The yellow marker and the tooltip now always agree: hover any item with a yellow marker and the tooltip lists which of your characters it upgrades and by how much, with the same percent in both places. This also fixes items you personally cannot wear (a plate drop while you are on your mage) showing a marker but naming no one on hover.
- Upgrade markers and GearMatic's tooltip lines now show up on items in your bank and Warband bank, not just your bags.
- An item now shows the yellow alt marker if it upgrades any spec that character can play, not only their current spec. The tooltip names the spec it is best for, so an off-spec weapon your alt would want for their other spec no longer gets missed.
- Alt suggestions are hidden for characters you could not actually get the item to. On realms with the Warband bank any of your characters can reach it, so all still show; without a Warband bank, characters on other servers or the opposite faction (where you cannot mail the item) are no longer suggested.
- The settings tab for this is now called Ignore Characters, its controls explain themselves when you hover them, and it has a one-click button to ignore every character except the ones on your current server.
[v3.18.1-release] - 07/02/2026
Fixed
The first hover of a gear map item with a cold boss-portrait cache never showed the tooltip's boss portrait or gold ring.
buildTooltipSourceresolved the display via the select-lessresolveDisplayID, which returns nil untilEJ_SelectInstance+EJ_SelectEncounterhave set the journal context, so the paint was deferred to the 0.2s async retry chain, and that chain painted the creature displayID with no journal icon (bypassing the flash-free icon-first path). NowresolveBoss(selects + persistent cache write) runs synchronously inbuildTooltipSourceand returns the journal icon alongside the displayID, so the first hover paints the ring and boss icon immediately; the async backstop also passes the resolved icon through (GearMap/Frame.lua;tests/lua/test_gearmap_tooltip_source_first_hover.lua).Found the actual first-hover killer: on retail the item-tooltip post-processor also fires for the comparison tooltips (ShoppingTooltip1/2, the "Equipped" frames), and
RenderTooltipSourceresponded to any non-matching tooltip by hiding the boss portrait, so the compare tooltip that pops right after the main tooltip wiped the portrait that had just been painted. The hide is now scoped to the main GameTooltip only; compare/ItemRef renders leave the portrait alone (GearMap/Frame.lua; locked by an offline repro intests/lua/test_gearmap_portrait_event_refresh.lua). Also added a persistent 40-entry portrait trace (GearMaticDB.gearMapPortraitTrace) recording every render/paint/hide/retry/anchor decision so portrait issues can be diagnosed from SavedVariables after a/reload.Rebuilt the boss-portrait pipeline on the same pattern Blizzard's own UI uses for encounter portraits (world-map boss pins and the adventure guide):
EJ_GetCreatureInfo(1, encounterID)is queried directly first (no journal selects, no forcedBlizzard_EncounterJournalload; the select dance is now only a fallback), the portrait slot is never left empty (when the creature cannot be resolved yet, the gold ring paints Blizzard's stockInterface\EncounterJournal\UI-EJ-BOSS-Defaultboss icon instantly and the real portrait upgrades in behind it), and aPORTRAITS_UPDATEDhandler repaints any visible creature-display portrait at full alpha, so a portrait whose data streamed in late self-heals exactly like the Blizzard journal does (GearMap/Frame.lua;tests/lua/test_gearmap_portrait_event_refresh.lua). The preview panel path uses the same resolve + fallback.A fresh max-level character saw a crafted-only gear map: the recommended ilvl ceiling (average ilvl + 12%) sat below every current-tier journal drop, so all dungeon/raid loot was filtered out while crafted/vendor items (ceiling-exempt aspirational records) took every slot. The assembly pass now collects the ceiling-rejected journal candidates, and when not a single journal record survives the gate, it lifts the effective ceiling to the journal's own floor ilvl plus the same relative headroom, re-admitting the entry band of real content (entry dungeons, LFR) while the top band stays gated (
GearMap/Engine.luaassembly loop;tests/lua/test_gearmap_ceiling_floor.lua). Diagnosed from the persisted/gm gear debugdump: 1151 loot records scanned,ilvlCeiling=212at avg ilvl 189, every journal drop at 243+.
In-Game
- The boss portrait and its gold ring now appear the very first time you hover a gear map item, instead of only after hovering it a second time.
- Fresh max-level characters in mostly leveling gear no longer get a gear map with only crafted items: dungeon and raid drops from the entry difficulties of current content now show up alongside them, and the highest-end gear stays hidden until your item level catches up.
[v3.18.0-release] - 07/01/2026
Changed
- The single-chevron upgrade indicator is now the WoW-native green upgrade arrow (
bags-greenarrow, the same arrow Pawn shows on bag items), and downgrades get a matching red down arrow derived from that same art. Applies to the per-spec tooltip lines (up and down icons, including the trinket lower-tier line) and the equip/downgrade alert popups plus their options previews. New shared helperUpgradeArrow.lua(ns.UpgradeArrowMarkupinline escapes,ns.ApplyUpgradeArrowtexture widgets,ns.UpgradeArrowSizenative dimensions); new assetTextures/arrow-down-red.tga(a 20x21 red arrow glyph centered at offset 6,6 on a 32x32 canvas, cropped via texcoords). Alert popups render the up/down arrows at their native size instead of the 36px chevron box; tooltip up and down arrows are pinned to a matching 20x20 with the red one nudged down to sit level with the green. The double chevron (upgrade-chevron.tga) on bag corners, loot, quest rewards, AtlasLoot, and the upgrade/loadout alerts is unchanged (ItemTooltipHook.lua,Alert.lua, all six TOCs;tests/lua/test_upgrade_arrow.lua). - Gear map rows for items the character cannot wear yet (required level above the player) now show their "Lv NN" label in red instead of grey; a new-slot row whose item is already wearable keeps the grey label (
GearMap/Frame.luarow delta rendering,UnitLevelgate).
In-Game
- Upgrade and downgrade markers got a facelift: item tooltips and the on-screen equip alerts now use the classic green up arrow you know from your bags, with a matching red down arrow for downgrades.
- On the gear map, gear you cannot wear yet now shows its required level in red instead of grey, so it is obvious at a glance which upgrades are waiting on a level-up.
[v3.17.0-release] - 07/01/2026
Added
Built an in-game gear-map profiler (
/gm gear profile [seconds], default 30; run again to stop early). It watches every frame while capturing and attributes main-thread time to named phases: journal scan (ej.tier/ej.select/ej.numloot/ej.lootread/ej.normalize), row assembly (asm.iteminfo/asm.canwear/asm.equipfacts/asm.eval/asm.rows), coroutine slices (build.slice), item warm queue (warm.drain), UI (frame.build/frame.loading/frame.events), and cache writes (map.save/map.fingerprint). Every frame at or over 25 ms is logged with its top phases inline plus agm=total, so a stutter frame whereframefar exceedsgmis provably outside the addon's instrumented code. Summary prints to chat; the full report persists toGearMaticDB.gearMapProfile(flush with/reload). Zero overhead when not capturing (GearMap/Profiler.lua, wired through Engine/Frame/Journal;tests/lua/test_gearmap_profiler.lua).Profiler is now one command on, one command off.
/gm gear profile [secs]arms everything itself: enables thescriptProfilecvar, persists the pending capture in SavedVariables, reloads, and after the reload the profiler boot frame auto-clears every gear-map cache, starts the capture (default 60s), and opens the gear map./gm gear profile offstops any running capture (persisting its report), disables the cvar, clears the pending flag, and reloads to flush. Typing/gm gear profilemid-capture just stops it early (Prof.Arm/Prof.Off+GearMaticGearMapProfilerBootPLAYER_ENTERING_WORLD pickup inGearMap/Profiler.lua;tests/lua/test_gearmap_profiler_arm.lua; reload viaC_UI.Reload, MCP-verified).Profiler CPU mode:
/gm gear profileautomatically arms the engine's CPU accounting (ResetCPUUsageat start,UpdateAddOnCPUUsageat stop) via thescriptProfilecvar, and the report gains two sections: per-addon CPU (loaded addons, sorted, with % of captured frame time) and per-frame CPU (EnumerateFrames+GetFrameCPUUsage, top offenders labeled viaGetDebugName). Built because the first live capture showed a solid 30 FPS lock withgm=0.0on every stutter frame, the cost is outside the instrumented gear-map build paths, so engine-level attribution is needed to name the real owner (GearMap/Profiler.lua,Core.lua;tests/lua/test_gearmap_profiler_cpu.lua; APIs verified against Blizzard'sPerformanceDocumentation.lua).Added
/gm gear clearcache: wipes every gear-map cache in one shot for a true cold build, session loot cache and EJ rescan state, score/eval memos, stat-extract cache, BestItems pools, crafted-link cache, warm-queue state and blacklist, resolved-name cache, journal encounter/creature/difficulty-label caches, frame display/instance caches, and the persistedgearMapCache/gearMapNameCache/gearMapBossCacheSavedVariables keys (settings untouched). Built for profiling cold starts with/gm gear profile(GM.ClearAllCachesinGearMap/GearMap.luawith per-module reset hooks;tests/lua/test_gearmap_clearcache.lua).
Fixed
Fixed the gear map still stuttering on a level-80 boosted character on retail: under Midnight the level cap is 90, so 80 is no longer max level, and the journal scanner's
TIER_LEVEL_RANGEtable still carried pre-squish level bands,[3]={70,80}Wrath,[4]={80,85}Cata,[5]={85,90}MoP,[6]={90,100}WoD, all of which matched a level-80's scan window. The boost cold-walked six EJ tiers (four of them dead expansions), dungeons and raids both. Retail tier bands are now derived from the real cap instead of hardcoded: the last three tiers band to{cap-10,cap}/{cap-20,cap-10}/{cap-30,cap-20}(Midnight/TWW/DF today, correct automatically next expansion), verified against Blizzard's MainlineEJ_TIER_DATA(exactly one tier per expansion, 1=Classic..12=Midnight), and legacy tiers keep real Classic-era bands clamped belowcap-30. A level 80 now scans exactly 2 tiers (TWW + Midnight), level 65 scans DF + TWW, level 30 scans Classic only. Mists keeps its real unsquished bands ({1,60},{58,70},{68,80},{80,85},{85,90}). Bumped the map cache token (gm20 -> gm21) so stale cached rows regenerate (GearMap/Providers/Journal.luatierBand;tests/lua/test_gearmap_leveling_scan_scope.lua).Fixed the gear map coming up completely empty on the level-80 boost once the tier scan was corrected: the leveling path's recommended-ilvl ceiling is
max(avg ilvl, bracket floor) + 12%, and thelevelBracketsfloor table tops out at 440, so the boost's ceiling was 493 while every TWW/Midnight dungeon drop sits far above it,tooHighfiltered every row (the old populated map at 80 was low-ilvl legacy-expansion loot sneaking under that stale ceiling). On retail, while leveling inside the current-content band (level >= cap-30), the ilvl ceiling no longer applies, the derived tier scan and per-item minimum levels already scope the results. Scaled old-world retail leveling (< cap-30) and Mists keep the ceiling since those floors match their content. The ceiling is part of the map-cache fingerprint, so affected characters regenerate automatically (GearMap/Engine.luabuildOpts; ceiling assertions intests/lua/test_gearmap_leveling_scan_scope.lua).Slashed the gear map's Encounter Journal churn, the real stutter source named by the CPU profile. Capture 2 (60s cold build, retail) showed Blizzard's own
EncounterJournalframe consuming 16.6s of CPU (28% of the capture, 21,334 event-handler calls) reacting to our scan's 2,924EJ_SelectInstance/EJ_SetDifficulty/EJ_SetLootFiltercalls across ~9 convergence rescans, while GearMatic's own addon CPU was 1.4%; each select costs ~1.7ms inside the call plus ~5ms of hidden-journal event processing after it. Three changes cut the select count by roughly an order of magnitude: (1) rescans are now incremental, instance-difficulty combos that already returned loot are remembered (scoped per class/spec/level/filter context, reset byclearcache; level-ups change the scope automatically) and only still-empty combos are revisited, withLoot.lua's union merging fresh arrivals into the session cache; (2) after a coroutine suspension the scan re-selects the EJ instance/difficulty only when the selection actually drifted (journal shown, orEJ_GetDifficulty/EJ_GetInstanceInfodisagree) instead of unconditionally every frame; (3) loot rows resolve their equip slot viaC_Item.GetItemInfoInstantso normalization no longer depends on item-cache warmth, which is what used to force full rescan walks (GearMap/Providers/Journal.lua; newtests/lua/test_gearmap_journal_incremental.lua, updatedtest_gearmap_journal_yield.luadrift contract).Fixed the gear map pinning the game at 10-15 FPS for 30+ seconds while it builds, worst on leveling (non-max-level) characters on retail and Mists. The build coroutine could only pause at its per-frame time budget when the journal scanner reached a yield point, and the scanner only offered one per instance-difficulty, so an entire Encounter Journal instance walk (select instance, set difficulty, set loot filter, normalize every loot row) ran inside a single frame. Leveling characters scan every tier whose level window overlaps (times up to 8 convergence rescans while journal data streams in), stacking those oversized frames for the whole build. The scanner now yields on every loot row so the 8 ms frame budget actually holds, reasserts the EJ instance/difficulty selection after a real suspension so a player opening the journal mid-scan cannot corrupt the results, miss-caches failed
EJ_GetCreatureInfo/EJ_GetEncounterInfolookups per scan pass (previously up to 9 retries per loot row, every row, every rescan), and caches difficulty labels per difficultyID instead of callingGetDifficultyInfoper row (GearMap/Providers/Journal.lua,GearMap/Engine.luayielder now reports suspensions; newtests/lua/test_gearmap_journal_yield.lua).
Changed
- While below max level, the gear map no longer scans or shows raid loot at all, on every game version, raid drops are useless while leveling. The journal provider skips raid instances entirely (which also cuts the leveling cold-walk roughly in half) and the dataset provider drops raid-category sources; an item that also drops from a dungeon keeps its dungeon source. Max level keeps raids, and the explicit Show all content toggle still shows them while leveling. The loot session cache now keys on the gated flag so flipping that toggle rescans correctly (
GearMap/Providers/Journal.lua,GearMap/Providers/Dataset.lua,GearMap/Loot.lua).
Notes
- Verified in-game with before/after 60s cold-build CPU captures on retail: average frame time 34.7ms -> 18.1ms (~29 -> ~55 FPS), stutter frames 1037 -> 277, worst frame 2982ms -> 404ms, Blizzard
EncounterJournalframe CPU 16.6s -> 0.5s (-97%), EJ selects 2924 -> 257, build coroutine active time 8.9s -> 1.9s, GearMatic total addon CPU halved.
In-Game
- Building the gear map list no longer drags your framerate down or freezes the game. The worst of it hit while leveling, where opening the gear map could pin the game at low FPS for half a minute; it now builds smoothly in the background and finishes much faster.
- On a freshly boosted or leveling character, the gear map now looks only at content that matches your level instead of digging through years of outdated expansions. It also no longer comes up empty on a fresh boost; your real dungeon upgrades show up right away.
- While you are leveling, the gear map no longer lists raid drops, since they are useless before max level. Raids return at max level, and the Show all content option still shows everything if you want it.
[v3.16.0-release] - 07/01/2026
Added
- Armor-specialization awareness. On flavors that have Armor Specialization (Cataclysm, Mists, and retail Mainline), GearMatic no longer treats a below-preferred armor type as an upgrade in the eight armor-specialization slots (head, shoulder, chest, waist, legs, feet, wrist, hands). A mail class (Shaman, Hunter, Evoker) is not told leather or cloth is an upgrade; a plate class (Warrior, Paladin, Death Knight) is not told mail/leather/cloth is; a leather class (Rogue, Druid, Monk, Demon Hunter) is not told cloth is. Cloaks (always cloth) and shields are exempt, and while leveling below the level where the preferred type is wearable (40 on Cata/Mists, 1 on retail) lower armor is still allowed. Classic Era, Burning Crusade, and Wrath have no Armor Specialization, so off-type pieces (for example Devilsaur leather for a Vanilla Hunter) are still scored on stats and can be recommended. An item on the Icy Veins best-in-slot list is exempt from the gate so a genuinely intended off-type BiS piece still wins (
Compat.luanewPassesPreferredArmorGate/CLASS_PREFERRED_ARMOR, wired intoCanClassWearItem,ClassPassesArmorGate, and the gear-map dataset/engine paths; newtools/preferred-armor-gate-selftest.lua, 50 cases). - A new FAQ entry, "Why won't it recommend a lower armor type, like leather for my Shaman?", explaining Armor Specialization and when off-type gear is still suggested, translated into all 12 locales.
[v3.15.1-release] - 06/30/2026
Fixed
- Trinkets no longer show absurd upgrade percentages (900%, 890%, ~196%) or get flagged as upgrades when they are not your best or second best. A stat score cannot value a proc or on-use effect, so trinkets are ranked by their Icy Veins guide tier, not by a raw stat number. Off-list trinkets are scored as unranked (item-level ordered among themselves) and read as lower tier instead of a false upgrade. The displayed trinket percentage is now capped and shown only when stats agree it is genuinely an upgrade (
Scales/trinket_rank.luascoreItemImplscores unranked trinkets at the synthetic tier-100 value again;Scoring/V2/Compare.luacaps the trinketstatDeltaat 25 while leaving the internaldelta/rankDeltatier signals uncapped for auto-equip). - Upgrade and downgrade percentages can no longer explode on any slot. When the item you are wearing scores near zero for your spec (for example a max-level character still wearing very low item-level gear), the percentage used to read tens of thousands of percent. It is now capped at a sensible ceiling. The cap lives in the single
percentDeltachokepoint inScoring/V2/Compare.lua, so it covers the character pane, bag tooltips, the bag upgrade arrow, the gear map rows, and the gear-map debug funnel at once; item gating and score-based ordering are unaffected. - Crafted and upgraded trinkets now rank at their true (effective) item level instead of an inconsistent base value, so a higher-item-level crafted trinket is correctly recognized as your second best rather than reading similar (
Scales/trinket_rank.luaEffectiveItemLevelprefersC_Item.GetDetailedItemLevelInfo). - Your best and second-best trinkets are now driven by the owned-pool tier ranking on every surface, so a better trinket sitting in your bags both auto-equips over a worse one and shows the green bag upgrade arrow, while the tier/item-level allowance still vetoes a bad item-level drop.
Notes
- Internal: renamed
tools/trinket-statscore-ranking-selftest.luatotools/trinket-tier-ordering-cap-selftest.lua, addedtools/percentdelta-cap-selftest.lua, bumped the gear-map cache token (gm18 -> gm20) so persisted rows regenerate with the corrected percentages.
[v3.15.0-release] - 06/30/2026
Changed
- Announcing your gear and loadout messages to guild chat is now off by default. Party and raid announcing are unchanged. You can turn guild announcing back on anytime in the Social options.
[v3.14.1-release] - 06/30/2026
Changed
- Refreshed the RepMatic and MailMatic icons in GearMatic's "More Infinite Loop Alchemist Addons" list to their new artwork, and added XPMatic's icon to that list.
[v3.14.0-release] - 06/28/2026
Added
- Weapon-type awareness for recommendations. GearMatic now knows the weapon setup each spec actually uses and never recommends a weapon a spec would not equip. The rule resolves per spec (so off-spec tooltip lines stay correct) and per game version, and is wired into every recommendation surface: the character pane, bags, the bag upgrade arrow, auto-equip, the gear map, and quest rewards (
Scales/spec_weapon_rules.luaWeaponRuleForScale/WeaponRuleFor, consumed byScoring/V2/BestItems.luapool building andScoring/V2/Compare.luaevaluation; the live bag/auto-equip path resolves throughns.ActiveWeaponRule).- Shield + one-hand specs are never recommended a two-hander: Protection Warrior and Protection Paladin (every version), Holy Paladin (every version), and Restoration Shaman on Mists/Cataclysm/Wrath only (Icy Veins lists viable 2H healing staves for Resto on Retail, Burning Crusade, Classic Era, and Season of Discovery, so it is left flexible there).
- Two-hand-only specs are never recommended a one-hander: Blood Death Knight (Retail/Mists/Cataclysm/Wrath) and the bear Druid (Guardian on Mists, Feral on Cataclysm/Wrath/Burning Crusade, where the weapon's Feral Attack Power makes a 2H mandatory).
- Vengeance Demon Hunter is kept to its dual-wield one-handers.
- Genuinely flexible specs are left unrestricted: Guardian Druid and Brewmaster Monk on Retail, the bear Druid on Classic Era/Season of Discovery, Elemental Shaman everywhere (it uses 2H staves in several versions), and any caster that picks between a 2H staff and a one-hand + off-hand by stats.
- Season of Discovery and Hardcore inherit the Classic Era rule set (same client flavor). A fallback was added so the weapon rule still resolves on Cataclysm and Wrath clients, which ship no per-spec scoring data and otherwise carry no spec on the active scale.
Fixed
- A Protection Paladin (and every other shield or one-hand-locked spec) is no longer told to equip a two-handed weapon over its one-hand and shield. A weapon that does not fit the spec now shows no GearMatic recommendation instead of a false upgrade, on the tooltip, the bag arrow, the gear map, and auto-equip.
[v3.13.1-release] - 06/27/2026
Fixed
- Several copies of the same item at the same item level (for example crafted gear with different secondary stats that share one base item ID) were all labeled "best".
Scoring/V2/BestItems.luaGetRanknow score-gates its item-ID fallback: a copy sharing the pool best's base item ID is marked best (or 2nd) only when its own weighted score actually reaches the pool best/2nd, so lower-scoring copies fall through to their real comparison. This also restores the v3.12.0 behavior where a lower item-level copy of gear you wear reads as a downgrade instead of best. - The green upgrade arrow in your bags appeared on every duplicate that merely beat your equipped item.
BagOverlay.luanow gates the arrow on the owned-pool best (isBestEquippableForActiveplusns.BagOverlay_ShouldChevron, mirroringns.BagOverlay_ShouldSkull): single slots show the arrow only on the best copy you own, and two-of-a-kind slots (rings, trinkets, dual-wield weapons) on your best two. The same verdict path feeds Baganator, so it matches there too. - Regression coverage: new
tools/crafted-variant-tiebreak-selftest.luaandtools/bagoverlay-chevron-bestowned-selftest.lua(the latter verifies the wiring throughMarkerVerdict), both red-green; correctedtools/bestitems-duplicate-ilvl-selftest.lua, which had asserted the v3.13.0 regression. 60/60 offline selftests green.
[v3.13.0-release] - 06/26/2026
Added
- Trinket auto-equip is now tier-aware. It will swap in a higher-tier trinket even a few item levels lower (the Icy Veins "trinket exception"), scaled by how many tiers better it is and capped at a 13 item-level "big jump" ceiling, instead of refusing any item-level downgrade (
AutoEquip.lua_allowTrinketSwap,TRINKET_ILVL_PER_RANK,TRINKET_MAX_ILVL_DROP;Scales/trinket_rank.luaRankForLink,TR.UNRANKED). Off-spec consideration uses the tier signal (Scoring/V2/Compare.luarankDelta) rather than the honest stat delta, so a ranked bag trinket can replace an unranked equipped one. - Per-spec "lower tier" and "similar" tooltip lines so no item is ever blank. A trinket that is not your best/2nd on a given spec's list shows
lower tier; a near-equal item showssimilar; both are decided independently per spec (ItemTooltipHook.luafallbackTooltipKind,formatFallback, mirrored in/gm bagdump). New locale keystooltip_lower_tierandtooltip_similartranslated into all 12 locales.
Changed
- Weapon "best" is now loadout-aware. An off-hand or wand no longer reads "best" while a two-hander is the winning loadout; a wand competes for the main-hand slot, and an off-hand keeps "best" only when a 1H + off-hand loadout actually beats the best 2H (
Scoring/V2/BestItems.luaoffHandSuppressed, RANGEDRIGHT/RANGED folded into the main-weapon ranking). - Tooltips, bags, and comparisons rank against one owned pool, so the same item shows the same best/2nd/percent on the character pane and in bags.
Fixed
- A wand in your bags now shows its real downgrade versus your equipped main weapon instead of comparing against itself and showing nothing (
Scoring/V2/BestItems.luaCompareBaselineno longer returns the wand's own pool row forINVTYPE_RANGEDRIGHT/INVTYPE_RANGED, so it falls back to the equipped main-hand). - An off-hand under a two-hander now shows the honest loadout downgrade (your best 1H paired with that off-hand versus your 2H) instead of going blank (
Scoring/V2/Compare.luaoff-hand branch,BestItems.OffHandLoadoutValue). - Trinket tier resolution reads the trinket name from the item link, stable under Midnight "secret value" returns from
GetItemInfo(Scales/trinket_rank.lua). The displayed percent shows only when the tier ranking and the real stat delta agree in sign, never the synthetic tier score.
[v3.12.0-release] - 06/25/2026
Changed
- The "best / 2nd best" tooltip badge is now scoped to the only equip slots where you wear two of a kind: trinkets, rings, and one-hand weapons when you can dual-wield (
Scoring/V2/BestItems.luaRankAppliesToSlot, gated inItemTooltipHook.lua). All other gear (armor, 2H weapons, shields/off-hands) now shows only the upgrade/downgrade percent chevron, never a best/2nd-best label. - The forced "best" badge on a currently-equipped two-slot item is now limited to your active spec, so off-spec rows show their genuine rank instead of stamping "best" on every spec (
ItemTooltipHook.lua).
Fixed
- A lower item-level copy of a trinket or ring you already have equipped no longer shows as "best" or "2nd best"; it now shows its real downgrade percent. Root cause: the equipped-item fingerprint (
linkFingerprint) ignored bonus IDs, so a lower-ilvl bag copy matched the equipped copy and was treated as already equipped, which forced it to "best". The fingerprint now includes item level (ItemTooltipHook.lua). - The best/2nd-best pool no longer lets the same item occupy both slots; duplicates are de-duplicated by item ID, keeping the higher item-level copy (
Scoring/V2/BestItems.luapushCandidate). A new ilvl-aware duplicate guard (equippedDuplicateOutranks) suppresses both the score-pool badge and the published-BiS "best" badge for a lower-ilvl copy of worn gear. - Two equipped trinkets no longer both read "best"; they now read one "best" and one "2nd best" on your active spec.
Added
/gm bagdumpdebug command (Debug/Score.lua): dumps every bag and equipped two-slot item with its per-spec rank, item level, pool best/second, BiS flag, and the exact badge each tooltip renders, for diagnosing trinket/ring labeling.
[v3.11.0-release] - 06/25/2026
Added
- The gear map window's GearMatic medallion (the emblem in the window header) now opens a right-click context menu, modeled on the CritMatic crit-log window icon (
GearMap/Frame.lua). A newattachEmblemMenuhelper enables mouse on the LibMatic RosterFrame'swin._emblemand bindsOnMouseUp: a right-click builds aGearMatictitle plus three buttons, Open Settings (ns.Settings.Open), Open Character Browser (ns.Browser.Toggle), Open Changelog (ns.ChangeLogPopUp.Show), passed to a cross-version menu wrapper (MenuUtil.CreateContextMenuon retail 11.0+,EasyMenu+ a reusedUIDropDownMenuTemplateholder on classic). The emblem also gains a hover tooltip. NewL["minimap_menu_settings"],L["minimap_menu_browser"],L["minimap_menu_changelog"], andL["gearmap_emblem_menu_hint"]keys added and translated across all 12 locales.
Changed
- The minimap button (the ring medallion) now opens the gear map on left-click instead of the settings panel, and opens the settings panel on right-click instead of toggling the character browser (
Minimap.lua). Left-click routes through a newopenGearMaphelper that mirrors the/gm gearslash path: it togglesns.GearMap.Framewhenns.GearMap.IsSupportedFlavor(ns.Compat.Flavor)is true (vanilla/TBC/Mists/retail) and otherwise prints the existinggearmap_unavailable_flavornotice (Wrath/Cata). The hover tooltip and thesettings_show_minimap_descoption blurb were updated to the new click behavior.
Removed
- The vendor auto-sell-junk feature no longer caps how many items it sells per visit (
VendorAutomation.lua). It previously stopped atNUM_BUYBACK_SLOTS(~12) items and printed a notice telling the player to sell the rest manually, on the rationale that the vendor buyback window only protects that many sales.VA.SellJunknow queues every junk slot in the bags unconditionally; theMAX_AUTO_SELLSconstant, theremaining/overflowbookkeeping, the per-visitsoldThisVisitcounter, and thevendor_sell_cap_noticenotice (and its now-dead locale key across all 12 files) were removed. The timed drip and the "auto-sold N junk items for X" summary are unchanged.
In-Game
- The gear map window now has a right-click menu. Right-click the GearMatic medallion in the top-left corner of the gear map window to open Settings, the Character Browser, or the Changelog.
- The minimap button now opens the gear map when you left-click it, and opens settings when you right-click it. Shift-drag still moves it around the minimap.
- Auto-selling junk at a vendor now sells ALL of your grey items in one visit. The old limit that stopped at about a dozen items and asked you to sell the rest by hand is gone.
[v3.10.0-release] - 06/24/2026
Changed
- The gear map's "Show all" checkbox was removed and replaced with a static
Legend: [skull] BISkey (GearMap/DifficultyChrome.lua). The checkbox toggledGM.Settings().showAllContent, which defaults to gated and was only ever turned on here, so removing it locks the existing default; theshowAllContentreads inGearMap/Engine.luaare untouched and now always evaluate to the default. The replacement is aGameFontHighlightSmallFontString showingL["gearmap_legend_label"]("Legend") then the same inline skull texture the rows use, thenL["gearmap_bis_legend"]("BIS"). It sits on the left of the header, 25px in from the edge:GearMap/SpecChrome.lua'slayoutRowanchors the legendTOPLEFTand shrinks the spec dropdown to fit its text (plus padding) and pins itTOPRIGHT. The legend is still assigned towin._gmDiffButton/win._gmDiffRefreshso the layout coordination and theGearMap/Frame.luarefresh callers keep working. NewL["gearmap_bis_legend"]andL["gearmap_legend_label"]keys added across all 12 locales; the now-unusedL["gearmap_show_all"]key is left in place. - The gear map now sorts every row by the upgrade percent it actually shows. The row label uses
up.displayDelta(the real-stat percent), but the list comparator inGM.Frame_BuildDisplayList(GearMap/Frame.lua) sorted onup.deltaPct(the weighted gating percent), which differs for nearly every non-trinket item, so the visible green percentages in both the Very Rare and Normal sections read out of order. The comparator's primary key is nowdisplayDelta or deltaPct, so each section runs top to bottom by descending displayed percent. Gating is untouched (rows still qualify ondeltaPctupstream inEngine.assembleRows); only the on-screen ordering changed.
Added
- The gear map shows "Equipped" instead of an upgrade percent for an item you already have on. For paired slots (rings, trinkets, one-handers) the baseline is the weaker of the two slots, so an item already worn in the other slot was scored as an upgrade over its sibling and displayed a green "+X%". New
Engine.RowIsEquipped(up)(GearMap/Engine.lua), called fromonRowUpdate(GearMap/Frame.lua), checksGetInventoryItemID("player", slotID)acrossC.SlotsForEquipLoc(equipLoc)for the row's item. Because raid items share one base itemID across LFR/Normal/Heroic/Mythic, an itemID match alone wrongly flagged a higher-difficulty record (e.g. the Heroic version) as "Equipped" when you only had the Raid Finder/Normal copy on; the row therefore also compares item level viaC_Item.GetDetailedItemLevelInfoand only reports "Equipped" when the worn copy's level is greater than or equal to the listed item's level (an itemID match with no resolvable levels still falls back to "Equipped"). When worn it renders a neutral localized "Equipped" label (preserving the best-in-slot skull) instead of the percent. Detection is live at render against the current character's inventory, so no scoring or cache changes were needed. NewL["gearmap_equipped"]key added and translated across all 12 locales. Covered bytools/gearmap-equipped-label-selftest.lua.
Fixed
- The gear map no longer lists a trinket as an upgrade when it is a real stat downgrade for your current spec. The gear map decided whether to list a trinket from its Icy Veins tier rank (
eval.delta), so a tier-ranked trinket whose real stats are worse for your spec (e.g. an Agility trinket on a Priest) appeared as a green plus even though the item tooltip's current-spec line showed a minus. The existing trinket guard (Scoring/V2/Compare.lua:322) only demoted a ranked trinket to real stats when its item level was lower than the equipped one, missing the equal/higher-item-level downgrade case. NewEngine.RowUpgradeDelta(eval, equipLoc)(GearMap/Engine.lua) returnseval.statDeltafor trinkets (falling back toeval.deltaonly whenstatDeltais nil, i.e. a pure-proc baseline), andassembleRowsnow gates the row and sorts on that value. A trinket that is a real downgrade is dropped (the gear map never shows downgrades); the best-in-slot skull and every other slot are untouched, and globaleval.deltais unchanged so auto-equip, loot alerts, and the bag overlay keep their behavior. Covered bytools/gearmap-trinket-realstats-selftest.lua. The gear map cache-schema token inEngine.GearMapFingerprintwas bumpedgm14->gm15so the persistedGearMaticDB.gearMapCache(which survives /reload) is invalidated and rebuilds with the new scoring instead of serving pre-fix rows;tests/lua/test_gearmap_source_display.luaupdated to assertgm15. - The gear map's spec override (the spec dropdown's off-spec lens) is now stored per character instead of account-wide. Previously
specOverridelived in one shared table (GearMaticDB.settings.gearMap), so a spec pinned on one character (e.g. Elemental on a Shaman, specID 262) was the same value every other character read. Cross-class picks were already dropped at score time byspecIndexFor(262 never matches a Priest's specs), but same-class characters shared a single override and the value did not persist reliably (the legacysettingstable is migrated into the AceDB profile and recreated empty each login, leaving the real value stranded inprofiles.Default.gearMap). NewGM.SpecOverride/GM.SetSpecOverride(GearMap/GearMap.lua) read/writeGearMaticDB.gearMapSpecByChar[charKey], a top-level table Core never nils, so each character keeps and persists its own override. All readers (GearMap/Engine.luaresolveScale/playerCtx/selectScaleAndOwned/Debug,GearMap/SpecChrome.luadropdown label) and the writer (SpecChrome select) route through the new API. Covered bytools/gearmap-specoverride-percharacter-selftest.lua;tests/lua/test_gearmap_spec_override.luaandtest_gearmap_scoring2_match.luaupdated to the new setter.
In-Game
- Trinkets in the gear map now match your item tooltip: a trinket that is actually a downgrade for your current spec no longer shows up as a green upgrade. Best-in-slot skulls are unchanged.
- The gear map's spec selector is now remembered per character. A spec you pick for one character no longer carries over to your other characters.
- The gear map now shows a "Legend: [skull] BIS" key in the top-left, so you can tell at a glance what the skull on an item means. The spec selector sits on the right. The old "Show all" checkbox was removed.
- The gear map now lists items in order of the upgrade percent shown on each row, so the biggest upgrades are always at the top.
- A gear map item you already have equipped now reads "Equipped" instead of an upgrade percent. A higher-difficulty version of an item you own (for example the Heroic copy when you wear the Raid Finder one) still shows as a real upgrade, not "Equipped".
[v3.9.0-release] - 06/24/2026
Changed
- Gear map Slot, Raid difficulty, and Dungeon difficulty filters now use a selection model instead of a toggle-off model. Open a dropdown and every option starts unchecked; an empty selection shows everything (button reads "All"), and checking one or more entries shows ONLY those (button reads
N/M). Previously every option defaulted to checked and you unchecked to hide.GM.SlotFilter/GM.DifficultyFilter(GearMap/GearMap.lua) no longer seed keys totrue.Engine.RecordPassesSlotFilter/RecordPassesDifficultyFilter(GearMap/Engine.lua) pass everything when nothing in their group is selected, otherwise admit only records whose slot/difficulty is checked (an item whose slot is not in the active selection is excluded; difficulty records that cannot be classified stay visible). Dropdown summaries inGearMap/SourceChrome.luanow read "All" at zero selected. A one-timegmFilterSelectV2migration clears any savedslotFilter/diffFilterso existing users start fresh-unchecked (old "all checked" was functionally identical). Selfteststools/gearmap-slot-filter-selftest.luaandtests/lua/test_gearmap_diff_filter.luaupdated to the new model.
In-Game
- The gear map's Slot, Raid, and Dungeon filters now work as a pick-list: open a filter and check the slots or difficulties you want to see. Check nothing to see everything. The filter button reads "All" when nothing is picked, or shows how many you have chosen.
[v3.8.0-release] - 06/24/2026
Added
- Gear map slot filter. A new "Slot" dropdown sits after the Crafted filter and works like the raid difficulty dropdown: a multi-select menu of equipment slots (head, neck, shoulder, back, chest, wrist, hands, waist, legs, feet, finger, trinket, main hand, off hand, and ranged where the flavor has a ranged slot), with an "All" /
N/Msummary. Selections persist inGearMaticDB.settings.gearMap.slotFilter. NewGM.SlotGroups/GM.SlotGroupKey/GM.SlotFilter(GearMap/GearMap.lua),Engine.RecordPassesSlotFilterhooked intoGM.Frame_BuildDisplayList, and the dropdown UI inGearMap/SourceChrome.lua. Slot names reuse Blizzard's localizedINVTYPE_*globals; one new stringgearmap_slot_label. Covered bytools/gearmap-slot-filter-selftest.lua.
Fixed
- Gear map percent now matches the item tooltip percent (e.g. the case where the gear map showed +1% while the tooltip showed +8% for the same item). Root cause: the gear map resolved its scale with
SI.GetScaleForSpecIndex(the spec's default scale) while the tooltip usesSI.GetActiveScale(which honors the pinned_activescale), so a pinned/custom scale gave the two surfaces different weights and different scores.selectScaleAndOwned(GearMap/Engine.lua) now usesGetActiveScalefor the active spec, falling back toGetScaleForSpecIndexonly when a spec override targets a non-active spec, so both surfaces evaluate against the identical scale. Covered bytools/gearmap-scale-parity-selftest.lua. - Gear map best-in-slot rows now show the upgrade percent on the left and the skull on the right (
+X% ☠), usingup.displayDelta. Previously the cell showed only the skull and dropped the percent. - Tooltip best/2nd-best/best-in-slot badge now shows the same upgrade percent as the gear map. The tooltip skipped computing the evaluation whenever the item ranked (
ItemTooltipHook.lua), so the badge had no number; it now evaluates unequipped current-character badge rows and appends thestatDeltapercent. Combined with the scale fix above, the badge number equals the gear map number. - Boss source + portrait in the gear map tooltip now resolves reliably and is cached so it is ready on the first hover.
EJ_GetCreatureInforeturns nil until the Encounter Journal context is set with BOTHEJ_SelectInstanceandEJ_SelectEncounter(previously only the instance was selected, so many bosses never resolved). Resolution now does both, caches the display ID + icon per encounter in a persistentGearMaticDB.gearMapBossCache(instant on later hovers and across sessions), and pre-resolves every displayed boss in the background when the gear map opens (prewarmBosses). The portrait paints the journal boss icon when one is available and the creature display otherwise, with no tooltip rebuild and no magenta-placeholder flash. Added a/gm gear bossdebugdiagnostic. - Gear map window size changes now actually take effect.
LibMatic-RosterFrame-1.0'sNewre-applies a savedlayout.w/hviaSetSize, so bumping the configured size did nothing once a size had been saved. Fixed three ways:build()resets the savedgearMapFramelayout (guarded bygearMapFrameSizeVersion), the configured size is larger (450 wide x 500 tall, up from 360 x 400), and anOnShowhook now forces that size every time the window opens so a stale saved layout can never shrink it again. It re-centers once after the reset.
In-Game
- New "Slot" filter in the gear map: pick which equipment slots to show.
- Best-in-slot items in the gear map now show the upgrade percent on the left with the skull on the right, and the percent in item tooltips now matches the gear map.
- The boss picture and gold ring now show the first time you hover an item in the gear map, instead of only on the second hover.
- The gear map window is taller now. (It re-centers once the first time you open it after this update.)
[v3.7.2-release] - 06/24/2026
Fixed
- Trinkets no longer show as upgrades when swapping to them would lower your item level. At max level a trinket is scored by its Icy Veins tier rank (
trinket_rank.lua:300000 - rank*2000 + ilvl), with unranked trinkets pinned to a100000 + ilvlfloor. When a curated (ranked) trinket was compared against an equipped trinket that is not on the list, thedeltawas the raw gap between the ranked synthetic score and the unranked floor (e.g. a rank-3 trinket at ilvl 250 read as "+177%" over an unranked stat-stick at ilvl 253), so bag/loot/tooltip markers and/gm scoreflagged a lower-ilvl trinket as a big upgrade even though it was a downgrade. Auto-equip already refused these swaps viaAutoEquip._allowTrinketSwap(candIlvl >= equippedIlvl), but that guard only lived at the equip step.Compare.evaluateImplnow applies the same rule at the shared evaluation source: a trinket candidate whose item level is below the trinket it would replace falls back to the honest stat-based delta (and drops the tier override), so every surface agrees with auto-equip and the in-game tooltip. Tier still wins on equal-or-higher item level. Covered bytools/trinket-ilvl-downgrade-selftest.lua. - Corrected a stale gear-map dedup selftest (
tools/outranks-duplicate-selftest.lua) that still asserted the pre-v3.7.0 "higher-difficulty copy wins" behavior; it now matches the shipped "lowest-difficulty, easiest source wins" collapse thattests/lua/test_gearmap_dedupe.luaenforces.
In-Game
- Trinkets no longer show as an upgrade when equipping them would lower your item level. A lower item-level trinket is now compared on its real stats, matching what the in-game tooltip shows, so the marker and the upgrade percent agree with what you see.
[v3.7.1-release] - 06/24/2026
Fixed
- Quest reward upgrade markers no longer trigger an "attempted to format a negative copper value" error on the current retail client. To read each reward's item link,
QuestRewardHookpopulated a hidden scannerGameTooltipviaSetQuestItem/SetQuestLogItemand then readtip:GetItem(), but populating that tooltip drove Blizzard'sGameTooltip_OnTooltipAddMoney->FormatMoneyover the item's money line, which produced a garbage negative copper value (-1492067296) and threw through the retailTooltipDataHandler. The hook never used the money line; it only needed the link. It now resolves links with the directGetQuestItemLink/GetQuestLogItemLinkgetters (no tooltip, no money processing), keeping the scanner-tooltip path only as a fallback for any flavor that lacks those getters (those use the old tooltip system, which does not have this money bug).
In-Game
- Fixed an error that could appear when you opened a quest's reward list.
[v3.7.0-release] - 06/24/2026
Added
- Baganator support: GearMatic's best-in-slot skull and an upgrade indicator now render inside Baganator bags through Baganator's public corner-widget and upgrade-plugin API (new
BaganatorIntegration.lua). It registersgearmatic_bis(the skull as a top-right corner widget) andgearmatic_upgrade(Baganator's upgrade slot), reusing a sharedns.BagOverlay.MarkerVerdict(link)helper so the skull/upgrade rule matches the default Blizzard bags exactly. Markers refresh on equipment change, bag update, active-scale change, and the/gm bistest previewtoggle. Baganator's buttons are anonymous and pooled and expose item data via.BGR, so the generic bag-overlay detector never saw them; the corner-widget API is the supported path and survives Baganator's layout rebuilds.
Changed
- Pawn scale selection is now visibility-first. GearMatic mirrors the scales you keep visible in the live Pawn addon: a single visible class scale becomes active even when it has no spec tag (a copied or customized scale), multiple visible scales prefer the current spec and otherwise resolve deterministically by name, and scales you have hidden or deleted in Pawn are pruned from GearMatic on import instead of lingering. Pruning only ever removes Pawn-sourced scales (
source == "pawn"); pasted import strings and plugin scales are never touched. The liveusePawnWeightspath uses the same deterministic single-visible logic. - An explicit scale choice is now sticky. Picking a scale (the Settings profile list,
/gm scale <name>, or a pasted/gm import) sets a per-character pin inGearMaticDB.activeManual[charKey], and Pawn auto-import will not overwrite a pinned, class-valid scale. This fixes the case where a Pawn user's customized Retribution scale (which carried no spec tag) kept being reset to a Holy scale on every login.
Fixed
- Gear map duplicate collapse keeps the easiest-to-obtain source again. When the same item drops at the same score from multiple difficulties, an inverted difficulty comparator in
outranksDuplicate(accidentally flipped fromcd < hdtocd > hdduring the v3.5.0 item-level-aware best-in-slot work) made the harder source win the collapse. Reverted so the lowest-difficulty, easiest source survives, astests/lua/test_gearmap_dedupe.luaasserts.
[v3.6.1-release] - 06/24/2026
Fixed
- Settings panel crash on the current retail client. The bundled Ace3 (AceConfigDialog rev 1296, 2022) called
tooltip:SetText(name, 1, .82, 0, true), but retail'sGameTooltip:SetTextgained analphaparameter, so thetrue(intended aswrap) landed in the numeric alpha slot and threwbad argument #5 to 'SetText' (outside of expected range)whenever you hovered a category or control in the options window. All four affected call sites now pass1for alpha (AceConfigDialog 523 + 1518, and bothAceGUIContainer-TreeGroupcopies), matching the upstream Ace3 rev 1386 fix. Addedtools/aceconfig-settext-retail-selftest.luato lock it.
In-Game
- Fixed a crash that could happen when opening GearMatic's settings and moving your mouse over the options on the current retail patch.
[v3.6.0-release] - 06/23/2026
Added
- Equip emote: a new Social option (
social.emote, on by default) performs a/emotecarrying the item link whenever you equip a new piece of gear (Social.EmitUpgradeEmote), throttled to once per 25 seconds. It fires on any equip, manual or auto, independent of the auto-equip setting. The toggle is localized in all 12 locales.
Changed
- The equip emote and the existing party/raid/guild broadcasts now also fire when you equip into a previously empty slot. The
prior == nilearly return inSocial.OnEquipChangeis removed andbroadcastEquipis called withprior ~= nilso the channel broadcast still only fires on a real swap while the emote covers every equip. Social broadcasts and equip alerts run off the rawPLAYER_EQUIPMENT_CHANGEDevent, so they are not gated by the auto-equip toggle.
Fixed
- Equipping a full set of gear at once (a spec gear swap touching many slots) no longer plays a stack of overlapping alert sounds.
Alert.playSoundis gated by a 3-second global cooldown (Alert.SoundCooldownPasses).
In-Game
- Equipping a full set of gear at once no longer plays a pile of overlapping alert sounds. They are spaced out now, so a single gear swap does not flood you with noise.
[v3.5.0-release] - 06/23/2026
Changed
- Item-level-aware best-in-slot. The Icy Veins best-in-slot list is no longer an absolute override.
Score.ScoreItemnow ranks plain best-in-slot gear by its real stat score (item level plus your stat weights decide the slot), and reserves the float override for items whose worth a stat score cannot see: trinkets, tier-set pieces, and Classic class/dungeon set weapons, resolved through the newns.GMBiSEffecttable andBR.IsEffectBiS. The best-in-slot skull is now a marker on the genuinely-best-to-equip piece rather than a forced float. - Among duplicate copies of one item, the higher difficulty / item level now wins.
GearMap/Engine.outranksDuplicatewas keeping the lower difficulty (Raid Finder); it now prefers the higher (so a Mythic copy beats its Raid Finder copy). Score.ScoreItemresolves three buckets at max level: trinket override, effect-best-in-slot float, then plain best-in-slot real stat score with abisflag; everything stays gated to max level.
Added
ns.GMBiSEffect: web-sourced (Wowhead, cross-checked) tier-set and Classic set-bonus piece names per spec for all five versions. 548 effect names across 147 specs, validated against the best-in-slot lists bytools/bis-effect-coverage-selftest.lua.Engine.SuppressBeatenBiS: after collapse, a plain best-in-slot skull stands down when a non-best-in-slot piece out-scores it in the same slot (two best-in-slot pieces never suppress each other, so two best-in-slot rings or trinkets both keep their skulls).BestItems.IsBestEquippable: best for any slot, second-best only for genuine two-ring / two-trinket slots.
Fixed
- The bag and character-sheet skull stood up on a best-in-slot piece even when a higher-scoring item was already owned (for example a higher-item-level two-hander out-scoring a best-in-slot one-hander). The bag and equipped skull are now gated on
BestItems.IsBestEquippable, so the skull marks only the piece you should actually equip. Loot-roll skulls keep the simpler rule, since a roll item is not owned yet. - Mists of Pandaria Brewmaster monk best-in-slot row was corrupted with Windwalker (damage) tier pieces and a mislabeled glove, leaving the tank with no working set bonus. It now uses the tank set, Shoulderguards / Chestguard / Gauntlets / Legguards of Seven Sacred Seals, for the 2-piece and 4-piece bonus, with the missing wrist slot filled and the dual-wield weapons split into main and off hand.
In-Game
- Item level and your stats now decide the best item in a slot. GearMatic no longer always forces the published best-in-slot item; the best-in-slot skull appears only on the piece that is genuinely your best to equip. It prefers the highest-difficulty version, so a Mythic piece beats its Raid Finder copy, and it steps aside when a higher item-level piece is the bigger upgrade. Set pieces and trinkets still win their slot, because their set bonuses and use effects are worth more than raw stats can show.
- The skull in your bags and on your character sheet now stands down when you already own a better item for that slot, so it marks only the piece you should actually equip.
- Mists of Pandaria: fixed Brewmaster monk gear recommendations that were using the wrong damage set pieces instead of the tank set.
[v3.4.1-release] - 06/23/2026
Changed
- The in-game AddOns-list description (TOC
## Notes) was rewritten to cover per-spec Icy Veins scoring and the best-in-slot skull marker, then localized into all 10 client locales (deDE, esES, esMX, frFR, itIT, koKR, ptBR, ruRU, zhCN, zhTW) via## Notes-<locale>, reusing the shared LibMatic addon descriptions in their native-accent form. - Shared LibMatic update: the GearMatic entry in the in-game "More Infinite Loop Alchemist Addons" settings list now reflects its current best-in-slot summary, in all 11 locales.
Fixed
- Upgrade percentages no longer use the internal best-in-slot or trinket ranking number.
Score.ScoreItemruns the BiS/trinket override hooks (synthetic ordering scores around 400000 / 300000) for ranking, but those scores were divided directly inpercentDelta, so a best-in-slot or trinket item compared against a normally-scored equipped piece showed runaway percentages such as +162411%.Score.StatScorenow exposes the real stat score and the evaluation carries a stat-basedstatDeltaused for the displayed percent, while the synthetic score is kept only for ordering. Best-in-slot items render the "best" badge on tooltips and the skull on the Gear Map instead of a number. - The best-in-slot and trinket-tier overrides are gated to max level via
ns.Compat.IsMaxLevel. While leveling, items rank on their real stats, so the endgame best-in-slot list no longer marks a leveling-item-level drop as best.
In-Game
- GearMatic's in-game description now appears in your game's language.
- Upgrade percentages are accurate again. A best-in-slot item shows the skull marker instead of a wildly inflated percentage, and every other item shows its true upgrade percent.
- The best-in-slot skull now appears only at max level, where the best-in-slot list applies. While you are leveling, GearMatic ranks gear by its real stats and points you at the biggest upgrade for your level instead of a max-level piece.
[v3.4.0-release] - 06/22/2026
Added
- Icy Veins best-in-slot override: for every live game version, GearMatic marks the Icy Veins published best-in-slot item for each slot as the best choice, overriding its own stat-weight ranking for those slots (a true BiS pick accounts for set bonuses, trinket effects, and crafted embellishments that a stat score cannot value).
Scales/bis_lists.luaembeds the scraped lists keyed by item name (difficulty/ilvl-agnostic, since a piece exists at many ilvls/difficulties under one name);Scales/bis_rank.luafloats a BiS-named item to the top of its slot (above the trinket-tier override), resolving vanilla sub-modes viaSpecLogicWeights.ResolveFlavor(Hardcore falls back to Era).Score.ScoreItemruns the BiS hook before the trinket hook. 151 specs: retail 39, mists 34, tbc 26, vanilla/Era 26, vanilla_sod/SoD 26. - FAQ entry (
faq_q_bis/faq_a_bis, all 12 locales) explaining the Icy Veins best-in-slot override and how it is verified. - Skull marker (
Textures/bis-skull.tga) for Icy Veins best-in-slot items: shown instead of the upgrade double-chevron on bag items, on the equipped paperdoll slot, and on the group-loot roll window.BiSMarker.luadrives the equipped + roll overlays viaPLAYER_EQUIPMENT_CHANGED,CharacterFrameOnShow, andSTART_LOOT_ROLL/CANCEL_LOOT_ROLL; detection reuses the BiS engine (ns.BiSRank.IsPlayerBiS), so it covers all five live versions.
Verified
tools/bis-match-selftest.lua: scores each version's full/gm gearcheck dumpand asserts GearMatic's top distinct picks per slot are the Icy Veins best-in-slot items (deduped by name; capped by how many BiS items are in the dump). 569/569 testable slots matched across retail (233), mists (42), tbc (116), vanilla/Era (158), vanilla_sod/SoD (20). All 32 repo selftests green.
In-Game
- GearMatic now marks the Icy Veins best-in-slot item for each slot as the best choice on every live game version, even when another piece looks better on raw stats, because the true best-in-slot pick accounts for set bonuses, trinket effects, and crafted items that stats alone cannot judge.
- A skull icon flags your best-in-slot pieces in your bags, on your character sheet for a piece you already wear, and on the group-loot roll window the moment a best-in-slot item is up for roll, replacing the usual upgrade arrow for those pieces.
- The in-game FAQ has a new entry explaining how the best-in-slot list works and why a lower-stat piece can be marked best.
[v3.3.0-release] - 06/22/2026
Added
- Re-authored Retail (Midnight, patch 12.0.7) and Mists of Pandaria per-spec stat-priority logic as power-map override files (
Scales/logic_retail.lua, 39 specs;Scales/logic_mists.lua, 34 specs), loaded afterlogic.lualike the TBC and Classic blocks. Sourced from a verified Icy Veins crawl that reads the>vs=operator directly from the guide's stat-priority markup (the separator icon class on retail, the ordered<h3>sequence on MoP Classic); text-flattened scraping silently drops=ties, which had turned ~14 retail specs' equal secondaries into strict orders. Equal secondaries now share a weight, removed the hallucinated Elementalmasteryrating86% cap.tools/speclogic-retail-mists-selftest.luaasserts every spec's order and every equality (1498 checks). LibMatic-ChangeLog-1.0(MINOR 5): the changelog popup renders at mostspec.maxEntriesmost-recent versions, default 10, so popups across all addons stay focused on recent releases.
Changed
- The in-game changelog popup combines a release day's player-facing changes into a single entry so same-day releases are not scrolled past. The 3.3.0 popup entry folds in the player-facing changes from 3.1.0, 3.2.0, and 3.2.1;
CHANGE_LOG.mdkeeps the per-version history below.
Fixed
/gm gearcheck dumpnow captures full loot coverage regardless of the dumping character's level. The Encounter Journal scan passesallTiers, so it walks every tier instead of only the tiers near the character's level, andallTiersis threaded into the loot cache key so it does not collide with the level-scoped gear-map cache. The offline full-coverage check (tools/gearcheck-offline.lua) now loadslogic_retail.luaandlogic_mists.luaso it grades the re-authored weights; verified clean (Retail 39/39 specs, Mists 34/34, 0 armor inversions on the full dumps).
In-Game
- Gear recommendations on Retail and Mists of Pandaria are now tuned for each specialization from the latest class guides, including correctly valuing stats the guides rate as equal, such as Elemental Shaman's Haste and Crit. Strike.
[v3.2.1-release] - 06/22/2026 (Hotfix)
Fixed
- Hotfix: auto-equip threw "bad argument #2 to 'tonumber' (base out of range)" when checking a trinket whose required level was above 36. The trinket guard read item level with
tonumber(select(4, GetItemInfo(link)));selectreturns multiple values, so the 5th return (itemMinLevel) was passed astonumber's base argument and any required level over 36 is an invalid base. Item-level reads now go throughAutoEquip._safeItemLevel, which truncatesselectto the single item-level value, matching the safe pattern used elsewhere in the addon. Regression test added. - The minimap button now opens GearMatic's settings in the standard Blizzard options panel instead of the separate floating AceConfig window.
Settings.Openopens the registered Blizzard category viaSettings.OpenToCategory(retail) orInterfaceOptionsFrame_OpenToCategory(classic), captured by the LibMatic panel registration, falling back to the standalone dialog only if neither category API is present.
Changed
- The FAQ question headings now use the GearMatic purple theme color instead of gold.
In-Game
- Fixed an error that could appear in chat when GearMatic checked a trinket while equipping gear automatically.
- Clicking the minimap button now opens GearMatic's settings in the normal options window instead of a separate floating panel.
- The FAQ headings now match GearMatic's purple theme.
[v3.2.0-release] - 06/22/2026
Added
- Trinket tier ranking: trinket slots are ranked by their Icy Veins guide tier for the player's spec instead of by stat score, because a stat score cannot value an on-use or proc effect. Score is
300000 - rank*2000 + ilvl, so the guide tier dominates and item level breaks ties within a tier; unranked trinkets sit below all ranked ones, ordered by item level among themselves. Self-contained inScales/trinkets.lua(the emitted tier tables) andScales/trinket_rank.lua(ns.TrinketRank.ScoreItem), hooked intoScoring/V2/Score.luaso every scoring path (tooltip, bag chevron, gear map, auto-equip, gearcheck) uses it. Covers retail, mists, tbc, and vanilla (Classic Era, inherited by Season of Discovery and Hardcore). Wrath and Cata have no tier data yet and fall back to stat scoring. English item-name match only; non-English clients fall back to stat scoring for trinkets. - FAQ entry explaining trinket ranking, added to the in-game FAQ tab and translated into all twelve locales.
Fixed
- Auto-equip no longer downgrades an equipped trinket's item level when a lower-item-level but higher-tier trinket scores higher (
AutoEquip._allowTrinketSwap). Trinket swaps now require equal or higher item level unless the slot is empty.
Changed
/gm gearcheckreports trinket tier-picks separately from jewelry and cloak stat-picks, since trinkets are now tier-decided rather than stat-decided.
In-Game
- Trinkets are now ranked by their Icy Veins guide tier for your spec instead of by raw stats, so a higher-tier trinket is preferred even at a lower item level, with item level breaking ties inside a tier. Auto-equip will not downgrade a trinket's item level on a tier score. Works on Retail, Mists of Pandaria, Burning Crusade, and Classic Era including Season of Discovery and Hardcore.
- The FAQ tab has a new entry explaining how trinket ranking works.
[v3.1.0-release] - 06/22/2026
Added
- In-game FAQ tab in GearMatic's settings, tailored to the player's live game mode. Content is resolved at open time with the same flavor and season detection the stat logic uses, so the vanilla client splits into Classic Era, Season of Discovery, and Hardcore. Six modes carry mode-specific "how it decides your upgrades" answers (Retail, Mists, Burning Crusade, Classic Era, Season of Discovery, Hardcore); Wrath and Cata show a generic answer. Shared questions cover the honest "do I still need to sim" answer (no invented percentage), why a lower item level can win, role coverage, where the weights come from, and the optional Pawn toggle. New
FAQ.luadata file andbuildFAQTab()in Settings.lua; all twenty FAQ strings localized in all twelve supported languages. - Custom Icy Veins stat logic for every Burning Crusade class and spec in
Scales/logic_tbc.lua, replacing the previous crawled TBC pool with explicit per-stat power maps plus caps, the same model as the vanilla retune. Adds Retribution Paladin, which the old TBC pool omitted. Validated at full coverage against a 3,802-item dump (14 of 29 specs clean, all remaining inversions verified as legitimate itemization, no ratio bugs). - Distinct Season of Discovery and Hardcore stat modes for vanilla, selected by
C_Seasons.GetActiveSeason. SoD authors the rune-reshaped tanks and Int-led Restoration Shaman; Hardcore applies a Stamina and Intellect survival tilt on the recommended spec per class, falling back to Classic Era elsewhere. /gm gearcheckand/gm gearcheck dump: an in-game convergence test that scores GearMatic's own loot tables for every spec of your class and reports item-level inversions, plus a throttled full-table stat dump that feeds an offline checker (tools/gearcheck-offline.lua) so weights can be validated against the full item table beyond the client cache cap.
Changed
- Strength is now counted as two attack power for the classes that get it (Warriors and Retribution Paladins) on Classic Era, Hardcore, and Burning Crusade, fixing strength gear being ranked below raw attack power. Enhancement Shaman values Agility above attack power on vanilla, and is treated as Strength-first on Burning Crusade per the Icy Veins guidance. Hunters are scored on ranged attack power and never melee attack power.
- The spec weapon-type rule is now enforced on the bag upgrade chevron, not just auto-equip. Subtlety Rogue is locked to daggers in both hands. Retail Hunters are blocked from one-handed melee weapons on Beast Mastery and Marksmanship.
Fixed
- Auto-equip now swaps in the best matching weapon from your bags when an equipped weapon violates your spec's weapon-type rule, instead of leaving a higher item-level but illegal weapon equipped (for example, a Subtlety Rogue with a sword in the off hand now gets the best bag dagger equipped).
- Tooltip upgrade scoring uses the live active scale for your current spec, matching the bag chevron, so the two no longer disagree.
- The haste-breakpoint weight is capped so your main stat and weapon outrank haste-to-cap, and a breakpoint stat is no longer force-boosted when its current value cannot be read.
- The gearcheck inversion pool is scoped to each class's armor specialization, and weapons are decided by stats rather than counted as inversions.
In-Game
- GearMatic now has an FAQ tab in its settings, written for your exact game version, answering the common questions in plain language. The honest take on simming: the vast majority of players never need it, only cutting-edge raiders chasing the last percent or two on trinket procs, set bonuses, or near-tie calls benefit from a sim.
- Season of Discovery and Hardcore have their own tuned recommendations. Season of Discovery accounts for rune builds that change a spec's role; Hardcore weights survival stats up so close calls break toward the safer piece.
- Burning Crusade gear scoring is more accurate for every class and spec, with Strength counted as two attack power for Warriors and Retribution Paladins, Hunters scored on ranged attack power, Enhancement Shaman treated as Strength first, and Retribution Paladins now covered.
- The green upgrade marker on your bags now respects your spec's weapon type, Subtlety is kept to daggers in both hands, and auto-equip pulls the best matching dagger from your bags instead of leaving a higher item-level sword equipped. Tooltip upgrade scores now match the bag marker.
[v3.0.0-release] - 06/21/2026
Added
- New per-specialization stat logic derived from the Icy Veins class guides for every spec across Retail, Mists of Pandaria Classic, Classic Era, and The Burning Crusade Classic. Each spec carries its stat priority, hard stat caps, and haste breakpoints. Canonical per-expansion caps are used (Classic Era 9% melee hit / 16% spell hit; TBC 9% / 16% plus 6.5% dps and 14% tank expertise; MoP 7.5% / 15% plus 7.5% dps and 15% tank expertise), routed by role and by caster vs melee, with healers excluded from hit/expertise caps and tank defensive caps (defense, armor) preserved.
- Cap- and breakpoint-aware scoring: a capped stat (hit, expertise, spell hit) is weighted highly until your current character reaches the cap, then drops; a haste breakpoint stat is boosted while under the threshold and demoted once past it, handing priority to the next stat (for example Subtlety Rogue Haste to roughly 700 for Trickster or 1100 for Deathstalker, then Mastery).
- New "Use Pawn weights" option (off by default, under the Pawn settings, only enabled when the Pawn addon is loaded). When on, GearMatic scores your gear with Pawn's live stat weights for your current specialization instead of its built-in Icy Veins guidance. Localized in all twelve supported languages.
Changed
- The primary stat (Strength/Agility/Intellect) and weapon damage are now the dominant scoring weights, so for gear that carries a primary stat (head, chest, weapons, and so on) item level decides: a higher item-level piece wins instead of a lower one with a tidier secondary-stat split. Slots with no primary stat (rings, neck, cloak, trinkets) are still decided by their stats, matching the guidance that jewelry is the exception. This resolves cases where a lower item-level piece was marked or equipped over a clearly higher one.
- On quest rewards where you choose one of several items, only the single best choice for your spec is marked, instead of several options, with an item-level fallback when no stat scale is available.
- GearMatic's built-in (default) gear scoring now follows the Icy Veins guide logic on all four supported game versions, superseding the previous flat stat-priority weights.
Fixed
- Guarded against Midnight (12.0) "secret values": stat reads such as GetCombatRating can return secret values that error when compared in addon code. GearMatic now detects them with issecretvalue and wraps the comparisons, so cap and breakpoint checks degrade safely instead of throwing a Lua error during scoring.
In-Game
- GearMatic's gear ratings are now powered by the Icy Veins class guides, tuned for your exact specialization on every game version and for every role including healers and tanks. It knows your spec's stat caps and breakpoints and weighs your main stat and item level heavily, so a higher item-level piece wins unless a lower one truly has better stats (as with rings and necklaces).
- Examples: Retail Subtlety Rogue values Haste up to your hero talent breakpoint (about 700 for Trickster, 1100 for Deathstalker) then Mastery; Mists reaches your Hit and Expertise caps first; Burning Crusade reaches the hit cap, casters the spell hit cap, melee expertise, and tanks aim to be uncrittable; Classic Era reaches the melee hit cap and caster spell hit cap first.
- On quest rewards where you pick one item from several, only the single best choice for your spec is now marked.
- New option (off by default): if you have Pawn installed, you can switch GearMatic to score with Pawn's weights instead.
[v2.30.1-release] - 06/20/2026
Added
- GearMatic now contributes a sample upgrade alert to the shared alert stack, so its alert can be shown when you preview or arrange your on-screen alerts.
Fixed
- The green upgrade chevron (shown on bag items, quest rewards, and alerts) no longer depends on the loot-specialization tag (C_Item.GetItemSpecInfo) to decide whether an item is off-spec. That tag is a loot recommendation, not a usability restriction, and routinely omits a perfectly valid specialization (for example, a dagger's tag could exclude Subtlety even though Subtlety uses daggers), which wrongly suppressed the chevron on genuine upgrades across many class and spec combinations. The off-spec check now keys solely on an item's explicit specialization/class restriction text, so genuinely restricted items stay unmarked while real upgrades for your current spec are shown. Applies on every game version; on versions without a specialization system there is no off-spec suppression, unchanged.
- A bare "/gm auto" command no longer silently toggles upgrade detection on or off. It now reports the current state, and you change it explicitly with "/gm auto on", "/gm auto off", or "/gm auto toggle". Because all of a player's characters share one settings profile, an accidental bare toggle previously disabled detection on every character at once, which hid every upgrade chevron until it was switched back on.
In-Game
- The green upgrade marker now shows on gear that suits your specialization but was being skipped before. For example, a dagger upgrade for a Subtlety Rogue now correctly gets the marker on quest rewards and bag items. Gear made for a different specialization still stays unmarked.
- Typing "/gm auto" by itself now tells you whether upgrade detection is on or off, instead of switching it. Use "/gm auto on" or "/gm auto off" to change it.
- When you preview or arrange your on-screen alerts, GearMatic now shows a sample upgrade alert.
[v2.30.0-release] - 06/20/2026
Fixed
- Auto-equip now respects each spec's required weapon type and will no longer place a weapon of the wrong type in your main hand. A spec that needs a dagger (such as Assassination Rogue) keeps a dagger instead of being handed a higher item-level sword, and Hunters are matched to the correct ranged or melee weapon for their specialization. The rule is applied during the auto-equip sweep on every game version where the specialization can be read; if no legal weapon is available, your current weapon is left in place.
Changed
- The gear map's source filters (raid, dungeon, crafted) and the per-source difficulty dropdowns are now available at every character level, not only at max level.
- Gear you will be able to use within a few levels is shown at full brightness with its required level, instead of being dimmed to grey.
- The gear map now matches gear to your level band: while leveling it hides max-level gear you cannot use yet, and at max level it hides low-level leveling gear, so the list stays relevant to where you are. Turning on "Show All Content" bypasses this and shows everything.
In-Game
- Auto-equip no longer puts the wrong weapon type in your main hand. If your spec needs a dagger it keeps a dagger instead of swapping in a sword, and Hunters get the right weapon for their spec.
- The gear map's source and difficulty filters now work at every level, not just at max.
- Gear you will be able to use soon is shown normally instead of greyed out.
- The gear map now shows gear that fits your level: leveling gear while you level, and max-level gear once you reach max.
[v2.29.0-release] - 06/18/2026
Added
- 11 new bundled fonts, selectable anywhere GearMatic lets you choose a font: Capital Hill, Capital Hill Monospaced, Extra Thick, Extra Thick Monospaced, Fabled Font, Fabled Font Monospaced, High Birth More Letter Gap, Scrambled Eggs, Scrambled Eggs Bold, Tomorrow Night, and Tomorrow Night Monospaced.
In-Game
- 11 new fonts you can pick anywhere GearMatic lets you choose a font.
[v2.28.1-release] - 06/18/2026
Fixed
- Cosmetic items (appearance-only gear such as transmog backs and shirts) no longer receive GearMatic's score block in their tooltip. Because cosmetics carry no real stats, the iLvl heuristic was producing meaningless 100% downgrade lines for every spec; GearMatic now skips cosmetic items entirely on flavors where the game reports them as cosmetic.
In-Game
- GearMatic no longer adds its upgrade info to cosmetic, appearance-only items, so their tooltips stay clean.
[v2.28.0-release] - 06/17/2026
Added
- Multi-source gear map: the /gm gear map now organizes gear by where it comes from (raid, dungeon, and crafted), with on/off checkboxes for each source. Filtering is applied at display time and never triggers a rescan. Each row shows its source, and crafted rows show the profession and recipe.
- Retail crafted gear: the retail gear map now includes crafted items, resolved at runtime to their real max-quality item level and scored through the same path as drops, so a crafted upgrade actually reads as one. Crafted (aspirational) gear is exempt from the recommended item-level ceiling so chase targets are not hidden. Retail crafted/vendor data is generated from a pinned 12.0.7 wago.tools DB2 extract.
- Retail raid tier set pieces: class tier set pieces now appear on the gear map with real stats. They are collected from the player's class sets, identified by elimination (crafted, PvP, and normal drops excluded), and each piece's item level is resolved by grafting a real raid-difficulty bonus tail so it scores like a raid drop at each difficulty.
- Per-source difficulty filters: raid and dungeon each gain a visible difficulty dropdown (Looking For Raid, Normal, Heroic, Mythic) shown when that source is enabled at max level. Difficulty is a display-time filter; every record carries its own difficulty, so toggling never busts the loot cache or fingerprint.
- Very Rare items are grouped at the top of the list under the Very Rare header and closed off with a gold divider separating them from the normal rows.
Changed
- Classic data rebuild: the Vanilla, TBC, and Mists gear datasets were regenerated to schema v3 with crafted, vendor, and token sources and authoritative raid/dungeon tagging.
- Gear-map rows now show where an item drops and at which difficulty (for example "Raid Heroic", "Dungeon Mythic", or "Looking For Raid") in place of the armor-type label. Looking For Raid rows omit the redundant "Raid" prefix; crafted and vendor rows keep their short source tag.
- The gear map window is raised to HIGH frame strata, marked top-level, and brought to the front when it opens, so it sits above the default UI and comes forward when clicked.
- The gear map window is now a fixed 360x400 size (no longer resizable), and the hover tooltip opens on whichever side of the window has more screen room.
- The Vendor source was removed from the retail map: retail vendor data is entirely PvP currency gear, which is never a PvE upgrade, so the toggle only ever showed an empty list. Vendor records are still tracked internally so tier-set detection can exclude PvP set pieces.
- The gear map's default position for a fresh profile now opens at a center-left spot instead of dead center; existing saved positions are unchanged.
Fixed
- Best-item ranking compared one-handed weapons only within their own slot, so a one-hander could be stamped "best" even when an owned two-handed weapon scored far higher. One- and two-handers are now ranked together for the main-hand slot, so a one-hander behind an owned two-hander correctly reads "2nd best".
- Copying chat with /gmc no longer errors on WoW protected strings; the offending line is skipped and the rest of the buffer still copies.
In-Game
- The gear map now sorts gear by source, raid, dungeon, and crafted, with checkboxes to show or hide each. Crafted gear is included with its real item level.
- Retail raid tier set pieces now show up on the gear map with their real stats.
- You can filter raid and dungeon gear by difficulty (Looking For Raid, Normal, Heroic, and Mythic) using the dropdown next to each source.
- Each item now shows where it drops and on which difficulty, like "Raid Heroic", "Dungeon Mythic", or "Looking For Raid", instead of its armor type.
- Very rare items now sit at the top of the list, set off by a divider.
- The gear map window stays on top of other windows and jumps to the front when you click it.
- Classic gear lists were rebuilt to include crafted and vendor gear.
- Fixed a one-handed weapon being wrongly marked your "best" when a two-handed weapon you own scored higher.
[v2.27.1-release] - 06/16/2026
Changed
- Updated for World of Warcraft retail patch 12.0.7 (Mainline interface 120007). No GearMatic-breaking API changes; the legacy globals it still calls remain available and are already behind the per-flavor compatibility layer.
Fixed
- Gear map (retail): the boss portrait in an item's tooltip no longer flashes a magenta placeholder or vanishes until you re-hover. The boss image was being resolved live from the Encounter Journal on every hover (which fails on a cold journal) and streamed into a visible texture, showing the magenta missing-texture color. It is now resolved once while the journal is loaded during the scan, stored on the record, and painted as a static creature icon. The gear-map cache version was bumped so saved maps regenerate with the new data.
- The "More Infinite Loop Alchemist Addons" section in General options was missing the MailMatic icon; added mailmatic-icon.tga so it renders alongside CritMatic and RepMatic.
[v2.27.0-release] - 06/13/2026
Added
- The /gm gear map now surfaces upcoming gear for leveling characters within a level horizon (current level plus a window, capped at max level), instead of showing an empty list at low level. Gear you cannot equip yet but will be able to soon is listed by its required level.
Changed
- Upcoming and empty-slot gear now shows its required level instead of a fabricated "+100%". A real upgrade percentage is shown only when there is an actual equipped item to compare against; rows that tie on percentage break the tie by item value so the strongest options rank first (matching Pawn's value-ranked behavior for slots with no baseline).
- The leveling item-level ceiling is now derived from the level bracket the gear belongs to rather than a near-zero average item level, so a freshly leveling character is not strangled by an over-tight ceiling. Max-level behavior is unchanged.
- Classic stat scoring parity: per-school spell damage (fire, frost, nature, arcane, shadow, holy), block value (distinct from block rating), flat health and mana, and tooltip-line fallbacks for defense and spell hit/crit/haste rating are now extracted and scored on the Classic flavors. Every stat name was verified per flavor against the live game data.
Fixed
- The gear map item tooltip no longer flickers or vanishes while you hover. The list refresh was dismissing the hovered tooltip on every repaint; it now only dismisses when the hovered row's item actually changes.
[v2.26.0-release] - 06/10/2026
Added
- 36 new bundled default stat scales across Classic flavors from current WoWSims data: Vanilla gains Hunter, Tank Rogue, Warden Shaman, Tank Warlock, and Fury/Arms Warrior; TBC gains Hunter, Smite Holy Priest, and Fury/Arms Warrior; Wrath gains 11 specs including both Death Knight roles, both Feral roles, Protection and Retribution Paladin, Combat Rogue, Enhancement Shaman, and Warrior specs; Cataclysm gains 17 specs including all three Death Knight and Hunter specs, Guardian and Feral DPS Druid, and all Warrior and Rogue specs. Existing bundled weights are unchanged, and Retail weights remain in sync with Pawn's current Ask Mr. Robot data, including the Devourer Demon Hunter spec.
- The default-scale refresh tooling now resolves all current WoWSims data formats, preserves the curated Vanilla/TBC/Mists weight sets, and merges the Retail block automatically, so future refreshes cannot drop specs.
Fixed
- Auto-sell at vendors now stops at the buyback window's 12-item capacity per visit and reports how many junk items remain, so an oversized junk pile can never sell past what buyback can recover; the legacy container-info fallback also reads the correct itemID return.
- Loadout equip plans re-validate bag coordinates before every pickup, expire after 15 seconds instead of resuming with stale coordinates on a later bag change, count a step as applied only when the item verifiably equipped, reserve bag slots so two identical items resolve to distinct copies, and can swap rings, trinkets, and weapons directly between equipped slots.
- Loadout item matching reads enchant, gems, and random-suffix data correctly (the old field splitter mis-indexed every field under Lua 5.1, so different-suffix copies hashed identically); saved loadouts migrate automatically from their stored item links.
- Creating a new loadout with an existing name now warns instead of silently overwriting the saved set.
- Ranged weapons are no longer offered as main-hand candidates in the loadout slot flyout on Classic flavors, and a failed flyout equip returns the item safely instead of stranding it on the cursor.
- The Suggest Loadout On Spec Change toggle now works, matching loadouts by name against the new spec.
- Cataclysm Classic: the ranged slot is tracked, scored, and durability-checked again; ranged weapons no longer score against or auto-equip into the main-hand slot.
- The off-spec gate uses the item spec API first and localized tooltip patterns as fallback, so spec-restricted items are filtered correctly in all 12 supported languages instead of only English.
- Weapon speed parsing handles comma decimals on European locales.
- Empty gem sockets are no longer double-counted when both the stats API and the tooltip report them, which inflated socketed-item scores.
- Glyph scanning unpacks the correct values on Cataclysm and Mists Classic, and the talent fallback reads the correct selected value with the proper spec-group argument.
- Imported scales match your class regardless of letter case, the explicitly activated scale always wins over same-spec alternatives in deterministic order, two-prefix Pawn exports parse their real names and class metadata instead of importing as one scale named Pawn, and malformed default-scale entries are skipped instead of erroring.
- Pawn scale auto-import classifies Demon Hunter scales correctly and no longer detects classes inside unrelated words.
- Auto-equip: main-hand-only weapons are never sent to the off-hand slot (which previously retried forever), two copies of the same weapon can be planned for dual wield, and the minimum-upgrade threshold works correctly when scores are negative.
- Alt comparisons no longer read the logged-in character's off-hand or equipped items when scoring another character's gear.
- Tooltip upgrade arrows use GearMatic's own textures instead of Pawn's, fixing broken icons when Pawn is not installed; the green upgrade border resets when a chat-link tooltip switches to a different item; the border now has its own settings toggle and declared default.
- Two identical equipped rings or trinkets form their own upgrade baseline instead of comparing new candidates against a weaker third copy from bags or sets.
- Loot upgrade chevrons follow loot-window pages on Classic, work on the modern Retail loot window, and re-decorate when item data for uncached drops arrives.
- The Loadout browser no longer triggers blocked-action errors from keyboard input during combat on Retail.
- Addon messages from other players are sanitized before display (length caps, escape codes stripped from loadout names and version strings), your own version ping no longer registers you as a peer, and group equip announcements are rate-limited per channel.
- The icon picker unavailable diagnostic prints its message correctly, and a dead spec-detection branch was removed.
Changed
- Bag overlay refreshes are coalesced and event-driven: the once-per-second full-UI frame scan is gone, discovered bag buttons are cached in a registry, per-item verdicts are cached with size caps, and disabling the overlay hides existing chevrons immediately.
- Best-item pools and the stat-extraction cache are no longer wiped on every item pickup or merchant refresh; invalidation now rides bag and equipment change events.
- Spec-restriction lookups are memoized per item, removing a hidden tooltip scan from every evaluation.
- Item tooltips reuse the active-scale evaluation for the border decision and cache the equipped-item fingerprint set, removing a redundant full evaluation and 19 inventory queries per tooltip.
- Quest reward decoration and character rescans are coalesced behind single pending timers, and item-info events only trigger rescans for items actually awaited.
- Auto-equip sweeps evaluate only the bags that changed and skip the weapon planner when no weapon changed and equipment is unchanged.
- The loadout sidebar hover highlight is driven by enter/leave events instead of per-frame polling, and the sidebar template probe no longer creates a duplicate frame.
- Alert frames are pooled and fully reused instead of permanently allocating a new frame, font string, and animation groups per alert; loadout keybind buttons are pooled by ordinal across renames; the armor cache is size-capped; profile switches refresh minimap, keybinds, and overlays immediately; the per-character seen-items list stores timestamps and prunes entries older than 180 days.
In-Game
- Auto-sell now stops at 12 items per vendor visit, exactly what the vendor's buyback tab can hold, and tells you how many junk items are left, so nothing can ever be sold beyond what you can buy back.
- Loadouts are far more reliable: swapping two rings or trinkets between their slots works, two copies of the same item equip correctly, the result message reports what actually equipped, and a stuck swap times out safely instead of grabbing the wrong item later.
- Creating a new loadout with a name you already use warns you instead of silently overwriting the old set.
- Hunters on Cataclysm Classic: your ranged weapon is tracked, scored, and durability-checked properly again.
- Playing in any supported language: items restricted to another specialization are now filtered out correctly, and weapon speeds with comma decimals are read properly.
- Upgrade arrows in tooltips display correctly without the Pawn addon installed, and loot window upgrade markers now work on Retail and follow page turns on Classic.
- Pasted and imported stat scales are honored properly: your chosen scale stays active, imports keep their real names, and Demon Hunter scales import for the right class.
- Smoother play: looting, opening bags, and mousing over items do far less hidden work, and long sessions no longer slowly grow memory from alerts.
- The green tooltip border for upgrades now has its own on/off setting.
[v2.25.0-release] - 06/09/2026
Added
- Use shared LibMatic alert position option, on by default: alerts from all Infinite Loop Alchemist addons anchor to one shared screen position and merge into a single stack, newest on top. Turning it off restores this addon's own alert position and stacking.
- Max Shared Alerts option, default 5: caps how many alerts the shared stack shows at once across all addons combined.
- The shared position and limit stay in sync across addons and persist through reloads; setting them from any one addon applies to all.
- Both new options are fully localized across every supported language.
In-Game
- New option: alerts from all Infinite Loop Alchemist addons can share one position on screen and stack neatly together, newest on top. On by default; turn it off in the alert settings to keep this addon's own alert position.
- New Max Shared Alerts setting controls how many alerts can be on screen at once in the shared stack, 5 by default.
- Drag the alert position in any one addon and every addon using the shared position follows.
[v2.24.0-release] - 06/08/2026
Added
- Bounce Style selector on the Alert Messages settings, choosing between Bounce and Classic Bounce for the gear alert animation (default Classic Bounce), driven by the shared LibMatic-CombatTextBounce styles.
- Preview buttons on the Alert Messages settings fire a sample upgrade/downgrade alert so you can test your look.
- Reset buttons on the Alert Font and Alert Messages settings restore those sections to their defaults.
- Picking a sound in the Sound settings now plays it immediately so you can preview each option (LibMatic-Settings play-on-select).
Changed
- Gear upgrades now default to the Level Up sound and gear downgrades to Zombie Attack.
- Mute All Sounds now defaults to off, so gear alerts make sound out of the box.
- Cleaned up the shared LibMatic sound pack: removed duplicate dropdown entries, renamed a couple of sounds for clarity, and re-normalized the custom alert sounds louder.
- Resetting a profile now prompts for confirmation. LibMatic-Settings injects an AceConfig confirm onto the AceDBOptions Reset Profile control, so the Profiles tab asks before wiping a profile.
Fixed
- Corrected the Wrath of the Lich King Classic TOC interface (was
38001, a non-existent client tagged on CurseForge as 3.80.1; now30405for Wrath Classic 3.4.5), so the Wrath build is matched to the right client. - Change-log popups from different Infinite Loop Alchemist addons are now independent. LibMatic-ChangeLog tracks each open window in a set and cascades them instead of sharing one frame, so closing one addon's popup no longer dismisses the others.
In-Game
- New Bounce Style option lets you pick how gear alerts animate (Bounce or Classic Bounce), with Preview buttons to test your look and Reset buttons to restore the Font and Messages settings.
- Gear upgrades play the Level Up sound and downgrades play Zombie Attack by default, and gear alerts make sound out of the box.
- Picking a sound in settings now plays it, the sound list is cleaner and louder, and resetting a profile now asks you to confirm first.
- Fixed the Wrath Classic build so it installs on the correct game version.
[v2.23.1-release] - 06/08/2026
Changed
- The General settings page now shows a short, localized description under each addon in the More Infinite Loop Alchemist Addons section, sourced from LibMatic-Settings.
[v2.23.0-release] - 06/07/2026
Added
- Alert text and the gear icon now use a shared adjustable drop shadow from LibMatic-AlertShadow, with a Shadow strength slider on the Alert Font settings to set how dark the shadow is.
- Alerts now defer under native full-screen popups (renown, level-up, cinematics) via LibMatic-OverlayGuard, so a gear alert landing during one shows right after the screen clears.
/gm test levelup,/gm test renown, and/gm test cinematicfire the sample gear alert behind a look-alike of that native screen, so you can preview the held-then-pop deferral without leveling. Plain/gm testis unchanged.
Fixed
- The alert sound now plays together with the alert. When an alert is held under a native screen, the sound waits and plays when the alert appears instead of during the screen.
- An empty gear slot is now treated as a fillable upgrade target, so equipping into an empty slot registers as an upgrade.
In-Game
- New Shadow strength slider makes gear alerts easier to read. Turn it down for a lighter shadow or to 0 for none.
- Gear alerts no longer get hidden behind the game's renown, level-up, and cinematic screens. They show right after, and the sound now plays with the alert instead of during the screen.
- Equipping gear into an empty slot now shows as an upgrade.
[v2.22.0-release] - 06/06/2026
Added
- 15 new alert sounds available from the shared LibMatic sound pack: Alarm Clock, Anima Cast, Artifact Unlock, Banshee, Deathwing Wound, Epic Loot Toast, Icy Touch, Legendary Toast, LFG Denied, Mission Complete, Shop, Shop 2, Ten, Titan Light, and World Quest Complete.
Changed
- The alert "Start delay" control is now sourced from LibMatic-Settings' shared
BuildCountUpControlsinstead of a hand-rolled option. No change in behavior.
[v2.21.3-release] - 06/06/2026
Fixed
- Off-hands and shields showed a false +100% upgrade when a two-handed weapon was equipped. With a 2H weapon in the main hand the off-hand slot is empty but blocked, you cannot equip an off-hand or shield without dropping the 2H. GearMatic was comparing the candidate against the empty off-hand slot (baseline 0) and reporting +100%. It now suppresses off-hand/shield evaluation entirely while a 2H is equipped.
- Items showed a false +100% upgrade for an alt whose gear GearMatic had never recorded for that slot. For an alt a missing slot means "unknown," not "empty." GearMatic now treats a missing alt baseline as not-comparable and shows no line, instead of assuming an empty slot and claiming a +100% gain.
- The character gear browser failed to open on retail 12.0 because
ItemButtonTemplatedid not resolve. The slot buttons now fall back to a plain icon button when the template is unavailable, so the browser opens on every flavor. Also fixed afooterTextnil crash that fired on durability updates when the browser was closed or only half-built.
Changed
- The other-characters lines on an item tooltip now show only characters the item is an upgrade for (at least a 1% gain), not downgrades. A character appears only when the item is actually worth sending to them.
- Weapons are now filtered by class proficiency, not just armor. An item is no longer shown as an upgrade for a character whose class cannot equip that weapon type (for example a two-handed weapon or staff for a Rogue, a sword for a Priest). Backed by a per-class weapon-type table verified against current-retail sources.
In-Game
- Off-hands and shields no longer show a false upgrade when you have a two-handed weapon equipped.
- Items no longer show a false upgrade for one of your other characters until GearMatic has actually seen that character's gear.
- The character gear browser opens reliably again.
- On an item's tooltip, your other characters now appear only when the item is an upgrade they can actually use, the right class for the weapon and a real gain.
[v2.21.2-release] - 06/05/2026
Fixed
- Upgrade/downgrade alert percentages are now fully colored. The alert colored only the digits; the trailing
%sign sat after the color reset and stayed the item's rarity color. The whole token (the+/-, the number, and the%) is now colored green for a gain and red for a loss, while the item name keeps its quality color. Fixed in both the static render and the roll-up count animation (LibMatic-CountUp bumped to MINOR 6). - Bag upgrade arrow and auto-equip ignored items the game did not loot-tag for the current spec. The current-character gate rejected any item whose
C_Item.GetItemSpecInfolist did not include the active spec, so usable upgrades (for example certain trinkets not loot-tagged for a healer spec) showed+X%on the tooltip but got no bag arrow and were skipped by auto-equip. The gate no longer trusts the loot-spec tag for usability; it relies on GearMatic's own scoring and keeps only the hard "For X specialization." tooltip restriction. - Items your class cannot wear no longer show any GearMatic per-spec lines. Armor proficiency is class-wide, so an item you cannot equip in your main spec cannot be equipped in any spec. The tooltip previously still showed off-spec "best/2nd best" badges for unwearable armor (for example mail on a cloth class) because the wear check only gated the upgrade/downgrade rows, not the badges.
In-Game
- Upgrade and downgrade alert percentages are now fully colored: green for a gain, red for a loss.
- The bag upgrade arrow and auto-equip no longer skip items your spec can use when the game does not label them for your specialization, such as some trinkets.
- Items your class cannot wear no longer show GearMatic spec lines on their tooltip.
[v2.21.1-release] - 06/05/2026
Fixed
- Buyback tooltips showed no GearMatic upgrade lines. The
SetBuybackItemhook resolved the item link viatooltip:GetItem(), which does not populate for a buyback tooltip on retail (and the modernTooltipDataProcessorcallback does not supply a buyback link either), so no link reached the scorer. The hook now resolves the link via the dedicatedGetBuybackItemLink(slot)API (the slot index is passed to theSetBuybackItemhook), with the oldGetItempath kept as a fallback.
In-Game
- GearMatic's upgrade and downgrade lines now show on items in the merchant Buyback tab.
[v2.21.0-release] - 06/05/2026
Added
- Off-spec set building in tooltips. The lines for your other specs now score against gear you own anywhere, including loose items in your bags/reagent bag, not just what is equipped or in a saved Equipment Set. A new owned-item pool (
BestItems.GetOwnedPool= equipped + equipment sets + bags) is used for off-spec evaluation only; the current spec still compares against equipped/sets as before. So while you are Discipline, the Holy and Shadow lines reflect the off-spec set you are collecting and show "best"/"2nd best" when an item belongs in it. - Colored alert numbers. Gear upgrade/downgrade alerts now tint the rolling number and its
+/-sign green for a gain and red for a loss, while the item name keeps its quality color. Powered by a new optionalnumberColorinLibMatic-CountUp-1.0(MINOR 5), with a matching path for the non-animated number.
Changed
- AutoEquip also refuses Warband-until-equipped gear. The bind guard now treats
bindType == 9(Warband-until-equipped, which soulbinds to the character on equip) the same as Bind-on-Equip: skipped from bags unless already bound. An unknown/uncached bind type is now treated as "could bind" (safe skip) rather than "safe to equip".
In-Game
- When you hover gear, the lines for your other specs now count gear sitting in your bags, so you can build a set for your off-spec and see whether an item improves it.
- Gear upgrade and downgrade alerts now color the number green when it is a gain and red when it is a loss. The item name keeps its quality color.
- GearMatic will not auto-equip Warband-until-equipped gear from your bags either, since equipping it binds it to this character. Gear that is already bound still gets equipped automatically.
[v2.20.3-release] - 06/05/2026
Fixed
- Two-slot gear (trinkets, rings, weapons) showed a false upgrade for an item you already wear. The two-slot baseline compared a candidate against the WEAKER of your two equipped slots, so a lower-item-level copy of a trinket/ring you already have equipped (or a different item in the same unique limit-category) was flagged as beating your other slot, even though the game won't let you equip a second one.
Comparenow detects when the candidate's item ID is already equipped in the slot group (or itsC_Item.GetItemUniquenesslimit-category is at cap) and baselines against the equipped copy it would actually replace. Single-slot gear and genuine free-slot upgrades are unaffected. Covered bytools/conflict-baseline-selftest.lua.
In-Game
- Fixed trinkets, rings, and weapons showing a false upgrade arrow when you already have a better copy of the same item equipped (you can't wear two). GearMatic now compares against the copy you are already wearing instead of your other slot.
[v2.20.2-release] - 06/05/2026
Fixed
- Item tooltip upgrade/downgrade percentages were wrong for gear with bonus/upgrade IDs. On retail, the tooltip hook scored a base item link (item ID only, missing the bonus/upgrade/crafting IDs) handed to it by
TooltipDataProcessor, so crafted and Bind-on-Equip gear read base-template stats and showed wildly wrong verdicts (a real upgrade could display as a ~90% downgrade).appendUpgradeLinesImplnow prefers the renderedtooltip:GetItem()link, which carries the full bonus/upgrade/crafting IDs. The bag overlay, auto-equip, quest-reward, and loot scorers already used full links (GetContainerItemLink/GetLootSlotLink/GetItem) and were unaffected.
In-Game
- Fixed gear upgrade and downgrade percentages in item tooltips that could show wildly wrong values (often a big downgrade) for crafted and Bind-on-Equip gear. Tooltips now read the item's real stats.
[v2.20.1-release] - 06/05/2026
Fixed
- AutoEquip never binds a Bind-on-Equip item. The bag-upgrade sweep previously swapped any wearable upgrade into its slot via
EquipCursorItemwithout checking bind type, so a Bind-on-Equip item that scored as an upgrade got bound to the character permanently. A newCompat.WouldBindOnEquipcheck (itembindType == 2plusC_Item.IsBoundon the bag slot) now gates the armor sweep, the weapon candidate gathering, and the weapon equip step. Items that are already soulbound, Bind-on-Pickup, or no-bind are still equipped normally. Covered bytools/autoequip-boe-selftest.lua.
In-Game
- GearMatic no longer auto-equips Bind-on-Equip gear from your bags, so it can't bind something you were keeping to sell or trade. Gear that is already Soulbound still gets equipped automatically, just like before.
[v2.20.0-release] - 06/04/2026
Added
- Roll-up number animation on upgrade/downgrade alerts (default on). When an alert shows a gear-score change, the number rolls up to its value instead of appearing instantly. A toggle restores the instant number.
- Settings Profiles tab. Generic settings tabs were rebuilt on LibMatic-Settings and a Profiles tab added; settings are now backed by an AceDB profile with a one-time migration that preserves existing settings, tracked characters, and scales.
- Full-name command help, with the help text localized into every shipped locale.
Changed
- Moved to LibMatic shared modules. Options-panel registration routes through LibMatic's RegisterPanel/OpenPanel, the in-game changelog popup renders via LibMatic-ChangeLog with shared styling, the login banner uses the shared startup banner, and alert sounds come from LibMatic-SoundPack. LibMatic is consumed as an in-repo symlink and bundled as a packager external.
- Removed the alert test-position button from the options.
Fixed
- No error on login.
ns.dbis now guarded before readingprofile.showLoginNag, so a login-timing path no longer errors. - Changelog popup toggle is bound to the
showChangeLogPopupkey, so the General-settings toggle controls the popup correctly.
In-Game
- Gear upgrade and downgrade alert numbers now roll up when they appear. Prefer the instant number? Turn off the roll-up animation in the options.
- New Profiles tab in the settings. Save your GearMatic settings as profiles and switch between them; your existing settings carry over automatically.
- Fixed an error that could appear at login.
[v2.19.0-release] - 06/02/2026
Changed
- Pawn auto-import now defaults OFF (
pawnAutoImport = falseinDEFAULT_SETTINGS). New profiles use GearMatic's bundled scales unless the user enables Pawn import in the options. Existing profiles keep their saved value (ApplyDefaultsonly fills unset keys). GearMatic_Mists.tocinterface bumped to 50504 for Mists of Pandaria Classic 5.5.4.
Added
- Discord icon in the General Support group (
discord.tga), wired through the shared LibMatic-SettingsdiscordIconhook. - "More Infinite Loop Alchemist Addons" group in General options, linking CritMatic and RepMatic with their icons and copy-CurseForge-link boxes (new
critmatic-icon.tga/repmatic-icon.tgainTextures/). New locale keysettings_group_more_addons.
[v2.18.0-release] - 05/31/2026
In-Game
- Items you can equip now show the correct upgrade again. A higher item-level piece sitting in your bags was making genuine upgrades look like big downgrades.
- When GearMatic posts your gear upgrades to guild chat, it now spaces them out to about one per minute, so a batch of auto-equips no longer spams the guild.
Fixed
- Best-owned baseline no longer raw-scans loose bag items.
Scoring/V2/BestItems.luarebuildhad afor bag = 0, NumBagSlots()loop that pushed every bag item into the pool, so a high-ilvl item stashed in bags became the pool best and genuine upgrades scored as large downgrades (real case: ilvl171 feet showed -81% vs an unequipped bag boot, identical across all three specs). Restored to equipped + equipment-sets only, matching v2.16.0. Commit e952d17.
Added
- Guild broadcast cooldown: gear-upgrade chat broadcasts to the GUILD channel are throttled to one per 60s in
Social.lua(GetTimegate, matching CritMatic). Party/raid/instance channels stay unthrottled, so AutoEquip sweeps no longer flood guild chat. Commit df36ee2.
[v2.17.2-release] - 05/31/2026
In-Game
- The gear-upgrade chat broadcast now leads with a skull icon instead of a star, and the icon shows correctly in every game language.
Changed
- Social broadcast marker changed from
{rt1}(star) to{rt8}(skull) inSocial.lua, and the matchingsettings_social_deschelp text updated across all 12 locales. The numeric{rtN}raid-target token is locale-independent, so the skull renders on every client (the{skull}keyword would only work on enUS).
[v2.17.1-release] - 05/31/2026
In-Game
- The interface is now fully translated in every supported language (German, French, Spanish, Italian, Portuguese, Russian, Korean, and Chinese).
Changed
- Localization: filled the 38 keys that every non-English locale (and
enGB) was missing, so they no longer fall back to English. Covers loadout slot-action hints, the Pawn and vendor settings, the changelog-popup toggle,current_spec_marker,tooltip_best/tooltip_second_best, and the load splash. Translated fordeDE, esES, esMX, frFR, itIT, koKR, ptBR, ruRU, zhCN, zhTW(plusenGB), matching each file's existing diacritic/style convention; all%d/%sformat specifiers and|cff...|rcolor codes preserved. Each locale now covers the full 239-keyenUSset (0 missing, 0 duplicates, all passluac -p).
[v2.17.0-release] - 05/31/2026
In-Game
- Item tooltips now show your upgrade chance for every spec you have, with your active spec listed first and marked (current).
- One-handed weapons in your bags no longer show a false upgrade arrow when your class can't dual-wield them.
- The gear-slot swap window now correctly lists the items you can put in that slot.
- Upgrade markers for your other characters now show up correctly again.
- The character browser no longer blocks your keyboard while it is open.
Added
- Per-spec upgrade rows in item tooltips lead with the active spec, promoted to the top of the list and tagged with a
(current)marker via the newSI.GetActiveSpecIndex()(resolved fromC_SpecializationInfo.GetSpecialization).
Fixed
Compare.EvaluateForCharran the current character's can-wear / off-spec gate (ShouldEvaluateForCurrentChar) for ALL characters, so alt upgrade rows (tooltip alt lines,BestAltUpgradefeeding the bag/loot/quest overlays) were suppressed for any item the logged-in character couldn't use. The gate now only applies when scoring the current character; alts are class-filtered by their own callers.- One-hand weapon baseline (
BestItems.CompareBaseline) and best/2nd-best assignment (assignOneHandedBestItems) treated non-dual-wield classes as dual-wielders, so a 1H weapon was compared against the off-hand frill and inferior weapons read as upgrades (false bag chevron) or as a spurious "2nd best" badge. Both paths are now gated onCanDualWield(). GetItemInfoInstantequipLocwas destructured at return position 9 (theGetItemInfolayout) instead of position 4 inLoadouts/SlotFlyout.luaandLoadouts/Equip.lua, so the slot-swap candidate grid was always empty and the 2H unequip-first step never fired.- Pawn scale import derived
specIDfrom trailing digits of the scale name instead of the scale's realSpecIDfield, and theResiliencestat alias mapped to a misspelled key (resilienceitrating), dropping resilience weight from every score. Both corrected (alias and export map now useresilience; import readspawnScale.SpecIDfirst). - The full character scan never cleared a slot that is now genuinely empty, so an unequipped item lingered in saved data and inflated the tracked average item level. Empty slots are now cleared.
- Durability helpers (
CountLowDurability,MinDurabilityPct) could divide a nildurabilityfrom legacy saved rows; the loop now guards onslot.durability. - Auto-equip's combat guard checked only
UnitAffectingCombat; it now also returns true onInCombatLockdown()so it won't attempt a protected weapon swap during the combat-lockdown tail. - The character browser frame enabled keyboard capture without
SetPropagateKeyboardInput, trapping every keystroke (movement, action bars, chat) while the window was open. It now consumes only LEFT/RIGHT/ESCAPE and passes everything else through.
Changed
- Removed an unreachable duplicate
exportslash subcommand.
[v2.16.0-release] - 05/30/2026
In-Game
- AutoEquip no longer loops swapping your weapons during combat, and now picks the best weapon setup for your spec, a two-hander or dual-wielding two one-handers, whichever scores higher.
Fixed
- AutoEquip thrash loop. Equipping a weapon fires
BAG_UPDATE_DELAYED, which re-ran the sweep; the just-removed weapon (now in bags) re-qualified because a 2H-blocked off-hand slot (score 0) was treated as a free "empty" slot, so any 1H was force-equipped into it, kicking out the 2H, then the 2H beat the lone 1H and re-equipped, looping every 0.5s and broadcasting each swap to guild chat. Added self-retrigger suppression (ignores theBAG_UPDATE_DELAYEDan auto-equip itself causes for 1.5s), an anti-oscillation guard (won't re-equip an item it just displaced for 10s), and 2H-occupancy awareness (a blocked off-hand is no longer treated as a free slot).
Changed
- AutoEquip now solves for the optimal weapon configuration instead of greedily filling the weakest slot. Each sweep scores every weapon (equipped + bags) with the active stat weights and picks the highest-scoring valid config: best two-hander alone, best two one-handers (dual-wield, gated on
CanDualWield()), best one-hander + off-hand/shield, or main-hand alone, then equips toward it only when it beats the current weapons by the min-delta threshold. The decision is a fixed point, so it converges and stops. Planner and guards are covered by a unit test.
[v2.15.6-release] - 05/30/2026
In-Game
- GearMatic's bag upgrade markers no longer break your cast bar or spam errors during combat in dungeons, raids, and arenas.
Fixed
- v2.15.5 wrapped
scanFrame/scanContainerinpcallto swallow the secret-boolean error, butpcallcatches the error without stopping taint propagation: execution stayed tainted-by-GearMatic and the taint spread to Blizzard's secureCastingBarFrame(and was misattributed to other addons, e.g. "execution tainted by 'RepMatic'"). Confirmed viataint.log:BagOverlay.lua:135boolean-tested a secretIsShown()~130,000 times in an instance, poisoning the globalON_BAR_HIGHLIGHT_MARKSand the cast bar's animation tables. Real fix:scanFramenow skips forbidden frames and frames carrying any secret aspect (IsForbidden()/HasAnySecretAspect(), bothSimpleFrameScriptObjectAPIbase methods verified via the wow-api MCP) BEFORE the boolean test, so the secret value is never tested and no taint is generated. The fullEnumerateFrameswalk still runs, so third-party bag overlays (Bagnon, AdiBags, BetterBags, ElvUI, ArkInventory, Bagshui) keep working; only secret/forbidden frames are skipped.
[v2.15.5-release] - 05/29/2026
In-Game
- GearMatic's bag upgrade markers no longer cause errors in dungeons, raids, and arenas.
Fixed
BagOverlay.refreshAllwalks the whole frame tree viaEnumerateFramesto find bag item buttons (retail bag buttons are matched by their methods, not fixed names, so this scan runs everywhere including instances). On retail 12.0 (Midnight) it reached secret-value frames such as the cooldown viewer and aura frames, whereframe:IsShown()returns a secret boolean; boolean-testing it at line 140 threwattempt to perform boolean test on a secret boolean value (execution tainted by 'GearMatic'), once per such frame per scan tick (the reported100x). Secret values only activate in instanced/combat content, which is why it only fired in dungeons, raids, and arenas. Wrapped each foreign-frame probe (scanFrame/scanContainer) inpcall, so any error from inspecting a frame GearMatic does not own (secretIsShown/IsVisible/IsObjectType, the earlier non-stringGetName, or anything future) is caught and that frame is skipped, while the sweep continues and real bag buttons are still decorated.BagOverlayonly colors its own overlay textures and calls no protected functions, so the brief secret-read taint is inert (no blocked actions). Closes the whole "poke a foreign frame on the secret-values API" class for the bag scan.
[v2.15.4-release] - 05/29/2026
In-Game
- GearMatic no longer causes errors while WoW's built-in damage meter is open.
Fixed
BagOverlay.refreshAllwalks the entire frame tree viaEnumerateFrames(once per second on a poll, plus on bag events) and ranlooksLikeBagItemButtonon the retail damage meter'sDamageMeterEntryrows. For thoseScrollBoxListViewbuttonsframe:GetName()returns a non-string (a FontString), so line 95'sn:find("ContainerFrame")threwattempt to call a nil value (method 'find'), spamming once per meter row per update (the reported113x). Guarded withtype(n) == "string"before any string method, so meter rows are correctly rejected and real bag buttons (BlizzardContainerFrame*, Bagnon, AdiBags, BetterBags, ElvUI, ArkInventory, Bagshui) are still detected. Hardened the sameGetName()-assumed-string pattern inBagOverlay.decorateContainerFrameand inItemTooltipHook(addLineBold,alreadyAdded), which concatenate the name into a_G[...]lookup, so no sibling variant can surface. Behavior is unchanged for valid names; only non-string returns now bail instead of crashing.
[v2.15.3-release] - 05/29/2026
In-Game
- GearMatic no longer interferes with unit tooltips in dungeons, raids, and arenas.
Fixed
UnitTooltipHook.appendUnitInfothrewbad argument #1 to 'UnitIsPlayer' ... Secret values are only allowed during untainted executionon retail 12.0 (Midnight).tooltip:GetUnit()returns a secret unit token whenever the hovered unit's identity is sealed (combat against non-player/pet units, and dungeon/raid/arena instances), and passing that token toUnitIsPlayer(thenUnitName) crashed during tainted addon execution via theTooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Unit)path. Added anisSecretValuehelper (nil-safe wrapper around the Mainlineissecretvalueglobal) and now bail before any Unit API call when the unit token, or the resolved name/realm, is secret. Classic flavors are unaffected (issecretvalueis nil there, so the guard returns false and the legacyOnTooltipSetUnitpath is unchanged). The mouseover summary only ever matched the player's own stored characters, so suppressing sealed units removes no working functionality, it only replaces the error with graceful silence in the contexts where the line could never resolve anyway.
[v2.15.2-release] - 05/28/2026
In-Game
- Item tooltips were listing each of your class specs twice. Every spec now appears once.
- Your equipped weapons now rank the way rings and trinkets do. With two one-hand weapons, one shows best and the other second best instead of both showing best. A two-handed weapon shows best.
Fixed
ScaleImport.GetScalesForClassdeduped class scales byspecIDwhen present and bynameotherwise. A Pawn-imported scale (specID= spec index, namePawn:...) and the bundled default for the same spec (specID= nil, name = spec) therefore never collided, so both rendered and every spec showed twice. The v2.15.0 retail default pool made this fire for any class that had both a Pawn import and a bundled default. Dedup now keys on the normalized spec name (falling back tospecID, thenname) so the two sources collapse to one row, with the user/Pawn scale winning. Bundled scales also get a resolvedspecIDviaGetSpecializationInfoForClassIDso the rows sort in stable spec order.BestItems.GetRankforINVTYPE_WEAPONcheckedsecondStrippedfields thatassignOneHandedBestItemsnever populates (it splits the two one-hand weapons into separate main-hand / off-hand rows that each carry onlybest), so a weapon could only ever returnbestor nil, neversecond, unlike trinkets and rings. GetRank now maps the main-hand row tobestand the off-hand row tosecond, trusting the placementassignOneHandedBestItemsalready computed. On a tie the off-hand item wins the top slot (slot 16 is scanned before slot 17, so the later equal-scoring weapon wins the>=swap), so two equal-scoring weapons no longer both show best.
[v2.15.1-release] - 05/28/2026
In-Game
- The upgrade arrow on quest reward items now reflects your current spec only. An item that is only an upgrade for one of your off-specs no longer shows the arrow when it is not an upgrade for the spec you are actually playing.
Fixed
QuestRewardHook.evaluateOnedropped its off-spec fallback for the current character. The reward-button chevron now fires only when the active (current-spec) scale delta is>= 0.5%; previously it looped over every class spec and lit the chevron if ANY spec cleared the threshold, so a Discipline priest saw the arrow on an item that was only a Holy/Shadow upgrade. The now-unusedscalesForCurrentClasshelper was removed.BagOverlayandLootHookwere already current-spec-only (EvaluateForChar), verified unchanged.
[v2.15.0-release] - 05/28/2026
In-Game
- Retail gear scoring now uses real per-spec stat weights for all 39 modern specs. Every item now shows an accurate, distinct upgrade value for each spec instead of the same number for every item.
- Items that rank as your best or 2nd best for a slot now show the best / 2nd best badge in tooltips even when they sit in your bags or are offered as a quest reward, not only when already equipped. Bag or quest copies of the item you are already wearing still stay unmarked.
Changed
tools/gm_emit_retail.pyrewritten to parsereferences/pawn/AskMrRobot.lua(real differentiated per-spec weights) instead ofScaleTemplates.lua(the uniformprimary=1 / every secondary=0.5starter templates). Maps the 15 AMR stat names to GearMatic extractor keys (HasteRating->hasterating,CritRating->critrating,Versatility->versatility,MaxDamage->maxdamage,MovementSpeed->speed,Indestructible->indestructible, etc). Spec display names are read from the source's inline comments so newly added specs (e.g. the third Demon Hunter spec) need no map update.Scales/defaults.lua["retail"]block regenerated: 40 specs across all 13 classes, each with its own differentiated weights. Replaces the prior placeholder stub block where every spec and every secondary stat shared identical weights, which made all items score the same.
Fixed
ItemTooltipHook.lua: the per-spec tooltip rows no longer drop a spec when a non-equipped item ranks best or 2nd best in that scale's pool.BestItems.GetRankis now consulted for non-equipped items too; a badge renders unless the item shares its itemID with the item already equipped in that slot (preserving the v2.13.1 duplicate-suppression). Previously such items showed neither a badge (badges were equipped-only) nor a chevron (suppressed by the best/2nd guard), so the row vanished.
[v2.14.1-release] - 05/27/2026
In-Game
- Item tooltips show one row per spec for your class even when you have only imported a scale for one of them. A priest with only a Discipline scale now also sees Holy and Shadow rows, populated from the bundled defaults.
- Equipped items show the best / 2nd best badge again in tooltips, including the comparison tooltip that pops up when you hover a quest reward or a bag item. The previous fix that stopped duplicate badges on bag copies was over-tightened and accidentally suppressed the badge on the real equipped slot.
Fixed
ScaleImport.GetScalesForClassnow backfillsns.DefaultScales[flavor]entries for the character's class on top of the user-imported saved scales. Dedupes byspecID(and bynameas a fallback) so the same spec never renders twice. Restores the v2.13.0 multi-spec tooltip promise when the user only imported a subset of class specs.ItemTooltipHook.isCurrentlyEquippedLinknow uses a fingerprint fallback (itemID:enchant:gem1:gem2:gem3:gem4:suffix) after the strict link match, with%d*(zero-or-more digits) on every field so Mists Classic 5.5.x links that serialize empty fields as::(instead of:0:like older clients) still match. Equipped detection works again in compare tooltips, standalone equipped tooltips, and quest-reward shopping tooltips, while bag duplicates with different enchant/gem fragments still fail the fingerprint (so v2.13.1's duplicate-badge protection is preserved).
[v2.14.0-release] - 05/27/2026
In-Game
- Equip and upgrade alerts now color the item name by its actual rarity (green for uncommon, blue for rare, purple for epic, orange for legendary) instead of always purple.
Changed
Alert.ShowGearEquippedandAlert.ShowGearUpgradenow derive the alert text color from the item's quality viaC_Item.GetItemQualityColor, falling back to the user-configuredfontColorwhen quality is unknown (uncachedGetItemInfo).Alert.ShowGearDowngradecontinues to usefontColorLoss(red) so the loss indicator stays distinct from rarity.itemIconAndNamenow also returns the quality alongside icon and name.
[v2.13.1-release] - 05/27/2026
In-Game
- Quest reward and bag duplicates of items you already have equipped no longer get a misleading
bestbadge. Only the actual item in the equipped slot gets the badge.
Fixed
isCurrentlyEquippedLinkreverted to strict full-link match. The itemID-fallback added in 2.12.0 returned true for any item whose itemID matched something in an equipped slot, including quest-reward copies and bag duplicates. Strict link-match avoids the false positive; the rare link-format-differs case now falls through to the chevron path, where a 0% delta self-comparison suppresses the line cleanly.- Badge gate in
appendUpgradeLinesImplrequiresequipped == true.BestItems.GetRank's stripped-link match also fired for duplicates (since strip ignores enchant, two copies of the same item with no enchants have identical stripped links). Just tighteningisCurrentlyEquippedLinkwasn't enough - GetRank had to be gated behind the equipped check too. Equipped items still get the correct best/2nd-best rank from GetRank, defaulting to "best" if GetRank returns nil (link-format edge cases).
[v2.13.0-release] - 05/27/2026
In-Game
- Item tooltips now show one line per spec for your class. Hover any item and you'll see a separate
best/2nd best/+X% upgrade/-X% downgradeline for each spec you have a scale for (Elemental, Enhancement, Restoration, etc), each with its own spec icon. - Switching specs in-game now auto-updates which scale is treated as current. Swap from Restoration to Elemental and the chevron/badge follows; no need to run a slash command after every spec change.
- Auto-equip still respects only the current spec, never your off-spec lines.
Added
SI.GetScalesForClass(charKey)inScaleImport.lua. Returns every scale inGearMaticDB.scales[charKey]whoseclassfield matches the character's class, sorted byspecIDascending. Filters out the_activesentinel key.iconForSpec(class, specIndex)helper inItemTooltipHook.luaresolves any spec's tooltip icon throughGetSpecializationInfoForClassID(classID, specIndex)via a localCLASS_NAME_TO_IDmap (WARRIOR=1 .. EVOKER=13). Falls back to the class-circles icon when the API doesn't return a per-spec result.- Per-spec tooltip rows.
appendUpgradeLinesImplnow loops overSI.GetScalesForClass(currentKey)instead of evaluating only the active scale. Each scale gets its own row:kind = "badge"(best / 2nd best) whenBestItems.GetRankreturns non-nil OR the item is currently equipped, otherwisekind = "chevron"fromEvaluateAgainstScalewith the threshold|delta| >= 0.5%. Rows pushed to the existingrowstable and rendered with the same render loop that previously handled chevron-only rows.
Fixed
SI.GetActiveScaleordering inverted. Previous order:bag._active→ spec match → any class match. New order: spec match →bag._active→ any class match. The old order meant swapping specs left_activepointing at the previous spec's scale, so the chevron/badge stayed on the wrong spec. The new order detects the current spec viagetCurrentSpecIndex()and returns the matching scale first;_activeis now a fallback for cases where no per-spec scale exists.- Off-spec rows on the same character no longer show
Charname (Spec):parens.formatLineandformatBadgenow select the row icon fromeval.scale.specID/scale.specIDwhen available, so the spec icon comes from the scale, not from "is this the current spec?" TheisCurrentflag is now strictly "same character" - current-spec AND off-spec on the player's own char both setisCurrent = trueand use the no-name format; only different-character rows (multi-char tooltip) get the alt format. - Green border on upgrades still works under multi-spec render. The old code referenced a single
currentEvalvariable that no longer exists; replaced with a freshEvaluateForCharlookup right before the border check (current spec only, by design).
[v2.12.0-release] - 05/27/2026
In-Game
- Currently-equipped items now show a
bestor2nd bestbadge on the tooltip instead of the+X% upgrade/-X% downgradepercentage. Trinkets included. Bag items still show the percentage chevron as before. PvP and PvE gear treated the same way once equipped.
Added
BestItems.GetRank(scale, equipLoc, itemLink)inScoring/V2/BestItems.lua. Returns"best"/"second"/nilby stripping the candidate's enchant and comparing againstrow.bestStripped/row.secondStrippedin the pool. Special-casesINVTYPE_WEAPONto check bothINVTYPE_WEAPONMAINHANDandINVTYPE_WEAPONOFFHANDrows (one-handed weapons can sit in either slot). General path covers single-slot and the rest ofTWO_SLOT_LOCS.- Trinkets are now tracked in the BestItems pool. Removed
INVTYPE_TRINKETfromSKIP_EQUIPLOCSand added toTWO_SLOT_LOCS(two trinket slots, slot 13 + 14). Equipped trinkets now get thebest/2nd bestbadge. formatBadge(scale, rank, isCurrent)inItemTooltipHook.lua. Renders the badge line with the active spec name (class-colored) plus the rank text from newL["tooltip_best"] = "%s: |cff8ec3e6best|r"/L["tooltip_second_best"] = "%s: |cff8ec3e62nd best|r"(light-blue badge color, distinct from the chevron's green/red).
Fixed
appendUpgradeLinesImplalways shows a badge on equipped items. Rank comes fromBestItems.GetRankwhen the pool has the item indexed; if the item is currently equipped butGetRankreturnednil(link-format mismatch, brand-new item the pool hasn't seen yet, etc), rank defaults to"best"so the slot is never blank. OldisCurrentlyEquippedLinkearly-return now only fires AFTER the badge gate, which means it never actually triggers - equipped items always have a rank one way or another.isCurrentlyEquippedLinknow matches by itemID as a fallback. Full-link==comparison can fail whentooltip:GetItem()'s link format differs slightly fromGetInventoryItemLink("player", slot)'s format (enchant slot ordering, bonus IDs, upgrade tags). Fallback parsesitem:(%-?%d+)from both links and compares the integer itemID; matches if either path agrees.assignOneHandedBestItemspreservesbestStrippedwhen rewritingpool["INVTYPE_WEAPON"]intopool["INVTYPE_WEAPONMAINHAND"]andpool["INVTYPE_WEAPONOFFHAND"]. Previously onlybestandbestLinkwere carried over, soGetRank'srow.bestStripped == strippedcheck always failed for one-handed weapons and the equipped weapon never matched as "best".secondStrippedcarried over too where applicable.
[v2.11.0-release] - 05/26/2026
In-Game
- Weapons now correctly factor their damage range into upgrade scoring. Previously only damage-per-second contributed; daggers, swords, and other weapons looked far worse than they actually were. DPS specs see the biggest swing, a weapon's mainline +Min/+Max damage now feeds the scale weights the same way Intellect, Agility, etc do.
- New
/gm auditslash command: hover any item and run it to see exactly how each stat in your active scale contributes to the score, which stats are weighted but not extracted from the item, and which stats are extracted but ignored by your scale. - Healer items from Vanilla / TBC / Wrath now parse the +Healing and +Spell Damage tooltip lines instead of dropping them.
Added
/gm audit [link|itemID]slash subcommand. NewDebug.AuditIteminDebug/Score.lua. Resolves item via hover cache, GameTooltip, ItemRefTooltip, ShoppingTooltip, or inline arg. Walks the active scale'sweightstable alphabetically; for each weight, printskey w=<weight> v=<extracted> contrib=<weight*value>or yellow-flags as GAP when weighted-but-zero. Suppresses contribution display for-1000000ignore-sentinel weights. After the weighted-stats section, lists extracted-but-not-in-scale orphans. Final two lines print the audit total alongsideScore.ScoreItemresult so any divergence (socket potential, AP redirect, Wrathion bonus) is visible. Appends raw tooltip lines at the end for diagnosing remaining extraction gaps.- Weapon damage range tooltip extraction. New
Norm.ExtractDamageRange(text)inScoring/V2/StatNormalize.luaparses"N - N Damage"lines via three patterns with progressively looser anchors (^%s*...%s*$,^%s*..., no anchors). Returns(minDmg, maxDmg)as two numeric returns. Wired intoExtract.ReadViaTooltipto pushstats.mindamageandstats.maxdamage. Pawn-style scales weightmindamage = maxdamageheavily on weapons; previously these were always 0 in the extracted stats table, undervaluing every weapon vs scoring. - Vanilla/TBC healing + spell-damage tooltip extraction.
Norm.ExtractHealing(text)matches+N HealingplusEquip: Increases healing done by spells and effects by up to NandEquip: Increases healing done by magical spells and effects by up to N.Norm.ExtractSpellDamage(text)matches the equivalent damage-side patterns. Both wired intoReadViaTooltip.ITEM_MOD_SPELL_HEALING_DONE_SHORTAPI mapping flipped tohealingpower(matches PawnIntegration'sHp/HealPoweralias canonical key) so API and tooltip paths converge on the same key.
Fixed
Extract.Readnow uses API path as source of truth. Previously on retail the merge logic preferredReadViaTooltipwhenever it returned a non-empty table, which silently dropped every API-only stat (Versatility, Avoidance, Leech, Speed, Indestructible were all missed pre-2.10.0 because of this). NowExtract.Readalways starts with the full API result, then supplements only forTOOLTIP_ONLY_KEYS = {weaponspeed, mindamage, maxdamage, redsocket, yellowsocket, bluesocket, metasocket, prismaticsocket, cogwheelsocket, shatouchedsocket, indestructible}. Any other tooltip-extracted key only fills in when the API didn't provide it (Classic flavors where API may be sparser). Adding a new class scale now Just Works because the API path knows every stat on every item for every class on every flavor; no per-stat pattern audit needed.- Multi-return-value collapse bug in
Extract.ReadViaTooltip. The previous wiringlocal minDmg, maxDmg = S2.Normalize.ExtractDamageRange and S2.Normalize.ExtractDamageRange(line)collapsed Lua's two-return value to one because theandoperator only forwards a single value.ExtractDamageRangecorrectly returned(4, 8)for "4 - 8 Damage" butmaxDmgwas alwaysnil, theif minDmg and maxDmgguard always failed, and weapon damage was never pushed to the stats table. Replaced with explicitif X then local a, b = X(line)blocks. StatNormalizetooltip patterns for modern tertiaries (Versatility, Avoidance, Leech, Indestructible, movement Speed) shipped in 2.10.0 stay in place but are now mostly defensive - the API path covers these on retail, and the tooltip patterns serve as fallback for any flavor where the API path doesn't (Classic Era resists, etc).
[v2.10.0-release] - 05/26/2026
In-Game
- Auto-sell junk (grey-quality items) at vendors. Defaults on. Toggle in
/gm settings-> General -> Vendor automation. - Auto-repair at vendors. Uses guild bank funds first if your rank allows and the withdrawal limit covers the cost; otherwise spends personal gold. Defaults on. Toggle in the same panel.
- Mark any non-grey item as junk so it sells alongside grey-quality items. Two ways: SHIFT+RIGHT-CLICK the item in your bag, or
/gm junk add <link>//gm junk remove <link>//gm junk list//gm junk clear. - Items with Versatility, Avoidance, Leech, Indestructible, or movement Speed now score correctly. Previously these stats were being dropped from item evaluation, making some items look like bigger downgrades than they actually were (e.g. a dagger with +4 Versatility was being scored as if it had none).
- Fixed an error message that appeared on retail every time you mouseovered another player.
Added
- Vendor automation module (
VendorAutomation.lua). New CreateFrame "GearMaticVendorAutomationFrame" registersMERCHANT_SHOWandMERCHANT_CLOSED. On show, firesVA.AutoRepair()thenVA.SellJunk(). On close, cancels any in-flight sell queue. - Throttled auto-sell.
VA.SellJunkwalks bags 0-4 once, queues every slot withquality == 0ORVA.IsJunk(itemID)true, then drains the queue viaC_Timer.NewTicker(SELL_INTERVAL=0.2)callingC_Container.UseContainerItem. The 0.2s spacing stays under WoW's per-second action throttle. Re-reads container info before each sell so items moved/equipped mid-queue are skipped. Prints "auto-sold N junk items for Xg Ys Zc" summary on completion. - Guild-bank-first auto-repair.
VA.AutoRepairchecksCanMerchantRepair, thenCanGuildBankRepair+GetGuildBankWithdrawMoney(withIsInGuildguard). CallsRepairAllItems(1)to draw from guild funds when bothallowedand the bank limit (or -1 = unlimited) coversGetRepairAllCost(); otherwiseRepairAllItems()for personal funds. Prints "auto-repaired for X (guild/personal funds)" summary, or "auto-repair skipped: need X, have Y" when personal funds short. - Per-character junk-list rules.
GearMaticDB.junkRules[charKey]is an itemID set.VA.MarkJunk(itemID),VA.UnmarkJunk(itemID),VA.IsJunk(itemID),VA.ListJunk(),VA.ClearJunk()manage entries. Sell loop checksquality == 0 OR VA.IsJunk(itemID)so flagged whites sell alongside greys. /gm junkslash subcommand./gm junk add <link|itemID>,/gm junk remove <link|itemID>(aliasrm),/gm junk list,/gm junk clear. Item link parsing extracts itemID from theitem:Nsubstring, or accepts a bare numeric ID.- SHIFT+RIGHT-CLICK on bag items toggles junk status.
hooksecurefunc("ContainerFrameItemButton_OnModifiedClick", ...)fires only when the global exists (Classic + Retail both have it). Resolves bag/slot viabutton:GetBagID()/button:GetID()with fallbacks tobutton.bag/button.slot/button:GetParent():GetID(). No conflict with default WoW behavior (no native action on that combo for bag items). - GUI toggles in General tab. New "Vendor automation" inline group at order=25 holds
autoSellJunkandautoRepairtoggles, both full-width. Both defaulttrueinDEFAULT_SETTINGS.
Fixed
- Tooltip parser missed Versatility, Avoidance, Leech, Indestructible, and movement Speed.
Scoring/V2/StatNormalize.luaLINE_PATTERNSbuilt patterns only for classic-era secondaries. On retailExtract.ReadprefersReadViaTooltipwhen non-empty, so these stats were silently dropped even thoughReadViaAPIhad them. Symptom: weapons with Versatility scored ~5 points per stack lower than they should have. Added fiveadd(withValue(ITEM_MOD_*), key)calls plus oneadd(bare(...))for Indestructible. Falls back to English literals when theITEM_MOD_*global doesn't exist on a flavor. OnTooltipSetUnitHookScript error on retail Dragonflight+.UnitTooltipHook.luanow detectsTooltipDataProcessor.AddTooltipPostCall+Enum.TooltipDataType.Unitand uses the modern API on 10.0+; pcall-falls-back toHookScript("OnTooltipSetUnit")on Classic flavors. The legacy handler was removed fromGameTooltipin 10.0 and was throwing "Doesn't have a OnTooltipSetUnit script" on every retail login.release.shwas nuking install-dir symlinks. The post-package sync did unconditionalrm -rf "$target"; cp -R "$STAGED_DIR" "$target"on every flavor dir, replacing any pre-existing symlink with a copy of the packaged build. Now skips the copy when[ -L "$target" ](target is already a symlink), preserving live-edit setups while still copying for flavors that don't have a symlink.
[v2.9.0-release] - 05/26/2026
In-Game
- Weapons that grant raw +Attack Power (older expansion gear, heirlooms) now contribute to your DPS-spec scoring correctly on retail. Previously the value was being silently dropped.
- New
/gm export scale <name>command outputs a portable stat-weight string you can share with other players or paste into other stat-weight tools. - Fixed an error that appeared when mousing over players on retail.
Added
- Public addon API for plugin scales. Three new functions on the
GearMaticglobal:AddPluginScale(providerName, scaleName, classID, specID, weights)registers a class/spec-tagged stat-weight scale at runtime;RemovePluginScale(providerName, scaleName)clears it;ListPluginScales([providerName])enumerates current-character plugin scales. Plugin scales persist inGearMaticDB.scales[charKey]under<provider>:<scale>withsource = "plugin:<provider>", coexisting with Pawn-imported and user-pasted scales. Weights accept either lowercase canonical keys or Pawn-style CapitalCase via the existingnormalisePawnKeypath. /gm export scale <name>slash command.Pawn.ExportScaleserializes a stored GearMatic scale back to standard Pawn import-string format. Reverse-maps canonical lowercase keys to Pawn CapitalCase via a static table, with a livePawnCommon.Scales[name].Valuesprobe overriding when Pawn is loaded so re-exports preserve the original key spelling.-1000000weights export as=X(Pawn'sPawnIgnoreStatValuesentinel).Class=andSpec=lines emitted from the scale's stored class/specID. Embedded double-quotes in the scale name get stripped because Pawn's parser regex can't handle them; the slash output prints a note documenting the rename.- AP→max(STR, AGI) redirect on retail.
Scoring/V2/Score.lua:113-121routes anyattackpower-keyed weight through whichever ofstrengthoragilitycarries the larger weight in the active scale.Scoring/V2/StatExtract.luaaddsAP_SKIP_KEYS_RETAIL = {attackpower, rangedattackpower, feralattackpower}and skips those keys inReadViaAPIso synthesized retail AP doesn't double-count when the redirect applies. Merge guard at lines 162-167 only fires when the API path wins so real+N Attack Powertooltip text on legacy gear is preserved.
Fixed
OnTooltipSetUnitHookScript error on retail.UnitTooltipHook.luanow detectsTooltipDataProcessor.AddTooltipPostCall+Enum.TooltipDataType.Unitand uses the modern API on Dragonflight+ (10.0+); falls back to the legacyHookScript("OnTooltipSetUnit")on Classic flavors viapcall. The legacy script handler was removed fromGameTooltipin 10.0 and was throwing "Doesn't have a OnTooltipSetUnit script" on every retail login.
[v2.8.0-release] - 05/25/2026
In-Game
- Wands now correctly show an upgrade line and score on Mists Classic. They were silently skipped on flavors where the old ranged slot doesn't exist.
- Items that are an upgrade for your current spec now show with a green tooltip border, a quick visual cue to help you spot upgrades at a glance.
- Items with empty sockets factor those sockets into the upgrade calculation. A socketable piece now correctly outranks an identical socketless one.
- On Mists Classic, items eligible for the legendary cloak quest line get a bonus socket factored into scoring.
- Repeated hovers of the same item feel snappier; an internal cache speeds up the second look.
- Bag changes, vendor sells, and spec swaps refresh stale scoring automatically.
Added
- Wrathion PrismaticSocket bonus on Mists Classic. New
Scales/wrathion_items_mists.luacarries ~179 itemIDs from Heart of Fear, Terrace of Endless Spring, Throne of Thunder, and BS-craftable epics, exposed asns.WrathionUpgradeableItemIDs.Scoring/V2/Sockets.luaaddsSockets.WrathionAdjustedStats(stats, itemLink)which returns a shallow copy withprismaticsocket = (existing or 0) + 1when the itemID is eligible.Score.ScoreItemconsults this right afterExtract.Read. - Basic socket potential scoring.
Sockets.PotentialFor(stats, scale)now returnsempty * gemAmount * bestGemmableWeightinstead of the prior stub0. Counts empty red/yellow/blue/prismatic sockets (meta is excluded; metasocketeffect carries its own weight).gemAmountper flavor: Mists=320, Cata=240, Wrath=60, TBC=12; 0 elsewhere. Best stat is the max weight acrossstrength,agility,intellect,spirit,stamina,critrating,hasterating,masteryrating,hitrating,expertiserating,dodgerating,parryrating,spellhitrating,spellpower,attackpower. - 200-entry FIFO item-parse cache. New
cacheGet/cachePut/cacheClearhelpers inScoring/V2/StatExtract.luacap atCACHE_MAX = 200, keyed on itemLink. FIFO eviction viatable.remove(order, 1).Extract.Readreturns the cached table on hit (skipping bothReadViaAPIandReadViaTooltip) and inserts the result on miss. Measured 0.90ms miss vs 0.001ms hit on a Mists epic.ns.StatExtract_ClearCache()exposed for external invalidation. - Green tooltip border on upgrades.
ItemTooltipHook.luaaddssetTooltipBorderUpgrade/resetTooltipBorderhelpers.setTooltipBorderUpgradetriestooltip.NineSlice:SetBorderColor(0, 1, 0, 1)first, falls back totooltip:SetBackdropBorderColor(0, 1, 0, 1). Triggered when the CURRENT character's eval delta is>= 0.5percent; alt rows don't trigger border. Reset viaOnHideHookScript onGameTooltip,ItemRefTooltip,ShoppingTooltip1,ShoppingTooltip2. Gated byGearMaticDB.settings.colorTooltipBorder(defaultstrue). - Three more BestItems invalidation events.
Scoring/V2/BestItems.luaregistersITEM_LOCKED,MERCHANT_UPDATE,PLAYER_SPECIALIZATION_CHANGED(Mists+), andACTIVE_TALENT_GROUP_CHANGED(Wrath/Cata). Latter two arepcall-protected viapcall(refreshFrame.RegisterEvent, refreshFrame, ...)for flavors that don't support them. /gm wrathion <itemID>diagnostic. Mists-only slash subcommand printslisted=,with=,without=,diff=for the supplied itemID, togglingns.WrathionUpgradeableItemIDstemporarily to compare scores with and without the Wrathion bonus.
Fixed
- Wand-slot bug on Mists+ flavors.
Compat.SlotsForEquipLoc("INVTYPE_RANGEDRIGHT")and("INVTYPE_RANGED")now return{ 16 }on flavors whereHasRangedSlotisfalse(Mists 5.0+, retail). Previously the function returnednil,EvaluateForChargot no slot, and wands silently dropped out of the tooltip upgrade pipeline. Wand of the San'layn and other WotLK-era wands reportINVTYPE_RANGEDRIGHTfromGetItemInfoeven on Mists Classic where the game equips them into slot 16. - Quest reward overlay threshold parity.
QuestRewardHook.luaevaluateOnethreshold lowered from>= 1to>= 0.5percent for both the current-spec eval and the multi-scale fallback, matching the tooltip-upgrade-line threshold. - Pawn scale converter rejected scales with any zero weight.
PawnIntegration.convertPawnScalenow accepts a Pawn scale as long as at least one weight is positive; previously, a scale withStamina = 0.1and other strong positives was passed through but any scale with even one zero-or-negative weight returnednil. Compare.luabaseline now uses BestItems pool for current char.baselineForCurrentCharcallsS2.BestItems.CompareBaseline(scale, equipLoc)first when the character is the player's current character, falling back to the worst-equipped-slot lookup otherwise. This matches the broader pattern of comparing against your single best-in-slot baseline.- Self-comparison early-out in evaluateImpl.
Compare.evaluateImplearly-returnsnilwhen the candidate is already the best or second-best for that slot, preventing the item-vs-itself baseline from generating misleading positive deltas.
Changed
- Wrathion bonus is now copy-on-apply. Replaced
Sockets.ApplyWrathionBonus(stats, itemLink)(in-place mutator) withSockets.WrathionAdjustedStats(stats, itemLink)(returns either the input table or a shallow copy withprismaticsocket+1). Required so the LRU-cached raw stats table fromExtract.Readisn't mutated on each scored hover; the cache stays clean. - StatExtract cache cleared alongside BestItems cache.
BestItems.Invalidatenow also callsns.StatExtract_ClearCache()so equipment / bag / vendor / spec events flush both caches together.
Diagnostics
/gm wrathion <itemID>prints whether an itemID is Wrathion-eligible plus a with/without score comparison.
[v2.7.0-release] - 05/25/2026
In-Game
- Items your class can't equip (a wand on a Warrior, a 2H mace on a Rogue, a polearm on a Mage, etc) no longer falsely score as upgrades.
- On retail, the GearMatic upgrade line now appears on bag item tooltips and the green up-arrow now appears on bag item icons. Both were missing on the new combined bag UI.
- Auto-equip is smarter: it won't try to swap your shield for a 1H weapon when your spec can't dual-wield, and it won't claim it equipped something when the game silently blocked the swap. Duplicate "equipped X" toasts on /reload are gone.
- Removed the login pop-up nag on retail. Retail scoring runs on GearMatic's own bundled stat weights.
Added
- Class weapon-proficiency gate. New
Scales/weapon_proficiency.luacarries a per-class banned-subclass table keyed by BlizzardsubClassIDintegers (0..19 fromEnum.ItemWeaponSubclass).Score.ScoreItemconsults the gate viaC_Item.GetItemInfoInstantforclassID == 2items and short-circuits to(0, false)when the class can't wield that subclass. Runtime patch adds[0]Axe1H to ROGUE's banned set on Classic / TBC. - Right-hand tooltip text extraction.
StatExtract.readTooltipLinesViaDataAPIandreadTooltipLinesViaFramenow walk bothleftTextandrightText(andTextRight<N>font strings) per line.StatNormalizeadds a^STAT_SPEED %s+(N.NN)$pattern that captures weapon attack speed intostats.weaponspeed.Score.ScoreItemapplies the SpeedBaseline subtraction when the active scale definesspeedBaseline. Dormant on every bundled scale today, ready for future SpeedBaseline scales. - Per-method
hooksecurefuncfan-out on retail.ItemTooltipHook.luanow hooks 21 namedGameTooltip:Set*methods (SetBagItem,SetInventoryItem,SetHyperlink,SetItemByID,SetBuybackItem,SetMerchantItem,SetLootItem,SetLootRollItem,SetQuestItem,SetQuestLogItem,SetSendMailItem,SetInboxItem,SetTradePlayerItem,SetTradeTargetItem,SetTradeSkillItem,SetGuildBankItem,SetHeirloomByItemID,SetRecipeResultItem,SetVoidItem,SetVoidDepositItem,SetVoidWithdrawalItem) plusItemRefTooltip:SetHyperlink,:SetItemByID, andShoppingTooltip1/2:SetHyperlink, in addition to the existingTooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, ...)path. Bag tooltips on retail 11.0+'s combined bag UI do not route throughTooltipDataProcessorfor the candidate-side tooltip, so the line was missing pre-2.7. Per-method hooks resolve the link from the call args and dispatch to the sameappendUpgradeLinesflow. Re-entrancy guarded bytooltip.__gmInUse+alreadyAdded.
Fixed
- Bag overlay missing on retail combined bag.
BagOverlay.looksLikeBagItemButtonandgetButtonItemLinknow recognize the modern ItemButton mixin via:GetBagID()and:GetSlotAndBagID(), on top of the legacy.bag/.info.hyperlinkchecks. Retail 11.0+ContainerFrameCombinedBagsSlot<N>buttons now get the green up-chevron overlay. - Tooltip line hanging outside the tooltip border on retail.
appendUpgradeLinesImplnow callstooltip:Show()on every flavor afteraddLineBold, not only on Classic. Per-methodhooksecurefunconGameTooltip:SetBagItemfires after the tooltip finished its layout pass; without an explicitShow()the backdrop did not grow to wrap the new line. - Auto-equip toast printing even when the equip silently failed.
AutoEquip.RunSweepnow comparesGetInventoryItemLink(targetSlot)before vs afterEquipCursorItemand only counts the equip + prints the toast when the slot's item id flipped to the candidate's id.EquipCursorItemclears the cursor even on a silent rejection (item-class restriction, ilvl gate), so the priorif CursorHasItem() then ... else equipped+1check produced false positives. - Auto-equip targeting the shield slot for a 1H weapon. New
slotHoldsShieldOrHoldable(17)guard infindBestSwapForLinkrestrictsINVTYPE_WEAPONcandidates to{16}when the off-hand currently holds anINVTYPE_SHIELDorINVTYPE_HOLDABLE. The lower-score-wins picker was choosing slot 17 (shield) for a 1H weapon on Resto Shaman because Resto's intellect-heavy scale rates shields lower than 1H weapons; the resultingEquipCursorItem(17)silently failed because Resto can't dual-wield. - Duplicate auto-equip toast on /reload. New
sweepPending/sweepInProgressflags in the OnEvent handler ensure only one sweep is scheduled or running at a time.BAG_UPDATE_DELAYED+PLAYER_ENTERING_WORLDboth schedule a sweep on /reload, and the new combined bag'sBAG_UPDATE_DELAYEDcan fire multiple times in quick succession; racing sweeps were each finding the same upgrade in flight and printing the toast twice. /gm scoresilent on retail.Debug/Score.luainstallHookswas callingGameTooltip:HookScript("OnTooltipSetItem", ...)at file load time; retail 10.0.2+ removed theOnTooltipSetItemscript handler, the HookScript threw, file load aborted, andns.Debug.Score.RunForHoveredItemwas never assigned. Every HookScript is nowpcall-guarded and aTooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, ...)parallel registration keeps the link-cache working on retail.
Changed
- Bag overlay chevron now sits 5px inside the item's top-right corner (was 1px outside) for visual breathing room against the new bag UI's slot icons.
- Removed the retail login nag that prompted players to install a third-party scoring addon. Retail bundled scales (39 specs across 13 classes) drive scoring directly. Removed
L["nag_retail_pawn"]from every locale and dropped theC_Timer.After(5, function() print(...) end)block inCore.lua:OnPlayerLogin.
Diagnostics
/gm scoredumpsS2.Extract.Read,Extract.ReadViaAPI, andExtract.ReadViaTooltipresults per item so the stat pipeline can be inspected end-to-end./gm scoreprints the tooltip-line gate states (autoEnabled,Compat.CanWearItem,isCurrentlyEquipped,minLevel/playerLevel/equipLoc/classID/subclassID) so a missing GearMatic line can be localised to a specific gate.
[v2.6.0-release] - 05/25/2026
In-Game
- Quest reward items now show a green chevron on every icon that's an upgrade for any of your character's specs. If the item is wearable only by another character on your account, the chevron shows yellow instead.
- Tooltip upgrade line is cleaner: a single arrow instead of doubled, and duplicate lines from refresh cycles no longer stack.
- Auto-equip is now ON by default for new characters. You can still turn it off in Settings.
- Two unused toggles were removed from the Stat Import tab in Settings.
Added
- Quest reward overlay rewrite (Pawn-aligned).
QuestRewardHook.luanow hooksQuestInfo_Displaywith atemplate.elementsfilter forQuestInfo_ShowRewards, mirrors Pawn's positional indexing (choices first 1..N, statics N+1..N+M), iterates bothGetNumQuestChoicesandGetNumQuestRewards, supports the quest-log pane viaGetNumQuestLogRewards/GetNumQuestLogChoices/SetQuestLogItem, and uses a hidden scanner tooltip'sSetQuestItem/SetQuestLogItem+:GetItem()to bypass the 9.0+GetQuestItemLinkbug. Buttons resolved viaQuestInfo_GetRewardButton(QuestInfoFrame.rewardsFrame, idx)with_Gname fallback for classic. - Multi-spec quest reward evaluation. New
Compare.EvaluateAgainstScale(scale)andS2.EvaluateAgainstScalebypass the off-spec gate so an item that's an upgrade for any of your class's scales (current spec, alt specs, bundled defaults) gets the overlay - not just the active spec.
Fixed
- Tooltip duplicate-line dedup.
appendUpgradeLinesnow skips appending if a "GearMatic" header is already present in the tooltip; preventsTooltipDataProcessorrefresh cycles from stacking duplicate upgrade lines on the same hover. - Quest reward overlay was only marking ONE "best winner". Dropped the priority/armor-tie-break filter; every wearable upgrade now gets the green chevron, matching the Pawn UX.
- Quest reward overlay missed static-only rewards. The old code's
if count <= 1 then return endkilled decoration whenever there were no choice items - many quests give all rewards as static and got nothing.
Changed
- Tooltip chevron uses a single up/down arrow (was doubled) to match Pawn's tooltip visual.
- Quest reward chevron overlay anchor shifted from
-2, -2to-7, -2so the icon sits 5px further inside the button's right edge. - Tooltip chevron texture has a
-5inline offset so the arrow sits flush against the spec text instead of leaving a gap. autoEquipUpgradesdefault flipped fromfalsetotrue. New characters opt into the auto-equip behavior by default; existing characters keep whatever value is already in SavedVariables.- Removed
GearMaticDB.settings.deferToPawn(Settings row, Core default, and theBagOverlayguard that consulted it). The bag-overlay path now always evaluates via our own scoring, no Pawn-defer wrapper. - Removed
GearMaticDB.settings.preferPawnWeights(Settings row, Core default, and theScaleImport.GetActiveScalebranch that auto-picked a Pawn scale when both addons were loaded). Active scale now always comes from the character's own bag (_activefirst, then any class-matching scale, then bundled defaults). ThebestPawnScaleForhelper is removed as it had no remaining callers.
[v2.5.0] - 05/25/2026
In-Game
- Retail (The War Within) is supported. Every modern spec across all 13 classes ships with bundled stat weights. Hover an item and the GearMatic line shows the upgrade % for your current spec.
- Items restricted to a different spec (the "For X specialization" line in the tooltip) no longer score as an upgrade for your current spec.
- The upgrade line in the tooltip is now compact and easier to scan: bold text, your spec name in your class color, the colon in your class color, and an up/down arrow showing direction.
- Sidegrades (0% lines) are no longer shown. The tooltip only adds a line when the item is meaningfully better or worse.
- Paste a stat-weight string from Raidbots or Wowhead with
/gm import ( ... ). Works on every flavor. - Revert to the bundled defaults with
/gm reset, or just drop a pasted scale with/gm clear pasted. - New
/gmcslash command opens a copyable window with the last 200 chat lines, for getting chat output out of WoW.
Added
- Retail flavor TOC.
GearMatic_Mainline.toc(Interface 120005) wired into the BigWigs packager so retail builds populate alongside Classic flavors. - Bundled Pawn-parity weights for all 39 modern retail specs, including Evoker (Devastation / Preservation / Augmentation) and Demon Hunter (Havoc / Vengeance). Generated from Pawn's
ScaleTemplates.luaviatools/gm_emit_retail.pywith verified zero weight drift across all 39 specs. - Tertiary stat extraction:
leech,speed,avoidanceare now read from item tooltips and scored if the active scale weights them. - Universal Pawn-format import (
( Pawn: v1: Name=...: stat=value, ... )) handled on every flavor. Pasted scales tagged withsource = "pasted"so the companion-program skull rule still distinguishes them from gearmatic-sim scales. - Reset / clear slash commands:
/gm clear pasteddrops the current character's pasted scale and reverts to the bundled default./gm resetclears every imported / sim / pasted scale on the current character. /gm copychat//gmcopens a scrollable EditBox with the last 200 chat lines, color codes stripped, highlight-all preselected.
Fixed
- Retail tooltip line wasn't rendering at all because
GameTooltip:GetItem()returns nil on 10.0.2+. Switched the retail hook path toTooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, ...)with re-entrancy guarding to stop the recursion loop that froze the client. - Retail stat extraction now uses
C_TooltipInfo.GetHyperlinkas the primary source (matches what Pawn reads) with the legacy frame scanner as a Classic fallback. The previous mix ofGetItemStats+ frame scanner produced inflated numbers because it counted hidden API-only stats that Pawn never sees. - Off-spec items: gate consults
C_Item.GetItemSpecInfofirst and falls back to a tooltip-text scan ("For X specialization") for low-level quest rewards that ship without spec metadata. - Baseline math: the worst-equipped slot scan now skips empty slots and clamps near-zero baselines via an epsilon, so a single low-armor off-hand can't blow the upgrade % up into the hundreds.
- 1H weapon comparison: when the off-hand currently holds a shield or holdable, the baseline scan excludes slot 17 so a 1H weapon is compared against the main-hand baseline alone (matches Pawn's
UnusableStats = { "IsOffHand" }shape). - Pawn-import alias keys: import paths map
resiliencerating->resilience,armorpenrating->armorpen, and route ranged / feral attack power into their dedicated extractor keys instead of collapsing into the genericattackpowerbucket.
Changed
- Tooltip line format: spec icon + class-colored spec name + class-colored colon + double up/down arrow + bold pct text. Drops the prior wordy "for current" phrasing in favor of the compact
<icon> <Spec>: >>+X% upgradeshape. references/pawn/checked into the repo as the canonical reference for parity work (Pawn 2.13.11 source).
[v2.4.7-release] - 05/24/2026
In-Game
- The upgrade % shown in the tooltip is now more accurate on Anniversary, Era, SoD, Classic and TBC characters.
- Druid Feral DPS and Feral Tank now have their own bundled stat weights on Anniversary, Era, SoD, Classic and TBC (previously only Balance and Restoration shipped).
Fixed
- Full Pawn parity for the bundled TBC and Vanilla (Anniversary / Era / SoD) scales. The prior blocks used import-alias stat keys (
resiliencerating,armorpenrating) that never matched the keys GearMatic's stat extractor actually produces (resilience,armorpen), so those weights silently scored zero. Ranged AP and Feral AP were stored underattackpowerinstead of the extractor'srangedattackpower/feralattackpower. Vanilla armor-penetration weights were stored as the raw Pawn coefficient instead of the rating-per-percent expanded value (e.g. Armsarmorpenwas1.1instead of3.75 * 1.1 = 4.125). Regenerated both blocks verbatim from Pawn'sClassicHawsJontemplates with the correct extractor keys, added the tie-breaker stats Pawn ships (per-school resists,hp5,mana,defenserating,dodgerating,parryrating,metasocketeffect,allresist), and added the missing Druid Feral DPS + Feral Tank specs. Verified 0 weight drift against Pawn across all 28 TBC + 28 Vanilla + 34 Mists specs.
[v2.4.6-release] - 05/19/2026
Changed
- Excluded
*.pngsource image files from the packaged.zipvia.pkgmetaignore. WoW only loads.tgaat runtime; the PNGs (Logo.png 2.7 MB, Textures/GearMatic-Medallion.png 2.2 MB) were source-only and added ~5 MB of dead weight to every download.
[v2.4.5-release] - 05/19/2026
In-Game
- Your spec now shows up correctly on Mists Classic (Disc Priest, Resto Druid, Prot Warrior, etc). The loadout window header, the /gm browser, and stat-weight matching all read the right spec again.
- Discord link in General Settings now points at the shared GearMatic / CritMatic / RepMatic Discord server.
Fixed
- Spec detection on Mists Classic 5.5.x (
_classic_flavor). Blizzard moved every spec / talent global into the newC_SpecializationInfonamespace; the legacyGetSpecialization/GetSpecializationInfoglobals return nil unless the player runs/console loadDeprecationFallbacks 1.Scanner.detectSpecNamenow probesC_SpecializationInfo.GetSpecializationfirst and falls through to the unqualified globals for Cata / Wrath / Vanilla. Without this, the GearMatic Loadout window and SavedVariables for Mists Classic characters lost their spec label even when the character clearly had an active spec in-game. v2.3.1 added the pcall wrap; v2.4.5 adds the actual namespace path that returns the spec name.
Added
- Talent + glyph capture in SavedVariables.
Scanner.detectTalentsnow reads the player's active spec group + the selected tier/column picks (viaC_SpecializationInfo.GetTalentInfoon Mists Classic,GetTalentInfoon Cata/Wrath, falling back to the 3-tabGetTalentTabInfomodel on TBC/Vanilla).Scanner.detectGlyphsreads enabled glyph sockets viaGetGlyphSocketInfo. Both persist intoGearMaticDB.chars[charKey].talents/.glyphson every scan and onScanner.RefreshSpec, ready for downstream features.
[v2.4.1-release] - 05/18/2026
In-Game
- Fixed a game freeze when trying to log out or exit. Quitting WoW with GearMatic enabled used to throw an "action blocked" error and lock the exit dialog. The exit flow is clean now.
Fixed
- Critical:
ADDON_ACTION_FORBIDDENblocking game exit. Two files containedStaticPopupDialogs = StaticPopupDialogs or {}(Loadouts/Sidebar.lua and Loadouts/SpecHook.lua). Even thoughorshort-circuits to the existing Blizzard table, the assignment writes the global, which marks_G.StaticPopupDialogsas having been written by GearMatic. WoW's taint system then propagated that flag through every subsequent secure read of the table, including Blizzard_StaticPopup's lookup ofFORCE_QUIT.OnAcceptduring the exit dialog, which forbade the protectedForceQuit()call. Removed both fallback assignments; entries are now added with direct key writes (StaticPopupDialogs["GEARMATIC_..."] = { ... }), which mutate keys without writing the global itself.
[v2.4.0-release] - 05/18/2026
In-Game
- Loadouts launched on Vanilla and TBC. Save named gear sets per character and swap between them with one click.
- Sidebar lives on the Character window. Toggle it with the new chestplate button next to the close X.
- Double-click a loadout to equip it; drag it onto an action bar to make a one-click macro; right-click for Rename, Change Icon, Save Current, Export, Delete.
- Alt-hover any equipment slot for a per-slot menu: Ignore Slot, Place In Bags, or pick a replacement from a grid of candidates in your bags.
- Built-in icon picker with search and Items / Spells filtering.
- Party / raid / guild GearMatic users see your loadout swaps in chat (toggleable in Settings; never SAY/YELL).
- Spec change prompts a non-intrusive "switch to loadout X?" popup. Never auto-swaps gear. "Don't ask again" supported per character.
- New /gm subcommands: loadouts, save, load, rename, delete, export, import, unequip, icon.
- Loadouts tab in Settings on Vanilla and TBC. Wrath / Cata / Mists keep using Blizzard's built-in Equipment Manager.
- Loadout strings export with a new GMLOv2 format. Old GMLO:01 codes prompt you to save and re-export.
- Full translations for every new string in all 12 supported locales.
Added
- Loadouts (Vanilla and TBC only): save and switch named gear sets per character with full Gears-parity UX.
- PaperDoll-attached sidebar with toggle button on the character frame title strip.
- Double-click a loadout row to equip; drag onto an action bar; right-click for context menu (Rename / Change Icon / Save Current / Export / Delete).
- Alt-hover any equipment slot for a per-slot flyout: Ignore Slot, Place In Bags, and a grid of candidate replacement items from bags (one-click swap).
- Built-in icon picker (uses Blizzard's IconDataProviderMixin) with search and All/Items/Spells filter.
- AceComm peer broadcast of loadout swaps to party/raid/guild GearMatic users, with a 5-second per-sender throttle. Only fires on real swaps; never SAY/YELL; toggleable in Settings.
- Drag-to-action-bar via per-character macros, auto-recreated on rename. Macro slot cap honors MAX_CHARACTER_MACROS.
- Non-modal spec-change suggest popup; per-character "don't ask" list. Never auto-swaps.
- New /gm subcommands:
loadouts,save,load,rename,delete,export,import,unequip,icon. - Settings tab "Loadouts" appears only on Vanilla and TBC.
- Loadout strings export as
GMLOv2:.... LegacyGMLO:01:exports prompt the user to save and re-export. - Translations for every new key into all 12 supported locales (enUS, enGB, deDE, esES, esMX, frFR, itIT, koKR, ptBR, ruRU, zhCN, zhTW).
- Wrath / Cata / Mists are intentionally not supported, those clients have Blizzard's built-in Equipment Manager.
- Sidebar title icon: silver portrait ring (BlueMenuRing desaturated + cool tint) with the new
GearMatic-Medallionbrand artwork, parked on the CharacterFrame title bar over the X close button. Ring + medallion show/hide together with the sidebar. - Sidebar visibility is now persisted per character in
GearMaticDB.settings.loadoutSidebarShown. Toggling off via the paperdoll button (or the sidebar X) stays off across/reloadand CharacterFrame re-opens; default is on for fresh installs. - Sidebar title bar reanchored to fill the full width: TopLeftCorner switched to the clean
UI-Frame-TopCornerLefttexcoords and TopBorder + LeftBorder reanchored off the new corner so the gold strip no longer cuts off where the old portrait socket used to overhang. - "Add new loadout" row renders "ADD" in Anton 18pt next to the green plus icon.
[v2.3.1-release] - 05/16/2026
In-Game
- Fixed /gm scan and the /gm browser on Mists Classic 5.5.3. Previously the browser showed mostly empty slot squares despite your character having a full gear set, and /gm scan appeared to do nothing.
- Slot icons no longer go blank right after login. Item icons are cached when scanning so the browser fills in immediately.
- Equipping or swapping an item never wipes the previous slot data, even if WoW's item info isn't loaded yet.
Fixed
- Critical: MoP Classic 5.5.3 scan abort.
Scanner.detectSpecNamecalledGetNumTalentTabs/GetTalentTabInfoafter atype(...) == "function"check. Blizzard kept the function symbols but now throws"Script_GetNumTalentTabs: API unsupported in this version of World of Warcraft."on call, which aborted bothScanner.RefreshSpecandScanner.ScanCurrentCharactersilently (no chat error unless/console scriptErrors 1was set). Symptoms on MoP Classic:/gm scanappeared to do nothing, the/gmbrowser showed mostly empty slot squares despite full gear, and saved-vars drifted down to a handful of stale slots. Fix: every legacy talent-API call (and the modernGetSpecializationcalls, defense in depth) is nowpcall-wrapped; on failuredetectSpecNamereturnsniland the caller falls through to the priorentry.specvalue so the rest of the scan completes normally. - Slot grid icons rendering blank against cold item-info cache. The
/gmbrowser calledGetItemIcon(itemLink)live at paint time, which returnsnilfor items WoW has evicted from its per-item cache (common right after login for items the player has not interacted with). With noGET_ITEM_INFO_RECEIVEDrepaint hook, those slots stayed blank until the cache warmed up. Fix:Scanner.readSlotnow captures the icon at scan time (fromGetItemInfo's 10th return, falling back toGetItemIcon), persists it on the saved slot entry, and the browser'spaintSlotprefersslotData.iconbefore the live lookups. - Slot data wiped on cold-cache reads.
Scanner.ScanCurrentCharacterandScanner.RescanSlotboth overwrote a slot withnilwheneverreadSlotreturned no link AND no id, even when the slot had real data from a previous session. On a fresh login this could persist a 19-slot character with only 4 surviving slots once cache warmed too slowly. Fix: whenreadSlotreports nil for a slot we already had data for, treat as ambiguous (cold cache, not a real unequip) and trigger a retry instead of wiping.RescanSlotgains a per-call retry counter soPLAYER_EQUIPMENT_CHANGEDfiring before item info loads no longer destroys saved data. Initial-scan retry budget bumped from 5 to 10 (2.5s -> 5s). - AutoEquip wrote partial slot entries. After equipping,
AutoEquip.refreshSlotInDatasetentry.slots[slotID] = { itemLink = link }and nothing else. itemID, itemLevel, rarity, name, classID, durability all stayed nil on the affected slot.Compat.AverageItemLevelsilently skipped the partial slot when computing iLvl, and the browser had nothing to display beyond the link. Fix: after capturing the link, runGetItemInfoonce and persist the full slot shape (itemID, itemLevel, rarity, name, icon, classID, durability, durabilityMax), matchingScanner.readSlot. Also stops wiping the slot on transient nil link reads right afterEquipCursorItem, which the API can return for a frame on Classic clients.
Static syntax check (luac -p) clean across every Lua module before tagging.
[v2.3.0-release] - 05/16/2026
In-Game
- On-screen alert banner pops every time you equip a piece. Big icon, a colored arrow (double green = upgrade, single green = side / first-fill, red = downgrade), and a percent number for the score change. Upgrades chime, downgrades play the raid-warning sound.
- Settings panel rebuilt into seven cleaner tabs (General, Detection, Alert Font, Sound, Social, Stat Import, Change Log).
- Nineteen new sounds bundled (LevelUp, Solid-Alert, Heroism Cast, Magic Beam, Jedi Beam, Batman Punch, Blue / Green Portal, Thunder, Whoop, Codec, Clamps, Blast, Coin, Shotgun, Boop, Combo Breaker, Done, Heaven) and selectable for the upgrade chime.
- Smarter scoring for low-level alts: every new piece is scored correctly from level 1, even before you pick a spec.
- Wrong armor type is now heavily penalized so leather on a warrior or mail on a mage stops looking like an upgrade.
- Heirlooms get a small score bump and are protected from being recommended as a swap target.
- Quest items and a built-in locked-item list (fishing poles, specialty pieces) are protected from auto-equip and from upgrade recommendations.
- Fix: stopped showing "+100% upgrade" on every white item.
- Twelve-locale translation coverage for every new string.
Added
- On-screen gear alert. Equip any piece and a banner pops with the item icon, a coloured chevron, and a score-delta percent. Upgrades show a double green chevron with a "Level Up" chime; downgrades show a red chevron with the WoW raid-warning sound; sidegrades and first-fills get a single green chevron. Sound only plays the first time you ever equip a given item on that character so repeat swaps stay quiet. Banner position, font (LibSharedMedia), colours, format strings, max stacked messages, start delay, fade time, and uppercase treatment are all configurable in the new Alert Font sub-tab. Manual previews via
/gm test(upgrade) and/gm test2(downrank). - Settings panel restructure into seven tabs. General (alert toggle, chat toggle, minimap, changelog popup, Support, About), Detection (the old tracking + smart-detect + auto-equip controls), Alert Font (sub-tabs for General, Notification format, Font), Sound (Upgrade sound on top, Downrank sound, Mute all), Social (unchanged), Stat Import (unchanged), Change Log (toggle + Open Now button).
- Bundled sound library. Nineteen OGGs ship with the addon (
LevelUp,Solid-Alert,Heroism_Cast,MagicBeam,JediBeam,BatmanPunch,BluePortal,GreenPortal,Thunder,Whoop,Codec,Clamps,Blast,Coin,Shotgun,Boop,COMBO-BREAKER,Done,Heaven) all registered with LibSharedMedia so they appear in every LSM-aware dropdown across your UI. PlusRaid Warningregistered against Blizzard's built-in chime as the default Downrank sound. - Class-default stat weights for low-level alts. Spec-less characters (level 1-9 with no talent points) now fall back to a class-wide weight set instead of the rarity-and-ilvl heuristic, so a fresh hunter scores every quest reward correctly from level 1. The bundled wowsims defaults still take over the moment a spec is detected.
- Armor proficiency penalty in scoring. Cloth on a level-50 warrior, leather on a level-50 hunter, and similar wrong-tier pieces get heavy score multipliers so they stop showing as upgrades over the proper armor type. Soft 10-percent penalty inside a ten-level grace window, hard 50-percent past it. Foreign armor types your class can't wear at all (e.g. mail on a mage) score at five percent.
- Stat overcap halving. When your current hit, spell-hit, or expertise rating is already past the soft cap, GearMatic halves that stat's weight when scoring new pieces so it doesn't recommend you stack what you already cap.
- Heirloom score bias. Heirloom-quality items get a 10 percent score boost so they don't lose to slightly higher-ilvl quest greens. Heirlooms are also protected against being recommended as swap targets when the equipped piece is also an heirloom.
- Quest / locked-item protection. Quest-bound items are never flagged as upgrade swaps or picked up by auto-equip. A built-in locked-ID list shields fishing poles and specialty gear loadouts from being clobbered by a regular weapon recommendation.
- Implicit armor weight. Stat-weighted scoring now also credits the raw armor value of a piece at the minimum positive weight times 0.1, so an armor-rich piece doesn't lose to a stat-equal but armor-light piece when the scale doesn't explicitly weight ARMOR.
- Branded chat output helper. New
ns:Print()prefixes every chat line GearMatic emits with the purple brand color. Load message moved offADDON_LOADEDonto a delayedC_Timer.AfteronPLAYER_LOGIN(8 seconds if ElvUI is loaded, 4 seconds otherwise) so it lands after the chat-frame splash instead of being hidden under it. - Twelve-locale coverage for every new string. Fifty-four new keys translated into enGB, deDE, esES, esMX, frFR, itIT, koKR, ptBR, ruRU, zhCN, zhTW. Slot names in the alert chat-line now read from the WoW client's localized
INVTYPE_*globals.
Fixed
- "+100% upgrade for current spec" bug on every white item. Scoring now reads live
GetInventoryItemLink("player", slotID)for the logged-in character instead of trusting the saved-vars snapshot, and refuses to claim+100%when the equipped slot has an item we just couldn't score yet (returns nil so the tooltip line is suppressed entirely rather than lying). Truly empty slots still get a+100%correctly. Alts whose gear has never been scanned are also suppressed so the tooltip doesn't spam fake upgrades for every untracked alt. GetItemStatsguarded for Vanilla. Wrapped the call so the absent-on-Classic-Era API falls cleanly into the fallback path instead of hard-erroring.
Changed
- All
print()and chat output routed through localization.slash_auto_*,slash_clear_usage,slash_equip_none,slash_scan_done,autoequip_in_combat,autoequip_missing_api,autoequip_cursor_abort,comm_no_peers,scaleimport_no_profiles,pawn_not_loaded,nag_retail_pawn,settings_libs_missing, andalert_chat_equippedall flow throughns.L[]now. - Every Lua comment stripped from the project. Cleaner codebase; behavior unchanged. TOC
##directives are not comments and stay.
Static syntax check (luac -p) clean across every Lua module before tagging.
[v2.2.0-release] - 05/15/2026
In-Game
- X / Twitter row added to the About section in Settings, under the Infinite Loop Alchemist profile name.
Added
- X / Twitter row in the About section. New
Textures/x-logo.tga(128x128 RGBA, bottom-left origin, matches the existing Buy Me A Coffee asset) plus an X icon and copyablehttps://x.com/infiniteloopalcinput rendered directly under the "Infinite Loop Alchemist" profile name. Strings localized in all 12 locales viasettings_about_x.
Static syntax check (luac -p) clean across every Lua module before tagging.
[v2.1.0-release] - 05/10/2026
Added
- GearMatic-to-GearMatic version ping over AceComm-3.0. New
Comm.luamodule registers the addon-message prefixGearMaticand broadcastsVER:<x.y.z>once onPLAYER_LOGINtoGUILDplus the appropriate group channel (INSTANCE_CHATin instances, elseRAID, elsePARTY). Peers' versions are silently collected intons.Comm.peers. New/gm peersslash subcommand prints which guildmates / party / raid members are running GearMatic this session, so the channel is testable without a UI. Plumbing only at this stage; no loot-drop or upgrade-broadcast wiring yet.
Changed
- TOC Interface numbers refreshed to current live Classic builds so the addon stops reporting "Out of Date" on launch:
GearMatic_Mists.toc:50500->50503(MoP Classic 5.5.3)GearMatic_Wrath.toc:30403->38001(Wrath / Titan Reforged)GearMatic_Vanilla.toc:11508(unchanged, Classic Era 1.15.8)GearMatic_TBC.toc:20505(unchanged, TBC Anniversary 2.5.5)GearMatic_Cata.toc:40402(unchanged)
Removed
GearMatic_Mainline.tocdeleted; retail / Mainline is no longer a supported flavor. Two reasons stack here:- wowsims (
https://wowsims.github.io/) does not target retail, so the Pawn-format scoring weights GearMatic relies on don't exist for Midnight specs. The addon's core "is this an upgrade for my spec" decision has nothing to read against on retail. - Blizzard's patch 12.0 ("Midnight") combat-addon block, which the Ace3 maintainer summarized as "Blizzard blocked the ability to use the COMBAT_LOG_EVENT_UNFILTERED event", knocks out the broader ecosystem this addon was designed to live in.
Will be reconsidered if/when wowsims publishes retail weights and Blizzard relaxes the addon API restrictions.
- wowsims (
Static syntax check (luac -p) clean across every Lua module before tagging.
[v2.0.1-release] - 05/09/2026
Fixed
- Auto-equip no longer ping-pongs items in and out of the same slot when the addon's slot snapshot is briefly empty.
Scanner.readSlotused to wipe a slot wheneverGetInventoryItemLinkreturned nil, which it does for a frame on Classic / Anniversary right afterEquipCursorItemand during the inventory-loading window on login. A wiped slot looked "empty" to the next sweep and triggered a "+100% over empty" stomp, kicking off Frayed Shoes / Thug Boots back-and-forth swaps even when the player already had the better piece equipped. Scanner now treats a nil link with a presentGetInventoryItemIDas needs-retry instead of empty, so valid slot data is never erased by a transient API hiccup. - AutoEquip cross-checks the live inventory before trusting an empty DB slot. Belt-and-suspenders for the Scanner fix: even if the DB says slot 8 is empty, AutoEquip now calls
GetInventoryItemLink("player", targetSlot)once before the safety check; if the live API reports an item, it syncs the DB back to that link and rescores so we never equip "+100% over empty" against a real piece.
Changed
- Changelog popup now uses the same parchment + wood-border look as CritMatic. Switched from the
Blizzard Tooltip(dark) backdrop toBlizzard Parchment 2background with aBlizzard Achievement Woodborder at edge size 15. Body text is now MoK 15pt in dark grey (0.2, 0.2, 0.2) so it reads cleanly on the parchment, with Anton kept as a fallback if MoK is unavailable. Same CritMatic palette, same warm "old paper" feel.
[v2.0.0-release] - 05/09/2026
Removed (breaking)
Send to /saytoggle and the SAY broadcast path are gone. /say is muted in instances by Blizzard, and on Classic / Anniversary the post-EquipCursorItemtiming made the broadcast unreliable in practice. Removing the option entirely is cleaner than continuing to ship a half-working channel. Group channels (PARTY / RAID / INSTANCE_CHAT) and GUILD remain. ExistingGearMaticDB.settings.social.sendToSay = truesaved-vars are now silently ignored.
Changed
- Social channel selection rewritten in the Questie style. Modeled on Questie's
_QuestieAnnounce.GetChatMessageChannel: a single group-context channel is picked based on where the player is (battleground ->INSTANCE_CHAT, raid ->RAIDorINSTANCE_CHATfor LFG, party ->PARTYorINSTANCE_CHATfor LFG), andGUILDis added as an additional simulcast when toggled and you're in a guild. No more "blast to SAY + GUILD + PARTY all at once" - one group channel, plus guild. - Brand color is now purple
#9212d5everywhere. Replaced the old soft-blue#7777ffacross chat lines, tooltip score header, minimap button tooltip, Loadout window title, the new in-game popup, and the load message so the addon reads consistently in chat.
Added
- In-game changelog popup, modeled on CritMatic's. Shows automatically on first login after a version bump (gated on a new General-tab toggle "Show changelog popup on update", default on), with the same AceGUI Frame + ScrollFrame layout, grey body text, and Anton font as CritMatic. Manual open with
/gm changelog(or/gm log). Capped at the latest 3 release entries plus a pointer to the fullCHANGE_LOG.mdon GitHub or CurseForge. /gmhelpslash command alias that prints the full slash-command help directly, matching CritMatic's/cmhelp. The original/gm helpstill works.- Branded multi-color load message, modeled on CritMatic's:
GearMatic: v X.Y.Z Loaded! - Use /gm for options - /gmhelp for all slash commands, with the addon name and slash commands in purple and the body text grey. - Login chat is quieter. The "GearMatic: smart upgrade detection is on. Type /gm auto off to disable." hint and the "GearMatic: registered config under Interface > AddOns > GearMatic (or just type /gm)." line are removed. The branded load message is now the only chat output on login.
Fixed
- Auto-equip no longer stomps a just-equipped upgrade with a worse bag item in the same sweep. When two candidates for the same slot lived in your bags (e.g. Frayed Shoes + Thug Boots in feet), the sweep equipped the first one, then on the very next iteration still saw the slot as empty/weak in its in-memory snapshot, scored the second item as "+100% over empty", and equipped it over the first. Both items would show "+100%" in chat and you'd end up with the worse one equipped and the better one back in your bag. The sweep now refreshes the in-memory equipped snapshot from the known bag link after each successful equip, rather than calling
GetInventoryItemLink(which can return nil for a frame on Classic / Anniversary right afterEquipCursorItemand would erase the snapshot we just wrote). Subsequent candidates always compare against what was just equipped. - Auto-equip weapon swaps no longer leave a ghost off-hand/main-hand entry in the in-memory snapshot. Equipping a two-hander correctly clears slot 17 (the displaced off-hand) from the snapshot, and equipping a shield / off-hand / holdable into slot 17 over a two-hander correctly clears slot 16. Prevents stale weapon-slot entries from biasing later iterations of the same sweep and from showing the wrong off-hand in the loadout window until the next full scan.
- /say (and other Social) broadcasts no longer drop on auto-equip swaps. The Social handler used
GetInventoryItemLinkto read the just-equipped item, but on Classic / Anniversary that API can return nil for one frame right afterEquipCursorItem, which madeSocial.OnEquipChangebail atif not id then return endand never reachSendChatMessage. AutoEquip now hands Social the known bag link directly via a newSocial.RecordEquippath, which broadcasts immediately and updates the lastEquipped cache. The PLAYER_EQUIPMENT_CHANGED handler still services player-driven (drag-drop, EquipmentManager) equips, with a 1-second post-RecordEquip guard that ignores nil-link timing glitches without breaking real unequip detection. Scoring.ScoreItemno longer returns nil for armor-only items. On Classic, low-level gear like Frayed Shoes or Thug Boots may haveGetItemStatsreturn nil because they only carry an armor value. The previous code returned nil in that case, which downstream code read as a score of 0 and produced phantom "+100% over equipped" deltas during a sweep. ScoreItem now falls back to ilvl-rarity scoring (with the fallback flag set, so the auto-equip occupied-slot safety hardening still requires a real stat-weighted scale before swapping).- Fallback score now reads the actual armor value from the item tooltip and weights it heavily. Without this, low-level Vanilla gear scored only on
ilvl * rarity_multiplier, so a higher-rarity / equal-ilvl piece with zero armor could outscore a lower-rarity piece with 5+ armor and auto-equip would pick the worse one. Scoring now opens a hidden tooltip frame, reads the "X Armor" line, caches the result by item ID, and folds armor into the fallback score at 10x weight (ilvl * rarity_mult + armor * 10) so armor is the dominant signal for armor pieces. Frayed Shoes (5 armor) now reliably beats Thug Boots (0 armor) on score alone. - Auto-equip safety hardening relaxed for armor-piece upgrades in fallback mode. The v1.0.8 hardening required a real stat-weighted scale (Pawn) before it would swap into an occupied slot. That was correct for stat-driven items where ilvl alone can mislead, but it blocked obvious armor upgrades on leveling characters with no Pawn scale. AutoEquip now allows the swap into an occupied armor slot when the candidate has strictly more armor than the equipped item (read from the live tooltip, same scanner the score uses). Applies only to true armor slots (head, shoulder, chest, waist, legs, feet, wrist, hand, cloak, shield). Non-armor slots (rings, trinkets, weapons, ranged) keep the strict v1.0.8 rule because their value is in stats, not armor. Combined with the cursor-flow hardening, the worst case is still "wrong stat priority for casters in fallback" - never a destroyed item.
Changed
- Auto-equip success line stays branded "GearMatic" (no rename). Local chat-frame line continues to be
|cff7777ffGearMatic|r equipped X (+N%). It is suppressed only when /say will actually carry the announcement (SAY toggle on, not in an instance, slot was occupied). Other Social toggles (party / raid / guild / bg) do not suppress the local print, so you always have a personal record when /say cannot fire.
Added
- Bundled the same Anton font CritMatic uses for its alerts. Registered with LibSharedMedia as
Anton. Loadout window title, header, and footer now render in Anton with an outline so the two addons share a visual identity. Falls back to Blizzard fonts if the file is missing.
Changed
- Loadout slot textures now show clearly. Empty slot art renders at the same size as the item icon (both at full slot extent with 7%/7% texture-coord trim to remove the dark border that comes baked into Blizzard's slot art), and a dark slot background is laid behind so the slot is visible against the loadout window backdrop. Each slot uses its specific Blizzard art: Head, Neck, Shoulder, Back, Chest, Shirt, Tabard, Wrists, Hands, Waist, Legs, Feet, Finger, Trinket, MainHand, SecondaryHand, Ranged.
- Loadout prev/next buttons are now greyed out at the boundaries: prev disabled on the first character, next disabled on the last, both disabled when only one character is tracked. The cycle no longer wraps around past the last alt.
- Tooltip and quest/loot indicators no longer show the red downgrade chevron for sidegrades. Items in the -1% to +1% range get a clean line with no chevron prefix; only true downgrades (delta <= -1) get the red chevron.
[v1.0.8-release] - 05/09/2026
Added
New General-tab toggle: "Prefer Pawn weights for scoring" (default on, disabled when Pawn is not installed). When on, GearMatic auto-picks the Pawn-imported scale that matches your class (and spec when possible) and uses those weights for every scoring path (tooltip, quest reward, loot, bag overlay, browser, auto-equip). No manual "Set Active" click needed. When off, GearMatic falls back to your manually selected profile or its bundled defaults.
Renamed the cross-character browser to Loadout. Window title now reads "GearMatic Loadout". New slash command
/gm loadout(the old/gm browser,/gm browse,/gm charsaliases still work).New keybinding in General settings: "Open loadout". Bind any key to instantly open the Loadout window. Reapplied on login.
Quest reward chevron now uses armor value as a third tiebreaker after armor-type priority and delta. When two leather pieces tie at +100% for a Rogue, the one with more armor wins. Helps when an empty slot gives both items the same delta but one is objectively better-protected.
New "Run auto-equip sweep now" button in the Auto-equip group on the General tab. Triggers a single sweep on demand, even with the master toggle off. Same hardened safety path applies.
Auto-equip cursor flow can no longer lose an item.
ClearCursor()removed entirely from the swap path. New flow: pick up the bag item →EquipCursorItem(slot)→ if anything left on cursor, drop it back into the bag slot we just picked from (which is empty by definition) → if even that fails, abort with a chat message telling the user "item is on your cursor, drop it manually, nothing was lost." Worst case is the new item stays in the bag and the previously-equipped item stays equipped. There is no path to a destroyed/lost item.Critical auto-equip safety hardening. Auto-equip will no longer swap into an occupied slot when GearMatic cannot make a real comparison. Specifically: an upgrade is only auto-equipped over an existing item when (a) a real stat-weight scale is active (not the iLvl fallback), (b) both the candidate and currently-equipped item produced positive non-fallback scores, and (c) the raw stat-weighted delta clears the user's minimum percent. Filling a genuinely empty slot still works as before. This closes the path where a missing spec / not-yet-cached scoring caused the equipped item to read as score=0 and any bag item to read as a "+100% upgrade", which on a fragile cursor swap could lose the previously-equipped item.
Auto-equip swap is now atomic via
EquipCursorIteminstead ofPickupContainerItem + PickupInventoryItem + ClearCursor. Same pattern EquipmentManager and Pawn use. Eliminates the edge case where the previously-equipped item could fall off the cursor when its origin slot was already occupied. Falls back to the old path on clients withoutEquipCursorItem.Auto-equip now triggers on
PLAYER_ENTERING_WORLD(login //reload/ zone change) too, not just on bag updates and combat-end. If you enable the toggle while items are already in your bags, a/reloadis now enough; you no longer have to wait for a bag update or combat-end event before existing upgrades get equipped./gm equipprints a sweep summary:sweep done, considered N upgrade(s), equipped M.Helps debug "why didn't anything equip"."Cannot auto-equip in combat" message no longer spams the chat for automatic sweeps; it only prints when you ran
/gm equipmanually while in combat.Loadout window redesigned as a paperdoll. Real WoW slot textures and item icons, two-column gear layout matching the Blizzard character pane, weapon row at the bottom. Per-slot durability bar colored green/yellow/red. Hover any slot for the full item tooltip with durability percent. Header shows class-colored character name, race, class, level, spec. Footer shows iLvl, lowest-slot durability, and
(N/total)position. Prev / Next buttons at the bottom corners cycle through every alt on the realm; left/right arrow keys also navigate while focused.
[v1.0.7-release] - 05/09/2026
Changed
- Stat Import tab help text now explicitly mentions both
wowsims.github.ioexports and the Pawn addon as sources, with both names highlighted, so users understand the single paste box accepts strings from either.
[v1.0.6-release] - 05/09/2026
Added
- LICENSE file at the repo root: All Rights Reserved. Embedded third-party libraries (Ace3, LibStub, etc.) keep their own original licenses.
- Every TOC now declares
## X-License: All Rights Reserved.
[v1.0.5-release] - 05/09/2026
Added
- New General-tab toggle: "Defer to Pawn for tooltip and bag overlay". When Pawn is loaded and the toggle is on, GearMatic hides its current-spec tooltip line and green bag chevron so they do not duplicate Pawn's display. Yellow alt-aware chevrons, quest reward chevron, loot chevron, cross-character browser, durability nag, auto-equip, and social broadcasts stay live (Pawn does not provide those). Disabled-grey when Pawn is not installed. Default off.
[v1.0.4-release] - 05/09/2026
Added
- Saved profiles list now shows a blue
[Pawn]tag next to scales that were auto-imported from the Pawn addon, so you can tell at a glance which profile came from where. - One-time login warning on retail when Pawn is not loaded: GearMatic does not bundle retail stat weights, so on Mainline you need Pawn installed for accurate scoring. Without Pawn (or a manually pasted scale), GearMatic on retail falls back to item-level only.
Notes
- Retail requires Pawn. Bundled wowsims weights only cover Vanilla through Mists. On retail, install Pawn with your usual scales and GearMatic will auto-import them.
[v1.0.3-release] - 05/09/2026
Added
- Retail / Mainline support, backed by Pawn. GearMatic_Mainline.toc is back (Interface 110005). Spec auto-detect now uses
GetSpecialization()first on retail, then falls through to the classic talent API. GearMatic does not bundle retail wowsims weights, so on retail the recommended path is: install Pawn with your usual scales and let GearMatic auto-import them on login (or paste your own scale via/gm import).
[v1.0.2-release] - 05/09/2026
Added
- Real Pawn integration. If the Pawn addon is loaded, GearMatic now imports every non-hidden Pawn scale into your saved profiles automatically on login. Toggle in General settings ("Auto-import scales from Pawn"), or run on demand with the new "Sync Pawn scales now" button or
/gm pawnslash command.
Changed
- Replaced the dead
## OptionalDeps: Pawndeclaration in every TOC with a real runtime integration. The TOC line was previously a no-op that implied an integration we did not actually deliver.
[v1.0.1-release] - 05/08/2026
Removed
- Dropped Retail / Mainline support. The addon was never actually compatible with retail (no retail spec API, no retail wowsims weights bundled). Removing the broken
GearMatic_Mainline.tocso users on Dragonflight / War Within do not install something that silently fails.
[v1.0.0-release] - 05/08/2026
Initial public release.
Added
- Cross-character equipped gear tracker with login durability nag.
- Smart upgrade detection driven by Pawn-format stat weights.
- Bundled wowsims default scales for Vanilla, TBC, Wrath, Cata, Mists (57 specs).
- Auto-detect spec from talents.
- Tooltip overlay on bag, vendor, AH, group loot, and mail items.
- Quest reward window chevron for the best reward for your spec, with class armor priority (Plate > Mail > Leather > Cloth).
- Loot window chevron on upgrades.
- Bag overlay chevron on bag items, compatible with Bagnon and most bag addons.
- Yellow chevron variant for items the current character cannot wear but at least one alt can.
- Auto-equip toggle for out-of-combat upgrade swaps. Manual sweep with
/gm equip. - Cross-character browser at
/gm browsershowing iLvl, lowest durability, and per-slot scores. - Stat profiles tab in settings: paste, save, switch active scale, per-profile keybinds, and a cycle keybind.
- Social tab broadcasts equip changes to /say (skipped in instances), /party, /raid, /guild, and /battleground.
- Minimap button (off by default).
- Sidebar settings layout via Ace3 with General, Stat Import, and Social tabs.
All Relations
- All Relations
- Embedded Library
- Optional Dependency
- Required Dependency
- Tool
- Incompatible
- Include
This mod has no related projects

