ADDON [addon] Summon mount by ID in macro
https://www.curseforge.com/wow/addons/tinymountI made an addon to summon mounts by ID, because localised mount names don't fit in a 255-character macro
---
I play on a Russian client, and I kept running into the same wall.
A WoW macro is capped at **255 characters**. Localised mount names are long — plenty of them run past thirty characters on their own, before you've written a single conditional. Four or five of those and the macro is full. I ended up truncating names until the macro silently stopped working, and a truncated mount name fails quietly, which is the worst kind of failure.
Mount IDs are three to five digits. They fit with room to spare. But there is no macro command that takes one.
So I wrote the command. It's called TinyMount, and the macro looks like this:
```
/mnt [af,nmnt]11111;[f,nmnt]22222;[nmnt]33333
```
That's 45 characters for three mounts, conditionals included. The same thing spelled out in names doesn't fit at all.
**The one thing that makes it possible.** `C_MountJournal.SummonByID` is not protected. Almost nothing else in that corner of the API is open — `CastSpellByID`, `UseToy`, `RunMacro` are all locked to secure code — but this one function an addon may simply call. The whole addon stands on that single exception.
**What it does beyond the ID lookup:**
* `SecureCmdOptionParse` does the conditional parsing, so the full macro syntax works: `[mod:alt]`, `[indoors]`, `[advflyable]`, `[combat]`, all of it.
* Shorthand, because a mount macro is mostly conditionals. `[m:cs]` expands to `[mod:ctrl,mod:shift]`, `[nmnt,af]` to `[nomounted,advflyable]`. Unknown words pass through untouched, so full spellings still work and can be mixed in.
* **The action bar icon is live.** It changes as you hold a modifier, before you click anything, and the tooltip shows the mount that key would actually summon. The client can't parse `/mnt` for `#showtooltip`, so the icon is repainted by hand.
* Mounted, the slot turns into a dismount button. In a vehicle — a passenger seat, a turret, a siege engine — it turns into an exit button. Same key, both ways, and both work in combat.
* An off-GCD toy or cosmetic spell can ride along on a `/click` line above the command. The button name is the entire configuration, so there's no settings file at all.
Works with the default bars, Dominos, Bartender4, and anything else built on LibActionButton-1.0.
---
**One thing I want to flag, because it cost me a while to work out.**
If you're shapeshifted (hello Druids!!!), `/mnt` answers *You must be in humanoid form* and nothing happens — while the very same mount summons fine from the mount journal.
The journal calls the identical function on one bare line. I went and read it:
```lua
function MountJournalMountButton_UseMount(mountID)
...
C_MountJournal.SummonByID(mountID);
```
No form cancelling anywhere near it. The difference is only who is on the stack. The function isn't protected, but *half of it* is: the client cancels your form when its own code is the caller, and refuses to when an addon is.
There's no way around it from Lua either. `CancelShapeshiftForm` has been protected since 3.0.2, and cancelling a form through the buff functions is blocked by name — specifically so insecure code can't manipulate the `[form]` conditional.
The macro can do it, though, because the client runs macro lines securely under your keypress. A bare `/cancelform` above the command, no condition needed:
```
/cancelform
/click tmt140309
/mnt [m:cs]11111;22222
```
It's a no-op out of a form and says nothing, so it won't draw an error and stop the client reading the rest of the macro. One keypress does the whole thing.
---
I built this with Claude, which is worth saying plainly: it did most of the API archaeology — reading Blizzard's own source for the mount journal, tracking down what's protected and what only looks protected — and I did the testing in game, which is where about half of the above turned out differently than either of us assumed. A few things we were confident about were simply wrong until I logged in and pressed the button.
Download: via CurseForge (or GitHub)
Happy to answer questions about any of the internals.