Releases: lawrab/Quiver
Releases · lawrab/Quiver
Release list
v0.6.6
Quiver
v0.6.6 (2026-07-08)
Full Changelog Previous Releases
- v0.6.6: Anniversary 2.5.6 compat + menu/macro fixes
- Bump Interface to 20506 for the TBC Anniversary 2.5.6 client update
- Left-click on aspects/pet/traps/tracking menu buttons now casts
immediately (previously only right-click cast, left-click selected);
stings menu still requires selecting first since accidental sting
swaps mid-fight are costly - Bestial Wrath macro's Intimidation line now only fires with a valid
hostile target, avoiding an "Invalid target" error when pressing BW
with nothing targeted - BW macro rebuilds are deferred until combat ends instead of silently
failing, since EditMacro is combat-locked - Fixed pet revive/mend macro conditional so the dead-check applies to
the pet instead of the player
v0.6.5
Quiver
v0.6.5 (2026-06-11)
Full Changelog Previous Releases
- v0.6.5: Fix menu left-click casting spells instead of selecting
- Clicking a spell in the stings, aspects, pet, traps, or tracking menu
was immediately casting it rather than just selecting it for quick-cast.
Left-click now only selects; right-click casts immediately as intended.
- Clicking a spell in the stings, aspects, pet, traps, or tracking menu
v0.6.4
Quiver
v0.6.4 (2026-06-10)
Full Changelog Previous Releases
- v0.6.4: Aspect swap improvements
- The small badge icon on the aspects button now correctly updates while
in combat to show which aspect you would switch to on right-click - Right-click aspect swap now works in both directions during a fight —
you can toggle back and forth between your two selected aspects as many
times as needed, not just once per combat
- The small badge icon on the aspects button now correctly updates while
- Aspect swap badge + bidirectional in-combat swap
- Swap badge on the aspects orbit button now updates immediately when
aspects change in combat (SetTexture is not combat-restricted) - Right-click swap now works in both directions during combat using
/castsequence reset=combat with the ! prefix; [stance:N] does not
apply to hunter aspects in TBC Anniversary (they are buffs, not
shapeshifts), so the sequence is the only viable in-combat mechanism - Cache shapeshift form index per aspect name in DetectCurrentAspect
for future reference - Fix unused CONTENT_H variable in Help.lua
- Add GetPetActionInfo, IsMounted, TogglePetAutocast to luacheckrc
- Swap badge on the aspects orbit button now updates immediately when
v0.6.2
Quiver
v0.6.2 (2026-06-09)
Full Changelog Previous Releases
- v0.6.2: In-game help window
Add a six-page help reference accessible via the new "?" button in the
Settings panel header. Topics covered:- Getting Started: sphere overview, how to open settings, the seven orbit buttons
- Pet & Tank Mode: happiness ring, feeding, tank mode sync behaviour and mounted limitations
- Aspects & Tracking: quick-switch, sphere colour coding, badge system
- Stings & Traps: mutual exclusion rules, trap types, sting macro auto-update
- Macro Generator: all four macros explained, BW + tank mode interaction, MD focus targeting
- Alerts & Tips: sound alerts, ammo counter, general hunter tips
The window is draggable, dismisses on Escape, and remembers which page you
were on when you reopen it.
v0.6.1
Quiver
v0.6.1 (2026-06-09)
Full Changelog Previous Releases
- v0.6.1: Tank mode fixes and opener macro improvements
Tank mode orbit button:- Fixed missing icon when logged in without a pet — now shows the Growl/taunt
icon as a placeholder until a pet is summoned - Fixed BW macro not updating on dismount — mount/dismount now correctly pushes
the saved tank mode preference out to the macro rather than overwriting it - Fixed Growl sync on PostClick — reads actual Growl autocast state after toggle
instead of blindly flipping the flag, keeping display and macro in sync even
after a pet re-summon resets the action bar - Tooltip now shows "Not usable while mounted" warning when the player is mounted
- Removed garbled UTF-8 characters from tooltip (en-dash rendered as junk)
Opener macro: - Added Auto Shot as a selectable opener option — useful for a passive pull that
starts the auto-shot cycle without burning a GCD
- Fixed missing icon when logged in without a pet — now shows the Growl/taunt
- Fix pet food selection clearing on reload
GetItemInfo returns nil during PLAYER_ENTERING_WORLD before the item cache
warms, causing GetSuitableFood to return empty and the saved food to appear
incompatible. Move the food compatibility check from UpdateState into the
UNIT_PET handler so it only runs on genuine pet summons, not on world entry. - v0.6.0: Pet tank mode, macro generator overhaul, and 7-button orbit
Tank mode:- New dedicated orbit button at 0° (right of sphere); toggles Growl autocast
via /click PetActionButtonN RightButton to avoid ADDON_ACTION_FORBIDDEN - Growl autocast state is authoritative — petTankMode syncs from it on every
RebuildAll and on PET_BAR_UPDATE (covers mount/dismount bar resets) - BW macro conditionally includes /cast [known:Intimidation] Intimidation when
tank mode is on; auto-rewrites in-book macro on every toggle
Macro generator: - Removed FD Trap macro (single-spell, no composition value)
- BW macro drops the follow-up shot — you are already mid-rotation when
pressing BW; Intimidation is the only non-obvious addition - Open macro shot picker gains Hunter's Mark and Concussive Shot as options
- Removed separate bw_shot and fdtrap saved settings
Orbit layout: - 7 buttons evenly spaced at 360/7 ≈ 51.4° intervals; existing buttons shift
~10° each, near-vertical buttons (aspects 103°, stings 257°) continue to
use the existing screen-edge expand direction detection
- New dedicated orbit button at 0° (right of sphere); toggles Growl autocast
v0.5.0
Quiver
v0.5.0 (2026-06-08)
Full Changelog Previous Releases
- v0.5.0: Stings switcher, macro generator, combat fixes, and UI improvements
Stings switcher- New orbit button at 270° (bottom of sphere) for quick sting selection
- Left-click opens picker: Serpent, Viper, Scorpid, Wyvern Sting
- Right-click casts the selected sting
- Automatically creates and maintains a "Quiver: Sting" macro in the macro
book — drag it to your bar once and it stays synced to your selection
Macro generator (experimental — feedback welcome!) - New Macros tab in settings (Alt+Right-click sphere)
- Generates four hunter macros with configurable options:
- Quiver: Open — pet attack + opening shot (shot selector)
- Quiver: FD Trap — Feign Death + trap (trap selector)
- Quiver: BW — Bestial Wrath + Intimidation + shot (shot selector)
- Quiver: MD — Misdirection on focus (no options)
- All macros include #showtooltip so cooldowns show on your bars
- Quiver: Open uses /petfollow before /petattack to avoid the toggle-cancel
issue when the pet is already moving to the target - Create / Update and Delete All buttons to manage macros from the panel
- Macros are early-stage — if something doesn't work for your spec or
playstyle please share feedback so we can improve the templates
Settings panel - Split into two tabs: Bindings (left/right click) and Macros (alerts +
macro generator) — panel is now significantly less busy
Menu improvements - All orbit menus now expand away from the nearest screen edge automatically
— menus on the right half of the screen pop left, left half pop right - Side buttons (pet, food, traps, tracking) always expand away from the
sphere center regardless of screen position; only top/bottom buttons
(aspects, stings) adapt to screen edge - Menus rebuild on sphere drag-stop so expand direction stays correct after
moving the sphere
Combat lockdown fixes - SetFrameStrata, EnableMouse, SetButtonState, StartMoving, and
ClearAllPoints/SetPoint calls on secure frames are now all guarded against
combat lockdown — no more ADDON_ACTION_BLOCKED errors when opening menus,
taming pets, or dragging the sphere during combat
Auto-shot bar - Moved 40px below sphere bottom to clear the new stings orbit button
- Fix combat lockdown errors when taming pets and switching aspects
- Guard RebuildFoodPicker with InCombatLockdown() so taming a pet mid-combat
no longer triggers ADDON_ACTION_BLOCKED on ClearAllPoints/SetPoint - Defer food picker rebuild to PLAYER_REGEN_ENABLED so new pet state is
applied correctly once combat ends - Update PLAYER_REGEN_ENABLED to refresh all menus (aspects swap macro, etc.)
not just the sphere on-click handler - Fix happiness sound playing on every poll tick instead of only on transition
to unhappy - Clear saved food selection when a new pet type is tamed (different pet types
accept different foods) - Aspects orbit button icon now updates immediately in combat via
SetNormalTexture (not combat-restricted); attribute/macro deferred - Add Beast Lore to the pet radial menu
- Guard RebuildFoodPicker with InCombatLockdown() so taming a pet mid-combat
- Fix menu blocker strata and clean up luacheck warnings
- Fix blocker frames staying at DIALOG strata when menus are closed,
causing them to eat mouseovers and clicks over the bag UI - Add files["tests/"] override in .luacheckrc so test stubs can write
WoW API globals without false read-only warnings - Fix unused args and bare global assignments in test specs
- Fix blocker frames staying at DIALOG strata when menus are closed,
v0.4.1
Quiver
v0.4.1 (2026-06-01)
Full Changelog Previous Releases
- v0.4.1: Bug fixes, sound alerts, and tracking indicator
- Fix ghost clicks on hidden orbit buttons (blocker frame was incorrectly hidden)
- Fix aspect badge not hiding when no badge icon is set
- Fix right-click macro firing alongside Revive Pet when pet is dead
- Fix orphaned tracking call on sphere rebuild
- Add sound alerts for low ammo and unhappy pet (configurable in settings)
- Add tracking indicator icon on tracking orbit button
- Add busted test suite (35 tests across Ammo, Aspects, Pet, Traps)
- Add busted test suite: 35 tests across Ammo, Aspects, Pet, Traps modules
Includes wow_stubs.lua and loader.lua for sandboxed WoW API simulation.
All global overrides use _G.X to work correctly under busted's setfenv sandboxing.
Co-Authored-By: Lawrence Rabbets lrabbets@gmail.com - Sounds, tracking indicator, and config panel toggles
Sounds:- Ammo low: plays sound kit 8959 (raid warning bell) when crossing threshold
- Pet unhappy: plays sound kit 618 when happiness drops to 1
- Both gated behind db.profile.sounds.* so the setting actually works
- Add PlaySound/SOUNDKIT to luacheckrc
Config panel: - Add "Sound alert when ammo is low" checkbox
- Add "Sound alert when pet is unhappy" checkbox
- Expand panel height to fit three notification rows
Tracking indicator: - Tracking:UpdateTracking() now calls Sphere:UpdateTrackingIndicator()
- UpdateTrackingIndicator() updates QuiverBtn_tracking icon with the
texture path from GetTrackingTexture() so the orbit button always
reflects the active tracking type at a glance - Falls back to Track Beasts hint icon when no tracking is active
- Add luacheck, fix four code-review bugs, clean up warnings
luacheck setup:- Add flake.nix dev shell (lua5_1 + luacheck)
- Add .luacheckrc with full WoW API globals list
Code review bug fixes: - Sphere: add /stopmacro guard before user rightMacro in pet-emergency
macro so it doesn't fire alongside Revive Pet when pet is dead - Menus: restore blocker:Show() in PopulateMenu and HideAll so alpha=0
orbit buttons don't ghost-fire their macros (blocker at DIALOG strata
intercepts clicks; alpha=0 alone does not) - Menus: hide swap badge when GetSpellInfo returns nil icon to prevent
stale texture from a previous aspect pair staying visible - Menus: call UpdateOnClick() after RebuildAll() in the rebuildPending
path, matching the non-combat SPELLS_CHANGED handler
Luacheck warning cleanup (0 warnings / 0 errors): - Remove empty if shells around commented-out sound calls (Ammo, Pet)
- Remove unused INDICATOR_SIZE constant (Sphere)
- Rename unused castGUID arg to _ (AutoShot)
- Rename self in SetScript callbacks to frame/_ to eliminate shadowing
- Fix post-flight pet feed icon, sphere right-click macro, and orphaned tracking call
- Feed orbit button now shows Feed Pet icon when no pet is summoned
- Sphere right-click macro rebuilt on SPELLS_CHANGED so Call Pet guard
is set after spell book populates (fixes wrong action firing after landing) - Pet PLAYER_ENTERING_WORLD moved to raw frame to avoid AceEvent collision
with Menus overwriting the handler - Remove orphaned UpdateTrackingIndicator call in Tracking.lua
v0.4.0
Quiver
v0.4.0 (2026-05-30)
Full Changelog Previous Releases
- v0.4.0: Pet emergency right-click, ring pulse, death notification
Right-click the sphere to call or revive your pet in any situation:- Pet dead → Revive Pet
- No pet → Call Pet
- Pet alive → configured right-click action
Uses WoW macro conditionals baked at setup time so the correct action
fires even inside combat lockdown, without needing attribute updates
when the pet dies mid-fight.
Pet ring around the sphere now pulses red when the pet is dead and
amber when no pet exists (requires Call Pet to be known), making the
state visible at a glance without opening any menu.
Sphere tooltip and PostClick error message both update dynamically to
reflect the current pet state.
Chat notification fires when the pet dies pointing players to the
sphere right-click; can be toggled off in the config panel via a new
"Notify in chat when pet dies" checkbox.
- Aspects orbit button: right-click smart swap between two selected aspects
- Right-clicking the aspects button now toggles between the last two
aspects selected from the menu. If you are already in the selected
aspect it casts the other, otherwise it restores the selected one. - Macro is pre-baked out of combat and refreshed on aspect change and
PLAYER_REGEN_ENABLED so it always reflects current state. - Small corner badge on the aspects orbit button shows the swap-target
icon at a glance; button icon tracks the currently active aspect. - Tooltip hints guide setup: single selection shows "select a 2nd
aspect to enable quick-swap"; both set shows "Hawk / Viper (swap)". - Add /quiver slash command: /quiver reset to reposition sphere,
/quiver config to open settings. - Hidden menu buttons now drop to MEDIUM frame strata so they cannot
intercept mouse events or tooltips on bag frames behind them; raised
back to DIALOG when a menu is opened.
- Right-clicking the aspects button now toggles between the last two
v0.3.1
Quiver
v0.3.1 (2026-05-28)
Full Changelog Previous Releases
- Bump version to 0.3.1
- Auto-shot bar: end caps, haste color, fix colour on target switch
- Add gold vertical tick marks at each end of the bar so the full
range is always visible - Bar turns cyan when Rapid Fire or Quick Shots is active; reverts
to gold when the buff falls off - Haste detection polls UnitBuff every 0.25s inside Tick() instead
of using UNIT_AURA, which fires too frequently and causes GC churn - START_AUTOREPEAT_SPELL now checks HasHasteBuff() directly so the
colour is correct even if Quick Shots was already up when you tab
to a new target
- Add gold vertical tick marks at each end of the bar so the full
v0.3.0
Quiver
v0.3.0 (2026-05-28)
Full Changelog Previous Releases
- Bump version to 0.3.0
- Widen auto-shot bar to 102px and lower position by 4px
Bar now spans from the traps button center (210°) to the food button
center (330°) at radius 59 — both x-extents are ±51px. Offset changed
from -4 to -8 to sit a smidge lower below the sphere. - Auto-shot bar: cyan color on speed proc, gold when normal
Bar turns cyan when UNIT_ATTACK_SPEED fires with a faster speed (Rapid
Fire, haste trinkets, Bloodlust etc.) and reverts to gold when speed
returns to normal. speedBoosted flag resets on START_AUTOREPEAT_SPELL
and PLAYER_ENTERING_WORLD so the color is always in sync. - Add auto-shot swing timer bar
Gold bar below the sphere tracks time to next Auto Shot. Counts down
from weapon speed to 0, resets on each Auto Shot proc. Clips to 0.5s
window when Aimed Shot begins casting. Hides outside combat or without
a target. Movement detection uses PLAYER_STARTED/STOPPED_MOVING events
to avoid per-frame GetUnitSpeed; module reference cached as a file-local
upvalue to keep the OnUpdate path allocation-free. - Remove Stings module; fix aspect color update delay
Stings is unused and unlikely to be needed soon — removed from toc, Core,
Sphere (sting bar + UpdateStingDisplay), and deleted the module file.
Aspect delay fix: add UNIT_SPELLCAST_SUCCEEDED to the raw event frame.
Aspects are instant casts so this fires immediately when an aspect is cast,
catching the change before UNIT_AURA eventually fires for some other buff.
UPDATE_SHAPESHIFT_FORM and UNIT_AURA are kept as fallbacks. - Aspects: use raw WoW frame for event registration to avoid AceEvent collision
Quiver:RegisterEvent keys handlers by (addon_object, event). Stings registers
UNIT_AURA after Aspects, silently replacing it. Aspects now uses a dedicated
CreateFrame to register both UNIT_AURA and UPDATE_SHAPESHIFT_FORM independently,
so both events fire regardless of registration order.
Restore Aspects:Disable() in Core:Disable() to unregister the raw frame events. - Fix aspect detection: shapeshift API + correct event, fix UNIT_AURA handler collision
Two root causes:- AceEvent-3.0 keys handlers by (addon, event). Stings:Enable() registers
UNIT_AURA after Aspects:Enable(), silently replacing Aspects' handler.
Aspects now uses UPDATE_SHAPESHIFT_FORM instead, which doesn't conflict. - GetShapeshiftFormInfo returns (icon, active, castable, spellID) — no name.
Previous UnitBuff scan was looking at buff auras, which may not include
aspects (they are shapeshifts in TBC). Detection now uses GetShapeshiftForm +
GetShapeshiftFormInfo + GetSpellInfo to resolve the active aspect by spell ID,
with a UnitBuff fallback for clients where aspects surface as regular buffs.
- AceEvent-3.0 keys handlers by (addon, event). Stings:Enable() registers
- Fix aspect detection event and food orbit count not updating after feeding
Aspects: replace UPDATE_SHAPESHIFT_FORM with UNIT_AURA (aspects are regular
buffs in TBC Anniversary, not shapeshifts, so the shapeshift event never
fires). Remove the prev != current guard in DetectCurrentAspect so
UpdateColor is always called and the no-aspect pulse fires on load.
Food orbit counter: split BAG_UPDATE_DELAYED into two handlers. BAG_UPDATE
(fires per slot, cheap RefreshFoodOrbitCount) covers the orbit count when
the picker is closed; BAG_UPDATE_DELAYED (fires once, expensive GetSuitableFood
scan) covers the picker refresh when it is open. This fixes the count not
updating after quick-feeding via the orbit button if BAG_UPDATE_DELAYED was
unreliable in this scenario. - Fix aspect detection: use UNIT_AURA and always refresh sphere color
UPDATE_SHAPESHIFT_FORM does not fire for aspects since they are regular buffs
in TBC Classic Anniversary, not shapeshifts. Switch to UNIT_AURA filtered to
the player unit.
Remove the prev != current guard in DetectCurrentAspect so UpdateColor is
always called after a scan. This fixes the no-aspect pulse not appearing on
load (prev and current were both nil so the guard skipped the update). - Replace Aspects poller and Stings UNIT_AURA with updateInfo-filtered event handlers
Aspects was polling UnitBuff every second via an OnUpdate ticker, generating
15-20 AuraData table allocations/sec that outpaced Lua 5.1's incremental GC.
Stings fired a full UnitDebuff scan on every UNIT_AURA without filtering.
Both now use UNIT_AURA with updateInfo filtering: skip the scan entirely when
the update contains no aspect/sting changes. Falls back to a full scan when
updateInfo is nil (older Classic clients) or isFullUpdate is set.
Added ASPECTS_BY_NAME and STINGS_BY_NAME O(1) lookup tables to replace the
inner ipairs loops in DetectCurrentAspect and ScanTarget.
Removed Aspects:Disable() (no ticker to stop) and the Core:Disable() call. - Fix memory leaks: stop tickers on disable, reuse config panel, drop UNIT_AURA
- Mana/Aspects/Pet tickers stored as self.ticker so Core:Disable() can stop them
- Config panel built once and refreshed on open rather than recreated each time
- UNIT_AURA dropped for aspect detection (10-20 fires/sec in combat, each allocs
an updateInfo table); 1s poll already handles it - BAG_UPDATE -> BAG_UPDATE_DELAYED (fires once after bag settles, not per slot)
- UpdateTriggerReadiness guards SetScript with _lastSelected to avoid closure churn
- Aspects:DetectCurrentAspect gates UpdateColor on actual aspect change
- TENTHS_STR lookup table replaces string.format in 0.1s trap ticker hot path
- GetContainerItemID fast path in pet food scan before full GetContainerItemInfo
- Reduce trap cooldown ticker allocation rate
cdTicker: use 0.5s interval when trap menu is closed (was always 0.1s).
Menu-open path keeps 0.1s for smooth expansion-button text. This cuts
UpdateTrapCooldowns calls from 10/sec to 2/sec when menu is closed.
PopulateMenu: cache b._normalTex = b:GetNormalTexture() after SetNormalTexture.
UpdateTrapCooldowns: use b._normalTex / triggerBtn._normalTex instead of
calling GetNormalTexture() on every tick. On some WoW client builds
GetNormalTexture() allocates a fresh userdata wrapper each call; caching
eliminates that source entirely. triggerBtn._normalTex is initialised lazily
on first UpdateTrapCooldowns call so it works without a Sphere.lua change.
Display text: show tenths only for sub-1s remaining; integer (math.ceil)
above that. string.format is now only called for the last second of a
cooldown instead of the last 10 seconds, reducing string churn 10x. - Trap trigger button: keep countdown live when menu is closed
UpdateTrapCooldowns now manages cdTicker lifetime itself:- If maxRemaining > 0 and ticker is not running, start it (so the trigger
button countdown stays current without depending on SPELL_UPDATE_COOLDOWN
firing between GCDs). - If maxRemaining == 0 and menu is closed, stop it.
HideAll calls UpdateTrapCooldowns after clearing activeMenu so the ticker
restarts immediately if a trap is still cooling, eliminating the freeze-then-
resume gap that occurred when closing the menu while a cooldown was active.
Per-button visual updates remain gated behind menuOpen so the extra ticker
cycles when the menu is closed are cheap (trigger button only).
- If maxRemaining > 0 and ticker is not running, start it (so the trigger
- Fix pet ring visibility; reduce UpdateTrapCooldowns overhead
Sphere.lua: Move petRing from BACKGROUND to BORDER layer. Both petRing and
the sphere bg texture (bg) were at BACKGROUND; draw order within the same
sublayer is non-deterministic so the ring could render behind the sphere.
BORDER is guaranteed to sit above BACKGROUND, making the happiness ring
reliably visible.
Menus.lua: UpdateTrapCooldowns is called on every SPELL_UPDATE_COOLDOWN
(fires frequently in combat) AND every 0.1s when the trap menu is open.
Previously it re-called GetSpellCooldown for each of 5 buttons even though
Traps:UpdateCooldowns had just read and stored that data. Now it reads from
Traps.cooldowns directly. Also gates per-button visual updates (SetText,
SetDesaturated, cdFrame, cdDim, cdText) behind an activeMenu == traps check
so that work is skipped entirely when the trap menu is closed. - Memory: pre-allocate trap cooldown tables and pulse color constants
Traps.lua: Initialize now seeds self.cooldowns with one {start,duration}
table per trap. UpdateCooldowns updates those tables in-place instead of
replacing them on every SPELL_UPDATE_COOLDOWN event. This event fires
every GCD in combat; the old code discarded and re-created 5 tables each
time, generating continuous GC pressure.
Sphere.lua: Define PULSE_COLOR_MANA_LOW and PULSE_COLOR_NO_ASPECT as
module-level constants. UpdateColor (called every second via the aspect
ticker plus on every UNIT_AURA for the player) now assigns these constant
references instead of allocating a fresh {r,g,b} table on each call. - Fix frame memory leak: pool and reuse menu buttons instead of recreating
RebuildAll fires on PLAYER_ENTERING_WORLD, SPELLS_CHANGED, and
PLAYER_REGEN_ENABLED. The old PopulateMenu created ~52 new WoW frames
per call (26 buttons + 26...