Writing macros, a series of lessons (6 of…)

Today, we’re going to learn a few tricks on cheating around that 255 character limit. Mostly that’s shortening things, but there are one or two other ways around it. But before we stretch brain cells today, let’s pick up on another bit of reference work.

Unlike most of the WoW official forums, there is one that is surprisingly heavily moderated. Well, not all of it, but certain threads. I regret – a lot – that Blizzard doesn’t see fit to keep all of them in a single location. But… oh, wait, I’m not being clear.

Go to the UI & Macros Forum of the official forums. Always — ALWAYS — there are two stickied threads among the group. Both are “concise lists” – one of the most recent patch, one of the upcoming patch. Now they’re long and painful because they’re not just macros, they’re ALL the updated commands that can be used by players to do neat and nifty things. For quite some time they’ve been the pet project of Iriel (I say Thank You to Iriel). They’re the result of careful parsing of official announcements here and there plus parsing and testing of actual output. Take a moment to look. At this time, don’t break your brain chasing Frame and other API info, just look at the macro changes. Nifty, huh? As I said, so far I’ve not found a continuous compilation – if I ever do, it WILL be bookmarked. But what we’ve got is a glorious thing.

Oh, I said these two lists are heavily moderated. Most (not all, but a huge quantity) of the flame and garbage posts that figure so prominently in most forums and threads are deleted in these two. It helps a lot. It means you can browse through and get a much higher signal to noise ratio. (Note they’re open, so crap does sneak in – the later in the thread you go, the higher the probability of this happening. Caveat emptor.)

So, we’ve touched on a Most Important Reference, and ended our first digression. Let’s get to the meat of this, shall we?

Let’s start by making a huge – and to be honest, almost unnecessary – macro for show and tell, ok?

#showtooltip
/stopmacro [stance:1]
/cast [modifier:alt, target=player] Greater Heal
/cast [help, target=mouseover] Greater Heal
/cast [help, target=focus] Greater Heal
/cast [help, target=focustarget] Greater Heal
/cast [help, target=target] Greater Heal
/cast [help, modifier:ctrl, target=mouseover] Greater Heal(Rank 2)
/cast [help, exists, modifier:ctrl, target=focus] Greater Heal(Rank 2)
/cast [help, exists, modifier:ctrl, target=focustarget] Greater Heal(Rank 2)
/cast [help, modifier:ctrl, target=target] Greater Heal(Rank 2)
/cast [help, modifier: shift, target=mouseover] Flash Heal
/cast [help, exists, modifier:shift, target=focus] Flash Heal
/cast [help, exists, modifier:shift, target=focustarget] Flash Heal
/cast [help, modifier:shift, target=target] Flash Heal

For those interested, that macro is 778 characters – that includes the 15 carriage returns. Cutting this is obviously necessary.

Now, let’s take just a moment to see what this does.

  • a) If I’m in shadowform, quit doing this. It’s a healer macro, and I don’t want to get out of shadowform for it.
  • b) Cast greater heal normally. Cast downranked if I’m pressing ctrl, and cast flash heal if I’m pressing the shift key.
  • c) If I’m pressing alt, target myself (max-rank GH only). Otherwise, my target priority is: a target my mouse is over if it’s friendly; my focus if it exists and is friendly; the target of my focus if THAT exists and is friendly; and last but not least my target if it’s friendly.

Seems so simple, doesn’t it? (grin)

Now the first step in shortening any macro is asking a question. A simple question, really. Do you really need all those options, variations, and actions popping out of one little button? Really?

Sometimes the answer is, “no”. In which the fix is simple – cut out what you don’t need. But sometimes it’s yes.

I’m getting rid of the shadowform test line. Oh, I like it, and after I do a bunch of other things it may come back, but this is always option one. Wahoo, 22 characters gone, a whole bunch more to go.

The second thing is one we ran into in an earlier lesson. Since it’s redundant we’ll just to it – a semicolon (;) in place of several repeats of cast. Ummm, a reminder before your mind fries entirely – backslash (\) means ‘continued on next line’. In other words, what follows is nominally two lines.

#showtooltip
/cast [modifier:alt, target=player] Greater Heal; \
[help, target=mouseover] Greater Heal; \
[help, target=focus] Greater Heal; \
[help, target=focustarget] Greater Heal; \
[help, target=target] Greater Heal; \
[help, modifier:ctrl, target=mouseover] Greater Heal(Rank 2); \
[help, exists, modifier:ctrl, target=focus] Greater Heal(Rank 2); \
[help, exists, modifier:ctrl, target=focustarget] Greater Heal(Rank 2); \
[help, modifier:ctrl, target=target] Greater Heal(Rank 2); \
[help, modifier: shift, target=mouseover] Flash Heal; \
[help, exists, modifier:shift, target=focus] Flash Heal; \
[help, exists, modifier:shift, target=focustarget] Flash Heal; \
[help, modifier:shift, target=target] Flash Heal

And also shown but in this case not DISCUSSED… if we have multiple conditionals that have the same command AND parameters, we can put them ALL between said command and conditional. Again demonstrating:

#showtooltip
/cast [modifier:alt, target=player] \
[help, target=mouseover] \
[help, target=focus] \
[help, target=focustarget] \
[help, target=target] Greater Heal; \
[help, modifier:ctrl, target=mouseover] \
[help, exists, modifier:ctrl, target=focus] \
[help, exists, modifier:ctrl, target=focustarget] \
[help, modifier:ctrl, target=target] Greater Heal(Rank 2); \
[help, modifier: shift, target=mouseover] \
[help, exists, modifier:shift, target=focus] \
[help, exists, modifier:shift, target=focustarget] \
[help, modifier:shift, target=target] Flash Heal

For the record, we are now down to 524 characters. A lot better, but still too many characters. Fortunately, there are still tools in my bag.

First, I can eliminate a lot of spaces. I can eliminate any space adjacent to a symbol (commas, brackets, etc), EXCEPT those separating the command from the conditionals AND the conditionals from the parameter. At 499 characters I now have:

#showtooltip
/cast [modifier:alt,target=player][help,target=mouseover] \
[help,target=focus][help,target=focustarget] \
[help,target=target] Greater Heal; \
[help,modifier:ctrl,target=mouseover] \
[help,exists,modifier:ctrl,target=focus] \
[help,exists,modifier:ctrl,target=focustarget] \
[help,modifier:ctrl,target=target] Greater Heal(Rank 2); \
[help,modifier:shift,target=mouseover] \
[help,exists,modifier:shift,target=focus] \
[help,exists,modifier:shift,target=focustarget] \
[help,modifier:shift,target=target] Flash Heal

The next thing I do is check the logic path for unnecessary elements. OK, folks, this is the MOST FREQUENT element I see in macros. The default test for focus is “does it exist”. ie – if I tell the macro to cast something at the focus and there is no focus, the line can’t be performed. And instead of hanging (waiting for a focus to be assigned), the macro logic says, “if this line cannot be executed, go to the next line.”

In other words, I can eliminate “exists,” from 4 lines – 28 characters gone, and I’m down to 473 with:

#showtooltip
/cast [modifier:alt,target=player][help,target=mouseover] \
[help,target=focus][help,target=focustarget] \
[help,target=target] Greater Heal; \
[help,modifier:ctrl,target=mouseover] \
[help,modifier:ctrl,target=focus] \
[help,modifier:ctrl,target=focustarget] \
[help,modifier:ctrl,target=target] Greater Heal(Rank 2); \
[help,modifier:shift,target=mouseover] \
[help,modifier:shift,target=focus] \
[help,modifier:shift,target=focustarget] \
[help,modifier:shift,target=target] Flash Heal

Now, “target=target” is also redundant SO LONG AS there is a conditional that would otherwise apply. In other words, look at the conditional [help,target=target]. If I take out the whole conditional, there is nothing that allows the macro to see the target. But if I leave in “help”, then unless I designate a target the macro engine ASSUMES (that is, defaults to) target=target. 42 more characters gone, and we get:

#showtooltip
/cast [modifier:alt,target=player][help,target=mouseover] \
[help,target=focus][help,target=focustarget] \
[help] Greater Heal; \
[help,modifier:ctrl,target=mouseover] \
[help,modifier:ctrl,target=focus] \
[help,modifier:ctrl,target=focustarget] \
[help,modifier:ctrl] Greater Heal(Rank 2); \
[help,modifier:shift,target=mouseover] \
[help,modifier:shift,target=focus] \
[help,modifier:shift,target=focustarget] \
[help,modifier:shift] Flash Heal

The next thing is abbreviations. If you read the link I gave – the concise list of current macro changes – you saw what’s coming because it was JUST ADDED. I can abbreviate modifier as mod.

#showtooltip
/cast [mod:alt,target=player][help,target=mouseover] \
[help,target=focus][help,target=focustarget] \
[help] Greater Heal; \
[help,mod:ctrl,target=mouseover] \
[help,mod:ctrl,target=focus] \
[help,mod:ctrl,target=focustarget] \
[help,mod:ctrl] Greater Heal(Rank 2); \
[help,mod:shift,target=mouseover] \
[help,mod:shift,target=focus] \
[help,mod:shift,target=focustarget] \
[help,mod:shift] Flash Heal

And I’m at 383 characters. And while that’s a HUGE improvement over 778, it’s still not ENOUGH. OK, I could cut another option – cutting out the whole downranking option, for example, would do it without question. But we’ve already discussed cutting and there are a couple of other techniques. But… both are brain expanders. So take a moment to decompress before you read on. Seriously, go play, get a nice drink, whatever. Come back when your brain can take it. I’ll still be here.

Back? OK, let’s burn some brain cells. We’re going to do two things. BUT, we’re going to do them separately – independent of one another. We COULD combine them, and down the road we might even do stuff that does combine them, but doing it here and now would turn your skull into a grenade. See, we’re going to split the macro, and we’re going to do just a little bit of scripting.

WAIT, COME BACK. When I said scripting, did you go “oh, crap, need to escape before brain explodes?” No problem. We’ll save it for last. And I promise to just scratch the surface this time – brain expansion, not explosion. So let’s start with splitting the macro.

We need to go back to our list of commands and notice a special option. That’s /click.

The command /click is another of those ‘peculiar’ commands. What it’s saying is “tell the main program that you’ve moved the mouse and clicked on…” Now you’re very limited in what you can click. Basically, you’re limited to bags and slots – no using this to autocatch fish or autoloot or… (Yes, there are addons that do this. We’re still in macros. Patience…) To be more complete, the command MAY have most of the standard conditionals, MUST have one parameter, and MAY have a second parameter – and the two parameters must be in order. The first parameter is “what is clicked”, and the second parameter is “which mouse button”. Oh, hey, that’s simple. (snicker).

To click the top (first) button of the first (rightmost) vertical bar – the one you can add in the user interface – your macro would read:

/click MultiBarRightButton1

To click it with the right mouse button, it would read:

/click MultiBarRightButton1 RightButton

I need to digress. I’ve been a bit sloppy in the past with case – upper and lower case letters. In basic macros that doesn’t usually matter, but sometimes it does. In fact, it should be part of your troubleshooting procedures — if all else looks right, check the case. That said, when you get to advanced macro work case certainly matters. Take the preceding single line. The capitals in both parameters are necessary. Failing to include them will usually (and frustratingly NOT always) cause your macro to NOT WORK.

Anyway… you can, at any point, have your macro “click” another button. Which means… I can split my macro into two parts, put it in two places, and have the first one click the second as the last option — or for that matter, earlier. Or getting fancier, I can do THREE macros. Which means I can get away with:

/macro one/
#showtooltip Greater Heal
/stopmacro [stance:1]
/click [mod:ctrl] MultiBarLeftButton1; [mod:shift] MultiBarLeftButton2
/cast [mod:alt,target=player][help,target=mouseover] \
[help,target=focus][help,target=focustarget] \
[help] Greater Heal

/macro two – placed on left vertical bar in first spot/
[help,mod:ctrl,target=mouseover] \
[help,mod:ctrl,target=focus] \
[help,mod:ctrl,target=focustarget] \
[help,mod:ctrl] Greater Heal(Rank 2)
/stopmacro

/macro three – placed on second spot of same bar/
[help,mod:shift,target=mouseover] \
[help,mod:shift,target=focus] \
[help,mod:shift,target=focustarget] \
[help,mod:shift] Flash Heal
/stopmacro

Ooookay. Some things to note about about this. Least but still worth noting – I got to BRING BACK my shadowpriest “oops” protection.

Second… when I do this and I put the /click in the middle, I alway end the subsequent macro with a /stopmacro command. It’s paranoia, really — the macro engine (as opposed to the scripting engine) isn’t supposed to treat macros as subroutines. That is, when it finishes the macro ‘over there’ it shouldn’t come back. On the other hand… shouldn’t isn’t “WILL”. For what it’s worth, in this particular set the routine will stop if I jump.

Third… the showtooltip line is officially screwed when you do this. It will not look at the other macros. And there is no icon connected to “MultiBarLeftButton1″. So either preload a tooltip, or ignore it and pick an icon you prefer.

Finally… notice the REALLY SNEAKY thing I did. I branched instead of chained. See, I could have made a chain of /clicks instead of an option – that is, run through the first and go to the second (no choice, just /click first button) and at the end of it go to the third (again, end with /click second button) and so on, breaking up the original almost-800 characters into three or four bites. Instead I snuck in another two-for-one lesson by showing I can use the conditionals in the clicks. THAT SAID… remember that the conditional doesn’t reset in the later macros. Oh, it COULD if you’re fast enough. But you’re having to beat a few hundred characters that process in an eyeblink. So don’t test for a different conditional later. And THAT said… I’ve got a wasted element in macros two and three. Since I used the mod to decide which macro to go to in the click, including the mod in two and three is a waste – once the computer’s gone to that macro it’s “do that” or do nothing.

Which means my final macro set looks like:

/macro one/
#showtooltip Greater Heal
/stopmacro [stance:1]
/click [mod:ctrl] MultiBarLeftButton1; [mod:shift] MultiBarLeftButton2
/cast [mod:alt,target=player][help,target=mouseover] \
[help,target=focus][help,target=focustarget] \
[help] Greater Heal

/macro two – placed on left vertical bar in first spot/
[help,target=mouseover] \
[help,target=focus] \
[help,target=focustarget] \
[help] Greater Heal(Rank 2)
/stopmacro

/macro three – placed on second spot of same bar/
[help,mod:shift,target=mouseover] \
[help,target=focus] \
[help,target=focustarget] \
[help] Flash Heal
/stopmacro

That said, notice something useful -

Hmmm. Let me anticipate a couple of things. No, this does not let you get around the “multiple spellcasts in one macro” limit. If the GCD is triggered, it’s triggered regardless of how many macros you click.

And yes, this won’t work on neutrals, only on friendlies. If you’ve read the prior lessons, you know how to fix that little issue.

And with that… it appears I’ve lied, but I don’t think you’re going to be too unhappy. I’m getting to the point where I like to let you take a break. So… no scripting today. That will be the next lesson — an intro to scripting, with one or two glances at macro issues left uncovered. Please come – I promise to try and keep brain expansion BELOW the “boom” threshhold.   And while I’m at it, I will tell you how to figure out what the labels are for the bars so you can click them.  (You thought I was going to leave that hanging, didn’t you?)

In the meantime, go have fun.

~ by Kirk on December 11, 2007.

6 Responses to “Writing macros, a series of lessons (6 of…)”

  1. i keep deleting everything i type. you melted my brain with…all of that. is this some new rank of mind flay?

    seriously though, great explanation of how to simplify a macro without losing the functionality. methinks you may have some sort of coding background…

  2. Cool example.

    Out of (morbid?) curiosity, how long did it take to put that together? Or did you start at the finish line and work backwards?

    Looking forward to the scripting!

  3. @Doomilias – thank you. And only a little bit.

    @Black – Actually, I wrote the huge macro first and ran it down step by step, with the certain knowledge that I wanted to show not only a full condensation but /click before I was done. Though it wasn’t a “cold” creation – it’s an expansion of one that I actually use as a healer. Set tank or Boss as focus and then even when things get nasty I can always ensure the tank gets a heal. Mouseover by preference, target as last choice. If you read past articles you’ll see the precursor of this.

    So basically – about 3 hours of typing and editing altogether.

  4. Awesome stuff, really. Thanks alot – all this really helps my game :)

  5. Hi! Great work, I’m gonna read all of your posts! ;)
    Just a report: in the last macro quoting, there is a typo:

    /macro three – placed on second spot of same bar/
    [help,mod:shift,target=mouseover] \
    [help,target=focus] \
    [help,target=focustarget] \
    [help] Flash Heal
    /stopmacro

    An unnedeed “mod:shift” ;)
    Correcting this will make the post perfect!
    Oh… GREAT WORK!!!

    • Hi, Elenoire, and thanks.

      Please notice when I wrote this series. It was correct at the time I wrote it. WoW’s gone through an expansion or two since then. Since I don’t play it any more, I don’t keep up with the edits.

      So enjoy, but keep some caution while you’re at it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: