StellarLoot

WoW MoP auto-need/greed tool, for running dungeons.

File Details

v0.8.1

  • R
  • Jun 18, 2026
  • 177.16 KB
  • 13
  • 5.5.4
  • MoP Classic

File Name

StellarLoot-v0.8.1.zip

Supported Versions

  • 5.5.4

Changelog

0.8.1 — Stop Needing off-hand gear you can't wear with a two-hander

Fixed: an off-hand item no longer reads as a free upgrade while a two-hander is equipped. A two-handed weapon fills only the main-hand slot and leaves the off-hand empty, so an incoming off-hand piece (caster off-hand frill, off-hand weapon, or shield) was comparing against nothing — ilvl 0, or, in the default stat-only mode, simply matching on primary stat with no comparison at all — and rolling Need on gear the player structurally cannot equip. Reported by a Holy Priest on a staff who got a Need on an Int off-hand frill (Bottle of Potent Potables, 81076) over a higher-ilvl two-hander. The decision engine now recognizes that main-hand 2H and off-hand are mutually exclusive: an off-hand-only item is suppressed (Greed by default, via unusableAction) when it matches your current spec. A piece that matches your off-spec stat still routes to the off-spec equipment-set comparison untouched — wielding a 2H means a shield is an off-spec concern, and that path owns it.

Fixed: weapon ilvl comparisons account for the 1H/2H trade. A two-hander displaces both hands, so it now compares against the better of your two equipped weapons (it must beat the weapon you'd actually give up, not the worse one). A lone one-hander dropping while you hold a 2H compares against that 2H rather than the empty off-hand slot. Both only matter in requireILvlUpgrade mode; both close the same empty-slot blind spot the off-hand fix addresses.

Tests: 9 new pins covering the gate (frill / off-hand weapon / shield while holding a 2H), the controls that prove it doesn't over-fire when actually running a 1H + off-hand, off-spec shield routing, and both directions of the 1H/2H ilvl trade. 56 curated cases + the exhaustive corpus sweep pass with zero divergences.

0.8.0 — Effect trinkets stop nagging; full disposition UI

Changed: effect-only trinkets Greed by default instead of leaving a Manual dialog. 0.7.0 routed any trinket with no readable primary stat and no spec mapping to MANUAL, on the theory its value hides in Use:/Equip: effects the API won't surface. In practice that fired indiscriminately: a Protection Paladin running dungeons hit MANUAL on a caster Int-proc trinket (Flashfrozen Resin Globule, 81263) and a healer Spirit trinket (Empty Fruit Barrel, 81133) — items plainly not hers — reintroducing exactly the manual clicking StellarLoot exists to remove. Effect-trinket disposition is now governed by unjudgeableTrinketAction (MANUAL | GREED | PASS), defaulting to GREED. The cautious 0.7.0 behavior is one setting away; the default keeps SL grabby in dungeons, where precision is SLFG's job, not SL's.

Fixed: Spirit trinkets on non-healers are recognized as foreign, not unjudgeable. Spirit is unambiguously a healer stat, so a Spirit-bearing trinket on a non-healer is off-stat — not opaque. It now Greeds via the wrong-primary-stat path (governed by unusableAction) even when unjudgeableTrinketAction is set to MANUAL, so careful-mode users aren't nagged by an item that's clearly not theirs. Only trinkets with no readable primary stat and no Spirit reach the unjudgeable path.

Added: nonGearAction makes non-gear disposition configurable. 0.7.2 hard-coded mounts / pets / gold caches / recipes to MANUAL. That's now nonGearAction (MANUAL | GREED | PASS), still defaulting to MANUAL — auto-greeding a coveted mount stays off by default — but greedable for players who'd rather sweep non-gear.

Added: every disposition knob is now in the options UI. A new Disposition section surfaces the five fallback-roll knobs (unusableAction, wrongArmorTypeAction, nonUpgradeAction, nonGearAction, unjudgeableTrinketAction) as dropdowns. Each offers the same four choices — Need / Greed / Pass / Manual: the dropdown never strips away a roll the game itself allows, so a player can choose to Need a whole category, or leave any category for a manual decision. Greed stays the shipped default; when the client doesn't offer Need on a given roll, the choice degrades to Greed/Pass rather than inventing a Need. The Upgrades section gains an "extra margin vs. heirlooms" slider (heirloomNeedMarginExtra, ilvl-mode only), and the Log sub-panel gains a history-size slider (log.maxEntries). The expert classOverrides (forced primary stat, extra accepted stats) stay slash-only by design — they override spec auto-detection and reach across every item category, so they aren't fit for fire-and-forget widgets.

Tests: added pins for the new default (effect-only trinket → Greed), careful mode (→ Manual when configured), the Spirit-on-tank foreign case, and the nonGearAction sweep. 47 curated cases + the exhaustive corpus sweep pass with zero divergences — the trinket-disposition change never reaches an oracle pair, since every EJ-listed trinket is spec-mapped.

0.7.2 — QC fixes: ranged proficiency, MANUAL for non-gear; test suite

Fixed: warriors and rogues no longer count as gun/bow/crossbow users. MoP 5.0.4 removed the ranged slot; bows, guns, and crossbows are hunter-only and thrown weapons left the game entirely, but Data.ClassWeapons still carried the vanilla-era proficiencies. A ranged drop for a warrior was judged at the stat sniff ("missing primary stat") instead of the proficiency gate — same Greed either way, but the wrong mechanism. Warrior list verified in-game against the Weapon Skills passive; the rogue removal is inferred from the same patch change. Found by a manual QC review pass — the corpus sweep's oracle is structurally blind to this shape, since the EJ never lists ranged weapons for non-hunters.

Changed: non-gear drops (mounts, pets, gold caches, recipes) return MANUAL instead of autogreeding. Items that reach the end of the decision chain without being equippable gear or a known tier token aren't covered by Stellar Loot's design goal, and auto-greeding a coveted mount on the player's behalf is the kind of decision they'd rightly resent. The engine now declines to judge and leaves the dialog up. Tier tokens whose roll lacks a Need option still fall through to the default Greed. Also from the QC review pass; the raid corpus contains 11 such items (5 mounts, 4 battle pets, 2 gold caches).

Added: a test suite for the decision engine (tests/, dev-only — excluded from builds). Two layers: ~35 curated cases pinning the full shipped-bug history (toggle precedence, extraStats key forms, trinket mapping, the 0.7.1 cloak fix) asserting both the action and the decisive rule, plus an exhaustive corpus sweep — all 34 class-specs × all 2,931 Encounter Journal items × two equipped-ilvl regimes (~200k evaluations, ~3s), using Blizzard's own EJ loot-filter mapping as the oracle. Fixtures are generated from the ej-gear-audit 5.5.4 dump (build 68077) and committed, so the suite runs standalone: ./tests/run.sh. Mutation-validated: reverting the 0.7.1 cloak fix lights up 772 sweep violations. The first full sweep of the current engine found zero divergences from the EJ filter.

0.7.1 — Cloaks exempt from the wrong-armor-type rule

Fixed: cloaks no longer trip WRONG_ARMOR_TYPE for non-cloth wearers. Step 6's flexibility exemption keyed on ARMOR_GENERIC, which covers rings/necks/trinkets — but cloaks report subclass Cloth in MoP Classic, so every cloak read as off-type armor for anyone whose preferred type isn't cloth, and a mainstat-matching cloak upgrade was greeded instead of needed. The exemption now also matches equipLoc == "INVTYPE_CLOAK". (Cloth-subclass cloaks don't break the all-preferred-armor bonus in-game, so the proficiency and preference logic elsewhere is unaffected.)

0.7.0 — Trinket spec mapping: effect trinkets judged correctly

Added: Data.TrinketSpecs — itemID→specID mapping for every MoP raid trinket. Most MoP raid trinkets — 114 of the 150 itemIDs the Encounter Journal lists — carry no primary stat; their value lives in Equip:/Use: effects invisible to GetItemStats. The step-8 stat sniff misread all of them as "wrong primary stat," so the engine greeded (or passed, under stricter overlay configs) on items like Prismatic Prison of Pride for the very healers it was itemized for. The new generated file (TrinketSpecs.lua, 250 entries) carries Blizzard's own item→spec mapping, lifted from the EJ loot filter — which is spec-granular on MoP Classic 5.5.4 (build 68077), verified empirically — and extended with Warforged/Thunderforged variants, which use separate itemIDs the journal never lists, via an itemID-range scan joined by base name. Regeneration tooling and dump provenance live in the ej-gear-audit sibling repo.

Changed: trinkets consult the mapping before the stat sniff. Player spec in the item's set → main-spec branch (the normal ilvl comparison still decides Need); off-spec in the set → off-spec branch; in the table but matching neither → nonUpgradeAction. Trinkets with true primary stats (Skeer's Bloodsoaked Talisman, Dysmorphic Samophlange of Discontinuity) and all non-trinket items take the unchanged path.

Added: MANUAL outcome for unjudgeable trinkets. A trinket with no primary stat of any kind and no mapping entry — Timeless Isle effect trinkets, or a future tier's unmapped drops — now returns MANUAL: the engine declines to judge and leaves the roll to the player, instead of silently mis-rolling on a "wrong primary stat" read. Failure mode is loud, by design: an unexpected MANUAL means a gear source the mapping never covered.

Fixed: extraStats config keys can now match rating stats. The same corpus census settled 5.5.4's GetItemStats key scheme as mixed — base stats use _SHORT (ITEM_MOD_SPIRIT_SHORT), ratings are unsuffixed (ITEM_MOD_HIT_RATING) except mastery (ITEM_MOD_MASTERY_RATING_SHORT). The extraStats matcher hardcoded the _SHORT form, so a configured rating fragment could never match. It now accepts an exact ITEM_MOD_* key, or tries a fragment in both forms. (Dormant in practice — no known config populates extraStats — but wrong mechanisms don't get to ship knowingly.)

Verified: difficulty and forged siblings share exact base names. The 0.6.0 unique-equipped name-matching leaned on a "gut plus one boss checked" assumption; the corpus confirms it across every MoP raid, difficulty, and forged variant — 101 forged name-joins validated cleanly against journal base entries.

0.6.1 — Audit fixes: toggle precedence, defer-path hardening, DEFER logging

Fixed: per-item overrides no longer bypass the master toggle. The override check ran before the enabled check, so an overridden item still auto-rolled while the addon was disabled — contradicting the toggle's documented role as the panic button that stops everything. The master toggle is now the first check in the decision chain.

Fixed: the deferred-roll safety timer can now tell "undecided" from "canceled". Deferred rolls write a DEFER marker into the pending-roll table instead of leaving it empty. Previously a roll that was canceled (or won/expired) before the timer fired looked identical to one still awaiting item info, so the timer submitted a fallback roll against a dead rollID and left orphaned bookkeeping entries behind.

Fixed: the fallback action respects the roll options actually offered. With fallbackAction = "NEED", the timeout fallback submitted a Need roll even when the dialog never offered Need. The fallback now degrades NEED → GREED → PASS based on the options captured when the roll first appeared, and the log line says when (and why) it degraded.

DEFER decisions now reach the log. Deferred evaluations and their eventual timeout fallbacks are rendered and saved to the decision history like any other outcome. Previously a defer was invisible unless it timed out, and even then only as a transient chat warning — a dropped signal is much easier to miss than a negative one.

Removed: vestigial enchanting-skill tracking. PlayerState.enchantingSkill, RefreshProfessions, and the SKILL_LINES_CHANGED registration were scaffolding for the disenchant support removed in 0.2; nothing has consumed them since.

UI: the ilvl-margin slider label renders its formatted text on first panel open. The refresh path relied on OnValueChanged to apply the formatter, which doesn't fire when the value is unchanged — with the default margin of 0 the label stayed bare until the slider was dragged.

0.6.0 — Default-action knobs, unique-equipped ring matching, UI polish

Added: three default-action SavedVariable keys. unusableAction, wrongArmorTypeAction, and nonUpgradeAction (each GREED|PASS, default GREED) let callers configure what the decision engine does when an item isn't a Need. Defaults preserve existing behavior — SL stays grabby out of the box. The keys are not surfaced in the options panel; sister addons (e.g. StellarLoot_For_Gargul) overlay their own values for stricter raid behavior by passing a merged config into Decision.Evaluate, and advanced users can poke them via SavedVariables. Keeps SL's UI lean while still giving the decision engine the config surface integrations need.

Fixed: unique-equipped ring/trinket comparisons could read the wrong slot. When rolling on an item whose name matches one of two unique-equipped pieces (the common case is two same-family rings at different ilvls), the comparison now targets THAT slot specifically — the one the game forces you to replace — rather than the worst-ilvl slot in the family. Matching by name catches Celestial/Normal/Heroic siblings, which share names but use different itemIDs.

UI: section-label clipping fix. "Fallback Action" and "Per-item Overrides" headings rendered partially off-screen on the left because they anchored to dropdown frames with a negative x offset that overshot the scroll viewport's left edge. Now anchored at x=0, matching the column origin where the other section headings sit. Vertical spacing between the fallback description and its dropdown bumped from 4px to 20px to leave room for the dropdown's small label, and the Off-spec source dropdown shifted by the same amount for consistency.

Slash: /sl eval now notes the upgrade asymmetry. Output prepends a one-line reminder that linked items show base ilvl while equipped items reflect upgrades — so a 2/2 upgraded piece linked from inventory can look like a downgrade in eval output even when it isn't.

0.5.2 — Off-spec set comparisons read the right item

Fixed: off-spec equipment-set comparisons could read the equipped item instead of the set's. On MoP Classic 5.5.4, C_EquipmentSet.GetItemLocations hands back a player-encoded location for a set whose item lives in bags while a different item is currently equipped in that slot. The 0.5.0 code took that location at face value and called GetInventoryItemLink("player", invSlot), which returns whatever's currently equipped — the active spec's gear, not the set's. Result: a same-item drop showed up as a massive ilvl upgrade over the off-spec set (e.g. a 502 Crown of Potentiated Birth read as +52 over the Holy set, because the comparison was actually against the 450 Prot helm equipped at the time). Equipment-set resolution now identifies the set's item via C_EquipmentSet.GetItemIDs and locates it ourselves (equipped slot first, bag scan otherwise). The ilvl read goes through C_Item.GetCurrentItemLevel(ItemLocation), which also closes the 0.5.0 follow-up about upgrade-aware bag reads — an upgraded set piece sitting in bags is now compared at its upgraded ilvl, not its base.

/sl readsetilvl <name> debug helper — walks every slot the named equipment set defines and prints the assigned itemID, where the addon located it, the resolved ilvl, and the link. Quote the name if it has spaces. Useful for verifying off-spec set comparisons match what you expect without waiting on a real roll.

0.5.1 — /sl survives combat

Fixed: /sl errored when used in combat. Opening the Settings panel touches protected UI and is blocked under combat lockdown, so /sl during a fight threw instead of opening the options. The panel now defers opening until combat ends — invoking /sl mid-combat logs settings panel will open when you leave combat and registers for PLAYER_REGEN_ENABLED, then opens normally once the fight is over. A single watcher frame is reused across deferrals.

0.5.0 — Stat-only default, simpler everywhere

Interface bumped to 50504 for Mists Classic 5.5.4. The settings panel now opens by category ID rather than name — 5.5.4 tightened Settings.OpenToCategory to reject non-numeric IDs, so /sl (and any other entry into the options panel) errored out on the patched client.

Fixed: equipped ilvl ignored MoP upgrades. Equipped pieces were compared at their un-upgraded base ilvl regardless of upgrade state — a 2/2 upgraded chest at 510 was tracked as 502, so a 504 drop in the same slot looked like a +2 upgrade and triggered a false Need. Root cause: in 5.5.4 GetInventoryItemLink returns a stripped link with no upgrade encoding, so both GetItemInfo and GetDetailedItemLevelInfo (which delegate to the link) report base ilvl. Equipped-slot reads now go through C_Item.GetCurrentItemLevel(ItemLocation:CreateFromEquipmentSlot(slot)), which reads the live item and reflects upgrades. Incoming loot still uses the link path — drops are always base ilvl (upgrades happen at a vendor, post-loot), so link-derived base is the right answer for them. Equipment-set comparisons (off-spec, ilvl-strict mode) still use link-based reads and would understate upgraded bag items; flagged as a follow-up. /sl equipped <slot> is a new diagnostic that prints C_Item ilvl vs link base ilvl vs cached snapshot. Verbose logging now also emits a one-line equipped ilvl: 1=510 5=502 ... readout after RefreshAllSlots.

Ilvl-upgrade requirement now defaults OFF. Decisions default to "stat-matching item → Need" without an ilvl-delta check. Item level is an unreliable signal of item value: it skews wildly across expansions, on PvP gear, on BoAs, and on heirlooms (which report ilvl 1 in inventory). Stat-match is the more honest "do I want this?" signal. Existing users keep their saved setting; only fresh installs (and Reset) pick up the new default. Toggle Need only on item-level upgrades in the options panel for stricter endgame behavior.

Stat-only mode skips the off-spec equipment set requirement. Previously off-spec match required an in-game equipment set as the ilvl comparison source. With ilvl filtering off, the set is no longer needed; off-spec stat matches Need outright. The set is still used when ilvl filtering is on.

Heirloom handling — quality-7 heirlooms now substitute a single flat synthetic ilvl (Data.HEIRLOOM_ILVL = 400) anywhere their effective ilvl is computed. Previously they reported ilvl 1 to the API and triggered false Needs on every drop when ilvl filtering was on. Effective-ilvl resolution is centralized in Data.EffectiveILvl so the equipped side, the incoming side, and the equipment-set side all share the same logic.

/sl heirloom <link> debug helper — confirms whether an item is recognized as a heirloom and prints both the API-reported and the effective ilvl.

Fixed: equipped item level could stick at 0 after login. RefreshAllSlots runs once at PLAYER_LOGIN, when an equipped item often isn't in the client cache yet — GetDetailedItemLevelInfo/GetItemInfo then return 0, and the slot was only re-read on PLAYER_EQUIPMENT_CHANGED (which fires only when gear actually changes). A slot that read 0 stayed 0 for the whole session, so every same-slot roll compared against 0 and triggered a false Need. Slots that resolve to 0 are now tracked and re-read on GET_ITEM_INFO_RECEIVED once the item finishes loading.

Verbose logging now covers equipped-slot refresh. With /sl verbose on, the addon logs when a slot's item level can't be read at login — queued for a deferred re-read — and again when that re-read resolves it. Silent unless verbose is enabled; a way to confirm the fix above engaged.

Removed: quality filter. The minQuality / qualityFilterEnabled config and its UI row are gone — group loot does not surface sub-Uncommon items, so the filter was dead weight.

Removed: greedUnusable toggle. Items the class cannot equip now always Greed (Pass if Greed isn't offered). The previous opt-out toggle and its UI row are gone.

Optional heirloom stickiness retained — config heirloomNeedMarginExtra (default 0) still exists as a hidden knob; when set and ilvl filtering is on, it pads the upgrade margin required to displace a heirloom.

0.4.2 — Fix version display (for real this time)

Version in panel title now actually resolves on CF builds — the 0.4.0 panel-title check used a bare "@project-version@" literal in ConfigUI.lua to detect unsubstituted dev builds. The CF packager's keyword substitution runs across .lua too (not just .toc), so on a packaged release that literal got replaced with the real version (e.g. "v0.4.1"), turning the guard into if v == "v0.4.1" then return "(dev)" end — self-defeating. The placeholder is now assembled at runtime from two strings, so the packager's text replacement leaves it intact. 0.4.1's C_AddOns.GetAddOnMetadata fallback was correct as defensive code but did not address this bug.

0.4.1 — Fix version display

Version in panel title now resolves — the 0.4.0 lookup used the global GetAddOnMetadata, which has been moved to C_AddOns.GetAddOnMetadata on modern clients (including MoP Classic 5.5.0). The global was nil, so the title fell back to (dev) even on a properly-packaged release. Now prefers C_AddOns.GetAddOnMetadata and falls back to the global.

0.4.0 — Tier token data

Tier tokens populatedData.TierTokens now covers Pandaria raid tier sets T14 (Mogu'shan Vaults / Heart of Fear / Terrace of Endless Spring), T15 (Throne of Thunder), and T16 (Siege of Orgrimmar), including the Heroic Garrosh "Essence of the Cursed" wildcard tokens. 111 item IDs, organized by Data.TierTokenGroups (Vanquisher / Protector / Conqueror).

Tier token ilvl in trace — the in-game tooltip on a tier token doesn't reveal the ilvl of the gear it redeems for. The decision trace now includes that ilvl alongside every TIER_TOKEN_MATCH, TIER_TOKEN_MISMATCH, and TIER_TOKEN_NEED factor, so /sl eval <itemLink> makes the LFR/Normal/Heroic difference visible.

Options panel sync fix — the modern Settings canvas API doesn't auto-call panel.refresh() on show, so widgets sat in their default visual state on every login and clicking Okay parsed an empty overrides edit box, wiping the saved overrides table. The panel now refreshes on OnShow. Saved data itself was always intact; only the UI was out of sync.

Version in panel title — the options panel title now shows the addon version from the .toc, with a (dev) marker for unsubstituted @project-version@ or non-semver values, so it's obvious when running a local build vs a tagged release.

0.3.1 — Drop humanize delay

Removed the 0.8–2.2s pre-roll delay (and its config block). It served no real purpose — the loot client doesn't care how fast a roll arrives, and the delay only added latency between item drops and the addon's response. Rolls are now submitted as soon as the decision is made.

Also: added a brief Contributing note to the README.

0.3 — Auto-confirm

Auto-confirm BoP popup (new) — when the addon submits a roll on a bind-on-pickup item and the client prompts "looting this will bind it to you, do you want to loot it?", the addon now accepts the prompt automatically. Only rolls the addon itself submitted are confirmed; bind dialogs from picking up unrolled loot remain the player's responsibility. Test mode is unaffected (no real roll → nothing to confirm).

Off-spec equipment set dropdown fix — the "Off-spec equipment set" dropdown was empty even when equipment sets existed. The legacy GetNumEquipmentSets global was removed in Legion (7.0.3) and MoP Classic 5.5.x runs on the modern client, so the addon now uses the C_EquipmentSet namespace for both enumeration and per-slot lookups.

0.2 — Stellar Loot

Off-Spec Support (new) — opt-in path for hybrids (e.g. Holy paladin / Prot off-spec). Picks up the off-spec primary stat via auto-detect (inactive talent group) or a manual override, and compares ilvl against an in-game Equipment Manager set you nominate. Without a set, off-spec items fall through to Greed with a clear trace reason.

Disenchant dropped — DE was outside the four-action mental model (Need / Greed / Manual / Pass). All DE code paths, the preferDEoverGreed config flag, the UI checkbox, the override action, and the slash references are gone.

Slash commands are /stellarloot (or /sl).

0.1 — Initial release

First public release. Automatic Need / Greed / Pass / Disenchant rolls for World of Warcraft Mists of Pandaria Classic (5.5.x).

Decision pipeline considers, in order: per-item overrides → master toggle → quality threshold → roll-option availability → class equip-ability → preferred armor type → tier-token class match → primary stat match → ilvl upgrade vs equipped → default Greed (with optional Disenchant preference).

Configuration UI

  • Account-wide settings by default with optional per-character overrides.
  • Quality and ilvl-upgrade filters with individual disable toggles.
  • Fallback action selector (Greed / Pass / Need / Manual) for when item info doesn't load before the roll timer.
  • Per-item overrides editor.
  • Log sub-panel with embedded scrolling history, clickable item links, and a verbose toggle that expands each entry's full factor trace.

Other behavior

  • Humanize delay (0.8–2.2s default) before rolling, capped to never miss the roll window.
  • Defers decisions until item info loads; safety-falls-back to the configured action near roll expiry.
  • Persistent decision log (200-entry circular buffer, account-wide).

<sub>0.1 was published under the working name "AutoRoll" before the rename to Stellar Loot in 0.2.</sub>