2.8.7
What's new
SlotCast
2.8.7 (2026-10-04)
Full Changelog Previous Releases
- Add CurseForge project ID to the TOC
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Add project logo; keep art/ out of the packaged addon
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Add tag-triggered packager workflow for CurseForge releases
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Restore the Author line
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Ignore dist/
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Drop the Author line from the TOC for public release
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Add WoW Forever's interface version (16001) to the TOC
A Forever beta update started rejecting SlotCast as incompatible, even with
"Load out of date AddOns" on: the TOC listed only retail versions newer than
the client. 2.8.7.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Switch to the spellbook tab after opening Click Bindings
WoW Forever's beta opens the spells window on Talents whichever way Click
Bindings is opened, leaving nothing to drag spells from. Calling
PlayerSpellsUtil.OpenToSpellBookTab() afterwards was confirmed in game to
fix it, and is a no-op where the bug is absent. 2.8.6.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Open Click Bindings via ToggleClickBindingFrame first
Blizzard's own opener load-on-demands the UI and needs no chat-box
borrowing. It toggles, so an already-open window is detected first rather
than closed. /clickcasting and the frame pokes remain as fallbacks. 2.8.5.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Offer rank/max for the top rank too; re-check ranks when a spell is learned
A slot holding your best rank now gets the same R3/max toggle as a lower
rank: identical today, but R3 stays on Rank 3 and max moves to Rank 4 once
it is learned. The rank verdict cache was never wiped, so learning a rank
would not have been noticed until /reload. Bump to 2.8.4.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Show the highest rank on the rank button instead of "-"
A slot holding your best rank greyed out with a "no ranks" tooltip, which
read as broken. It now shows the rank (e.g. R3), still disabled, and says
it's the same spell as max until a higher rank is learned. Bump to 2.8.3.
Also corrects the backstop comment: the Forever probe (1.60.1) shows the
name test works there; Rank 2 resolved to its own id.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - probe: trace the rank decision for each bar spell
Prints SpellRank, what the bare name resolves to and its subtext, and the
running version, so a greyed-out rank button points at the test that failed.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Bump version to 2.8.2
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Detect lower ranks by the slot's spell id, not just the name parser
WoW Forever resolves "Healing Wave(Rank 3)" to the top rank's id, so the
name test called every rank flavour text and a Rank 3 slot cast max rank
with the rank toggle hidden. A slot holding a different spell than the bare
name resolves to, with a different rank subtext, is now a real rank.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com - Only defer, and only warn, when something actually changed
"binding change held until you leave combat" fired on any refresh that
happened during combat, and plenty of events land there for reasons
unrelated to bindings: roster updates, spell overrides, macro edits. The
message was accurate about the deferral and wrong about the cause.
DoRefresh now builds the plan first -- building only reads, so it is safe
in combat -- and compares a sorted signature of it, plus the settings
that affect frame writes, against what was last applied. Identical means
return silently. Nothing is deferred and nothing is announced unless the
result would genuinely differ.
Also skips the secure writes entirely out of combat when nothing changed,
and adds /slotcast quiet for anyone who wants the notice gone regardless.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Add bar click labels, enemy-frame skipping, and a stop-casting option
Three opt-in behaviours:- Labels.lua draws each slot's click on the action button itself, so the
bar documents its own grid. Decorative only -- no attributes, no
secure code -- and the font falls back if the narrow one is missing. - Enemy-ish frames (target, focus, boss, arena) can be left alone, since
a heal aimed at a boss frame burns a click and sometimes a global.
Excluded frames are actively restored, so the toggle takes effect at
once rather than at the next reload. - /stopcasting can be prepended so a click-cast interrupts the cast in
progress instead of being swallowed by it.
Clique ships eight per-group frame toggles; one switch covers the case
people actually have and costs a fraction of the panel space.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- Labels.lua draws each slot's click on the action button itself, so the
- Stop the recommendation callout clipping its own text
The box was sized for two lines and the text ran to three, so it cut off
mid-word. Box and label are taller, everything below shifts to match,
and the copy is trimmed to two lines -- the reasoning already sits in
the alignment line directly beneath it and in the Map button's tooltip,
so the callout only needs to be the nudge.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Make the vertical-bar recommendation read as one
A tip set in the same grey as the surrounding explanation is not a tip.
The horizontal-bar nudge and the reshaped-bar warning now sit in a
tinted callout with a coloured edge -- amber for the recommendation, red
for the warning -- and lead with the problem before the fix.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Give the panel room, and lead the grid with what it means
The two blocks that grow -- the warning list and the conflict list --
were spaced for their empty state, so a couple of messages ran into the
section below. Both now have room to grow into and a fixed height so
they clip rather than overlap. Wrapped text gets line spacing, and the
hints are shortened, with the detail left in the tooltips where it
already was.
The line describing what the grid means sat below the grid, which is the
wrong order: it now reads "Current grid alignment: 3 wide x 4 tall.
Columns are Left / Middle / Right; rows are none / Shift / Ctrl / Alt"
directly above the picture it describes, under the vertical-bar tip.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Open Edit Mode rather than rewriting the user's layout
Adds an Open Edit Mode button next to the grid controls, and a probe
section reporting which Edit Mode APIs exist so the question of whether
orientation is settable from code can be answered with evidence.
Opening rather than setting is a deliberate choice independent of what
the API allows: a bar's orientation lives in the player's saved UI
layout, which is shared across characters and often carefully arranged.
Rewriting that to suit one addon's preferred grid is not a trade an
addon gets to make on someone's behalf.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Recommend a vertical bar for the grid mapping
Both orientations work, but only one reads well: a vertical bar three
columns wide puts Left / Middle / Right across the top and the modifiers
down the side, matching how a mouse is laid out. A wide bar puts the
mouse buttons on the rows, so left and right run downwards -- correct,
and confusing to look at.
Say so where it is useful: in the slot hint, in the Map button tooltip,
and as a prompt on the preview itself when the bar is wider than it is
tall. The README leads with it.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Draw the click mapping, and warn when the bar was reshaped
Reported symptom: switching a bar from vertical to horizontal swaps
left and right clicks. That is the mapping working as designed and being
impossible to reason about -- the shape change moves every slot to a
different cell AND flips which axis carries the mouse buttons, so the
same spell lands on a different click.
Explaining that in prose did not land twice, so draw it: a grid of cells
under the slot list showing the click each position gets, read from the
live bindings rather than recomputed so the picture cannot disagree with
the behaviour. Flip the bar and the picture flips with it.
Also remember the shape a mapping was made for, and say plainly when the
bar no longer matches it, instead of leaving it looking like the
bindings scrambled themselves.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - State the whole grid mapping, not just which axis wins
Two different Edit Mode settings can produce the same shape with the
slots filled in differently inside it: horizontal with 4 rows and
vertical with 3 rows are both 3x4. The mapping is positional, measured
from where buttons actually sit, so both map correctly -- but "columns
are buttons" does not tell anyone what a click will do.
The panel now spells it out: "3 wide x 4 tall - columns are Left /
Middle / Right, rows are none / Shift / Ctrl / Alt", following the
L/M/R order setting. The probe prints the click each slot ended up with
alongside its cell, so the result can be read off rather than inferred.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Open Click Bindings through the chat parser as a last resort
/clickcasting works when typed but is not a SLASH_ global on Forever, so
the SlashCmdList lookup found nothing and the button did nothing.
Try SlashCmdList, then SecureCmdList, then hand the text to
ChatEdit_SendText exactly as if it had been typed. The parser knows
about commands that are not exposed as globals at all, which is why
typing it works when looking it up does not.
The probe now reports which route a command was found on.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Work out grid orientation instead of asking about it
The columns/rows toggle asked the user to answer something the addon
already had the data for: GridLayout returns the shape, so orientation
was there all along.
Mouse buttons are scarce (three comfortable, five at most) and modifier
combinations are plentiful (eight), so the shorter axis carries the
buttons. That reads a 3-wide and a 3-tall bar correctly with no setting.
The toggle becomes a label that states what was picked, and
/slotcast grid cols|rows forces it.
Shapes with no usable axis -- a single line of twelve, or a grid too big
on both sides -- now map in reading order rather than being skipped,
which is a case the old axis-only logic handled badly.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Explain the Click Bindings handoff with a dialog
Clicking the Target or Unit menu row now opens WoW's Click Bindings and
puts a dialog in front of it saying what to do there: bind ONLY Target
Unit Frame and Open Context Menu, then Save. Without that, landing in an
unfamiliar window with no explanation is its own kind of broken.
The warning against binding spells there matters as much as the
instruction -- two systems on one click is the failure this whole area
has been about.
Dialog is hand-rolled rather than StaticPopup, for the same reason as
the rest of the UI, and remembers being dismissed. /slotcast blizz
manual brings it back, since asking for it is an explicit request.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Open Blizzard's click bindings via /clickcasting
Guessing at frame names was the wrong approach: that UI has been rebuilt
more than once, while the slash command has not. Look the command up in
SlashCmdList by its text and invoke whatever handler the client filed it
under, falling back to the frame candidates only if that fails.
The printed steps now name /clickcasting too, so the manual route works
even when nothing can be opened programmatically.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Show Blizzard's Target/Unit menu bindings instead of offering our own
Those two actions belong to the game's click-binding system now. Binding
them in SlotCast silently did nothing AND blocked the binding that would
have worked, which is the worst of both.
So SlotCast stops competing: on a client with that system, the Target
and Unit menu rows become read-only, showing what is actually bound
there, and clicking one opens Blizzard's UI and prints the steps.
"/slotcast blizz off" takes them back for a client where that system
does not exist.
Removes the profile-writing path entirely -- 103 lines that never took
on 12.1 -- along with the modifier-bitfield capture that only existed to
feed it. A read-only mirror of the real setting is both honest and
simpler than trying to own someone else's config.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Add a manual route for the unit menu, and verify the automatic one
Writing Blizzard's profile is the convenient path, not the reliable one,
and it is still not taking on 12.1. So make the route that always works
easy to reach: a button that opens Blizzard's Click Bindings UI and
prints the steps, plus /slotcast blizz manual.
SyncDelegated now reads the profile back after writing and reports
failure if the entry did not survive. SetProfileByInfo returning without
error was never evidence that it took, which is why this looked like
silence rather than a refusal.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Hand Target and Unit menu to Blizzard's click bindings
Unit menus moved to C_ClickBindings, which an addon cannot drive from a
secure attribute -- but can write to. So for the actions that system now
owns, write the binding into its profile and stop binding the click
ourselves: our specific attribute would otherwise override the wildcard
one their binding produces, which is the whole reason it looked broken.- The modifier bitfield's encoding is undocumented, so it is captured
from the client via MakeModifiers() at the moment the user holds the
keys rather than reconstructed. - SetProfileByInfo replaces the whole profile, so the current one is
read first and everything that is not ours is preserved. Entries we
wrote are tracked by button+modifiers so they can be removed when a
binding changes. - The sync is idempotent and skips the write entirely when the profile
already matches, so it can run on every refresh without churning
someone else's settings.
/slotcast blizz off|menu|both, or the button in the panel.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- The modifier bitfield's encoding is undocumented, so it is captured
- Say plainly when the unit menu cannot be bound
togglemenu fails on 12.1 as well as menu, so there is no secure action
type left that opens a unit menu: it moved to C_ClickBindings, which an
addon cannot invoke from an attribute.
Detect that and say so in the panel, pointing at Blizzard's own Click
Bindings -- which does support modifiers, and which works on a click
SlotCast leaves unbound. A binding that silently does nothing is worse
than an absent one, and it also blocks the binding that would have
worked.
check now lists the surviving menu APIs so a real fix can be based on
what exists rather than on another guess.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Fix Target and Unit menu on 12.1
check on PlayerFrame showed the attributes landing perfectly while the
clicks did nothing, and frame.menu = nil was the giveaway.
"menu" is not a generic action type: SecureUnitButton_OnClick
special-cases it and calls frame.menu(). On 12.1 the frames still carry
"*type2 = menu" but have no menu function -- the real right-click menu
comes from C_ClickBindings -- so the attribute advertises a handler that
no longer exists and the click falls through to a generic handler that
has never heard of "menu". Detection now requires the function, not the
attribute, and falls back to togglemenu. /slotcast menuverb overrides it.
target, focus and assist now always use their macro forms rather than
only on the press stroke. Those built-in action types are vestigial in
the same way -- 12.1 advertises "*type1 = target" while targeting
actually comes from C_ClickBindings -- whereas a macro is plain script
execution and cannot quietly stop being supported. @mouseover is exactly
right for a click binding, since the cursor is over the frame.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - check: report the click handler and Blizzard's click bindings
Attribute readback on 12.1 shows alt-type1/alt-type2 landing correctly
while the clicks still do nothing, so the remaining suspects are
downstream of the write.
"menu" is not a generic action type -- SecureUnitButton_OnClick
special-cases it and calls frame.menu() -- so report which handler a
frame actually uses and whether it has a menu function. Also dump
Blizzard's click-binding profile, which runs on its own path and could
be claiming a combo before ours is consulted.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - check: allow aiming at a named frame
PlayerFrame and the compact party frames come from different templates,
so "works here, not there" is worth being able to point at directly
instead of inspecting whichever frame happens to be sampled first.
Frame names are case-sensitive globals but the slash handler lowercased
the whole message, so the raw argument text is now carried alongside the
lowercased one.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Register arena frames; list managed frames in check
Clique's default frame list has an arena group that ours lacked, so
arena enemy frames were never picked up. The naming has changed across
versions, so try each candidate; absent names cost nothing.
check now lists every managed frame by name and calls out PlayerFrame,
TargetFrame or FocusFrame if they are missing. A binding that works on
party frames but not the player frame is a discovery problem rather
than a binding problem, and the two were indistinguishable from the
symptom.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Show /slotcast check in the copy window too
Both reports now share one window and one display path, retitled per
report and stashed separately (lastProbe, lastCheck) so either survives
a /reload. "chat" as an argument to either still prints inline.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - check: dump raw frame attributes and the config, not just our bookkeeping
Comparing the plan against the frame only proves our writes match our
intent. It cannot show a binding that never reached the config, or a
Blizzard attribute shadowing ours. Dump every type/unit attribute on the
frame for buttons 1 and 2 across all modifier prefixes, plus the raw
binds table, so the failure can be located instead of theorised about.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Keep casts on the press stroke; only the unit menu forces release
Defaulting the whole frame to AnyUp fixed target and menu by giving up
cast-on-press everywhere, which is the wrong trade: those milliseconds
are the reason the cvar exists.
RegisterForClicks is per frame, so the stroke cannot be chosen per
binding -- but target, focus and assist have macro equivalents that run
on either stroke. Emitting those as /target [@mouseover] and friends
when firing on press leaves the unit menu as the only action with no
press-stroke form.
So "auto" (the new default) fires on press unless the unit menu is
actually bound. clicks up/down/both remain as explicit overrides, and a
binding stranded by the current mode is named in the panel, on status,
and by /slotcast check rather than just failing quietly.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Register unit frames for AnyUp, not AnyDown
Click registration followed the ActionButtonUseKeyDown cvar, which
governs ACTION BUTTONS -- not unit frames. Blizzard's unit frames stay
on the up-stroke and so does Clique.
Casting works on the down-stroke, but "target" and "menu" run on the
up-stroke, so registering unit frames for AnyDown left spell bindings
working while silently killing Target unit and Unit menu. Two thirds of
the addon working is what made this hard to see.
Up is now the default. /slotcast clicks down opts back in for anyone who
binds nothing but spells and wants them a few milliseconds earlier; it
warns about the cost.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Add /slotcast check, and detect modified-click hijacks
"The binding does nothing" has two very different causes with identical
symptoms: the attribute never landed, or it landed and something ate the
click. /slotcast check reads every planned attribute back off a live
frame and says which happened.
It also reports the client's own modified-click settings, because those
hijack the unit before any binding runs. SELFCAST defaults to ALT --
exactly the modifier people reach for when they run out of plain clicks
-- and an Alt-bound Target then targets the player instead of the frame,
which reads as "Alt-click doesn't work".
Collisions are surfaced in the options panel too, not just on demand.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Fix Target unit / Unit menu: learn the verbs, and stop the auto-map
overwriting them
Two separate faults, both reported as "target and menu don't work".
The menu verb was wrong. SecureActionButtonTemplate documents
"togglemenu", but real unit frames carry "*type2 = menu" -- handled by
SecureUnitButton_OnClick, not the generic action handler -- so setting
togglemenu produced a click that silently did nothing. Both verbs are
now read off a live frame instead of assumed, so whatever this client
uses to open its own menus is what SlotCast uses.
The auto-map also overwrote them. It clears slot bindings and then
assigns row 1 / column 1 to plain Left and column 3 to plain Right,
which is exactly where Target and Unit menu sit. It now leaves any
combo already holding a unit-frame action alone and names what it
skipped: a deliberate choice outranks a bulk mapping.
Both verbs are reported by /slotcast status and the probe.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Don't bake one person's grid scheme into the auto-map
The auto-map had three assumptions in it that are preferences, not
facts: that columns carry the mouse button, that middle-click sits
between left and right, and that a cell label is worth showing at all.- Which axis carries the button is now a toggle, disabled on a
single-row bar where there is no choice to make. A 3-tall grid wants
the opposite of a 3-wide one. - Mouse button order toggles between L/M/R and L/R/M, since middle-click
is awkward on plenty of mice. - Slot rows show their index again, with the grid cell appended only
when the grid is genuinely two-dimensional. On a plain row of twelve
the cell label was strictly worse than the number it replaced.
Modifier rows keep the canonical none/Shift/Ctrl/Alt order, matching
every keybinding UI in the game.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- Which axis carries the button is now a toggle, disabled on a
- Measure the bar's visual grid and map it onto clicks
Edit Mode bar shapes fill in a different order on different clients, so
a hard-coded fold order would be both unknowable for an unreleased
client and wrong the moment the bar is reshaped.
Instead, read where the buttons actually sit on screen and cluster them
into rows and columns. "Map grid to clicks" then assigns columns to
Left/Middle/Right and rows to none/Shift/Ctrl/Alt, so a 3x4 bar reads
exactly as it looks. Panel rows are labelled with their cell and the
header shows the detected shape; the probe prints the grid as a picture,
which makes a client's fold order obvious at a glance.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - /slotcast opens a standalone window instead of Blizzard's Settings
Settings.OpenToCategory depends on category-id plumbing that has been
rewritten more than once, and it was not opening the panel on 12.1. A
config panel you tweak while watching your unit frames is better off as
a draggable window anyway -- the same reasoning that made the widgets
hand-rolled in the first place.
The panel is now a pure content frame reparented into whichever host is
showing it, so the standalone window and the Settings canvas share one
layout with no duplicate construction. The Settings entry stays
registered for discoverability in the AddOns tab.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Fix the rank guard: compare spell ids, not mere resolution
The previous guard asked whether "Name(Subtext)" resolved to a spell.
Probe output from 12.1 shows C_Spell.GetSpellInfo strips the
parenthetical and resolves the base name, so every flavour subtext on
the client passed -- "Revive Battle Pets(Battle Pets)" included. The
guard failed open on all 8 test cases.
A parenthetical cannot fake changing which spell is named. Both forms
are now resolved and their spell ids compared: different ids mean the
suffix selected a rank, identical ids mean it was ignored.
The only false negative is a slot holding the highest rank, where both
forms name the same spell -- casting rankless there is identical in
effect, so it costs nothing. That asymmetry is what makes id comparison
safe to be wrong about in a way "does it resolve" never was.
Probe prints both ids so the verdict can be checked rather than trusted.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Probe: exercise the rank guard against real subtexts
The rank feature rests entirely on "Name(Subtext)" failing to resolve
for non-ranks, and that assumption was untested. The spellbook walk now
calls the shipping RankedFormResolves on every subtext it finds and
flags a YES loudly: on a rankless client every line must read "no", and
anything else means the guard fails open.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Stop claiming plain left and right click by default
Binding them overrode any Blizzard click binding on those two buttons
while only reproducing behaviour the frame already had: current clients
ship "*type1 = target" / "*type2 = menu" of their own, and a specific
attribute beats a wildcard. Defaults are now empty, so the two systems
coexist until the user deliberately binds a click.
Existing profiles are migrated once, and only if those two entries are
still at the old default values.
Also fixes CopyDefaults resurrecting deleted entries: merging defaults
key-by-key into binds meant clearing a binding came back on next login.
User-edited tables are now seeded only when absent entirely.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Fix four bugs found by the 12.1.0 probe
Probe output from retail 12.1.0 (build 69933) settled several things
that had been read defensively or guessed:- Bars 6-8 are at slots 145-180 on 12.1, not 73-108. The hard-coded
fallback was wrong for this client; the runtime probe is what saved
it. Those three fallbacks are removed rather than corrected -- there
is no safe value to guess -- and an unprobeable bar now reports as
unavailable, since binding the wrong slot is worse than binding none. - "Battle for Azeroth Pathfinder" has the subtext "Rank 2" on retail,
so the digit heuristic alone would have cast a nonexistent
"Name(Rank 2)". A subtext now only counts as a rank if the client can
actually resolve the parenthesised form, which is the real test and
works on rankless and ranked clients alike. - Blizzard's click bindings are wildcard attributes ("*type1 = target"),
which a specific attribute beats -- so SlotCast overrides them rather
than colliding, and nothing double-fires. The old warning was wrong.
Worse, every character ships two Interaction entries for ordinary
target/menu, so it would have cried conflict on every single login. - GetSpellInfo and GetSpellSubtext globals are gone in 12.1; the
C_Spell paths were already the primary and held up.
Confirmed and now documented: ClickBindingInfo fields are actionID /
button ("LeftButton") / modifiers / type, with PetAction=4 added to the
enum handling. TOC interface set to 120100.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- Bars 6-8 are at slots 145-180 on 12.1, not 73-108. The hard-coded
- Fix: LEARNED_SPELL_IN_TAB aborted Core.lua, killing all slash commands
RegisterEvent raises on an unknown event name, and that event was
removed in 11.0 (renamed LEARNED_SPELL_IN_SKILL_LINE). It was added in
the spell-ranks commit, where it took out the registration loop at the
bottom of Core.lua -- and with it the SlashCmdList assignment below.
Every /slotcast command has silently done nothing since.- Events register one at a time under pcall; an absent event costs that
event, not the rest of the file. Both spellbook event names are now
registered and whichever does not exist is dropped. - Slash commands move to the top of Core.lua behind a forward-declared
Dispatch, so diagnostics do not depend on the file they diagnose, and
say so explicitly if Core.lua stopped partway. - /slotcast status reports skipped events.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- Events register one at a time under pcall; an absent event costs that
- Make slash command failures visible instead of silent
Retail swallows Lua errors unless scriptErrors is on, so a module that
did not load looked identical to a command that did nothing: /slotcast
probe nil-indexed ns.Probe and died quietly.- Dispatch runs under pcall and reports its own errors to chat.
- Module access goes through Need(), which names the missing file and
says to recopy the folder. - /slotcast status lists which modules loaded.
- Probe falls back to chat if the copy window cannot be built, and
"/slotcast probe chat" forces that path. - Copy window gets a sized scroll child, SetToplevel and UISpecialFrames.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- Add /slotcast probe: copyable client capability report
Collects the things that cannot be determined outside the game, and
reports absences as loudly as presences: build and WOW_PROJECT_*
constants (scanned, not listed, so an unknown project id still shows),
which bars exist and which slots they drive, every spell API's view of
the spells on the bar, a spellbook walk for rank subtext, whether
ClickCastFrames exists and what is in it, a real unit frame's secure
attributes, and the click-binding profile if there is one.
Copy window is built from plain frames rather than templates, since it
has to work on a client where templates may be missing -- which is the
reason it is being run. Report is also stashed in saved variables so it
survives a /reload. Nothing identifying is collected.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Support Classic-style spell ranks, per slot
Every action slot holds one specific rank, so the binding has to choose
between casting "Renew(Rank 2)" and "Renew". That is a per-slot choice,
not a global one: downranking means wanting Flash Heal at max and
Greater Heal at Rank 3 bound at the same time.- Rank read from the client (C_Spell.GetSpellSubtext, then GetSpellSubtext,
then Classic's two-return GetSpellInfo), never rebuilt -- the word is
localised and the cast parser wants the local one. - A subtext only counts as a rank if it contains a digit, so retail's
non-rank subtexts ("Fire", "Holy") fall back to the rankless cast. - Per-slot toggle in the panel, global default above it, /slotcast rank.
- /slotcast castmode macro switches to "/cast [@mouseover] Name(Rank N)"
if a client's CastSpellByName will not take the parenthesised form.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- Rank read from the client (C_Spell.GetSpellSubtext, then GetSpellSubtext,
- Discover the bar->slot mapping at runtime instead of hard-coding it
Action slot ranges differ between clients, so asking each bar's first
button which slot it drives is the only mapping that ports. Bars the
client lacks are greyed out, and the default source bar falls back to
the highest one that exists.
Also drops "## AllowLoadGameType: mainline" from the TOC, which would
have blocked loading outright on any client reporting a different game
type.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - SlotCast: action-bar-driven click casting for retail WoW
Binds mouse clicks on unit frames to action bar SLOTS rather than to
spells, so whatever is dragged into the slot becomes the binding.- Slots.lua builds a flat {attribute, value} plan for the whole binding
set; Secure.lua hands the same plan to every frame and remembers each
attribute's prior value so removing a binding restores the frame's
original behaviour (plain left-click targeting survives). - Frame discovery via the shared ClickCastFrames registry plus a named
sweep for Blizzard's non-compact frames. - Combat lockdown handled by queueing refreshes for PLAYER_REGEN_ENABLED.
- Conflicts.lua detects overlapping bindings in Blizzard's built-in
Click Bindings, which fire on their own secure path.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
- Slots.lua builds a flat {attribute, value} plan for the whole binding
This mod has no additional files

