Monday, April 7, 2014 - 11:17

Welcome to the 6th part of my addon tutorial! Today we'll be taking a look at the core elements in any World of Warcraft UI element, the Frames and their Events! Or put more simply, what happens in the game and how your addon can know about it!

Table of Contents

  1. What is a Frame?
  2. What is an Event?
  3. The Code
  4. The Event Tracer

What is a Frame?

In World of Warcraft, a 'Frame' is a container for special UI items. These 'Frames' can react to happenings in the game, you can use them to display art, or let the user click something in them. They are what the UI is made of. Technically speaking, a Frame is a Lua table. So you can assign methods to it, and it can have 'children'. But don't worry about that for now.

What is an Event?

An 'Event' in World of Warcraft is a message sent by the WoW client to the user interface mostly in reaction to things occurring in the game world. Events are how the addon know what's going on. There are Events for nearly everything. When the player logs in, and Event fires. When you reload the user interface or zone into an instance, an Event fires. Events occur when you die, enter combat, leave combat, gain health or mana, join a battleground, receive a chat message, gain gold, and so on. A full list can be found here!

To track an Event, you need to make a Frame listen for it. You also need to create a script handler telling the Frame what to do when an Event occurs. So let's do that right now.

The Code

What we're going to do today, is to track when your character enters and leaves combat. This is one of the most important things to be aware of, as a lot of abilities like drinking, eating, mounting up and so forth are blocked in combat. There are also a lot of things the UI can't do during combat, like changing visibility and position of existing unitframes and so on. So let's get to it!

The Events we use to watch for combat, isn't what you might think from looking at the Event list on wowpedia. It's not "PLAYER_ENTER_COMBAT", as that only fires when your auto-attack starts. What you instead should listen for is when the out of combat regen starts and stops. That's the true indicator of when you're in combat or not, when abilities like mounting up, eating and drinking are available. The Events are called "PLAYER_REGEN_DISABLED" and "PLAYER_REGEN_ENABLED".

-- create the frame
local frame = CreateFrame("Frame", nil, UIParent)

-- assign the Events to it
frame:RegisterEvent("PLAYER_REGEN_DISABLED")
frame:RegisterEvent("PLAYER_REGEN_ENABLED")

-- create a script handler to react to the Events
frame:SetScript("OnEvent", function(self, event, ...)
   -- we don't need it in this example,
   -- but this is how you retrieve arguments passed along with Events:
   local arg1, arg2, arg3 = ...
   if event == "PLAYER_REGEN_DISABLED" then
      print("You're in combat!")
   elseif event == "PLAYER_REGEN_ENABLED" then
      print("Combat ended, mount up and run!")
   end
end)

You can add this to the addon we made last time, or make a new addon for it. When it's saved properly and the game client restarted, you should now be getting warnings in the default chatframe when you enter and leave combat.

True, not a very useful addon as the UI already does this for you, but the point here wasn't to reinvent the powder, it was to show you how Events work, give you something to play around with!

▲ Go back to the top

The Event Tracer

Blizzard have provided us with a handful of useful debugging tools. One of them is the Event Tracer. Which is exactly what it sounds like, something that traces Events. You can activate it with the following command written into the chatframe inside the game:

/eventtrace

Try it, and then wait for a while. You'll notice all sorts of Events occurring. If you mouse over any of them, you'll get more details about it like the arguments passed along with it. I find the Event Tracer to be one of the most useful tools in learning how the game and the UI works. No theory can beat actually seeing with your own eyes what's going on!

The Event Tracer provides very detailed information about the Events.

So, that was all I had for you today. I recommend that you study the list of Events at wowpedia, as well as checking out what other addon users are doing. A trick to figuring out stuff, is to find an addon that does something you like, then simply search that addon's code for "RegisterEvent" and "OnEvent". You can consider that one of my major secrets, actually. It doesn't seem like much, but it will take you straight to the heart of what's going on. You'll know what the addon is listening for, and what it does when it happens. I've spent countless hours gazing at what others have done, it's simply the best way to learn.

See you all next time!

▲ Go back to the top

▲ Go back to the top

Read More
Sunday, February 2, 2014 - 12:16

Welcome to the 5th part of my WoW addon creation tutorial! Finally it's time to get down to business and start creating addons!

Table of Contents

  1. Making the addon
    1. Creating the files and folders
    2. Testing the addon
  2. Code breakdown

Making the addon

The time has finally come to create your first addon. From here on there'll be a little less conversation, and a little more action! So navigate to your Interface\AddOns directory, and fire up your text editor of choice.

Creating the files and folders

We'll keep this as simple as possible, so for our excercise we'll be needing a single folder, and two text files. First off you should create your addon folder within the Interface\AddOns directory. Let's call our addon "FriendlyTutorialpt2". Not the shortest name, but there should be no risk of naming conflicts at least. I doubt very much you already have an addon with that name installed.

Now go into your text editor, and create a new file. Make sure the file encoding is set to UTF8, and without BOM. In Notepad++ you can set this from the Encoding menu. You should make this a general rule to encode all your text files in WoW addons as UTF8 without BOM. It's a format fully supported by WoW, and it allows you to use letters from pretty much any language on the planet inside the code. This'll come in handy when localizing your addons to languages not using the latin alphabet, like Russian.

Name your new file "FriendlyTutorialpt2.toc" and put it directly inside the addon folder of the same name. Then copy and paste the following code into it, and save it.

## Interface: 50400
## Name: FriendlyTutorialpt2
## Title: |cffffb200friendly|r|cffff7d0adruid|r|cffffb200.com|r |cfffffffftutorial pt 2|r
## Notes: Awesome addon
## Author: Lars Norberg
## Version: 1.0
## DefaultState: Enabled

main.lua

From what you learned earlier about the TOC file, you should be able to see that our addon now require WoW 5.4.x to run, and it will load a file called "main.lua". So let's create that file too! You should have a pretty good idea of what the rest of the code does too, and if not, check out my previous tutorial on the TOC format!

Now, once again create a new file in your text editor, make sure it's encoded in UTF8 without BOM, and copy the code below into it. Save the file directly into the addon folder as "main.lua".

-- our very first addon
local addon, ns = ...

local frame = CreateFrame("Frame", nil, UIParent)
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(self, event, ...)
    local arg1 = ...
       if (arg1 == addon) then
        local version, build, date, tocversion = GetBuildInfo()
        print("Your game client is running WoW version " .. version .. ", build " .. build .. " - " .. date)
        self:UnregisterEvent("ADDON_LOADED")
    end
end)

▲ Go back to the top

Testing the addon

Make sure all the files are saved, then fire up WoW. Once you're at the character selection screen, click the button labeled "AddOns" in the bottom left corner. You should be able to find our newly created addon on the list that appears. Once that is verified, log into the game world!

Our new addon in the addon list
Our addon in action!

What you see in the chat output window - and you might have to scroll a bit up to find it if you have many addons installed, should be a message similar to "Your game client is running WoW version 5.4.2, build 17688 - Dec 12 2013". Of course, the actual values here change based on when you run this addon. Every time a patch comes, these values will be different. The output on my screen indicates I was running WoW 5.4.2 build 17688 when I took the screenshot. These values are the same as you see in the bottom left corner of the WoW startup screen.

▲ Go back to the top

Code breakdown

Now that you've succesfully made a very simple addon, let's take a look at what it actually did, line by line.

-- our very first addon
local addon, ns = ...

The first line that starts with "--", is just a comment. Comments are ignored by the client, and are just there for our own reference.

The second line creates 2 local variables, named "addon" and "ns". What "local" means in this context, is that they belong to our current addon, and can't be read by any other addon. You should as a rule ALWAYS make any variable you create a local variable. The only exception is your saved variables, as they need to be global. More on that at a later stage in the tutorial.

Both of our 2 newly created variables get their values from a very special operator called an "ellipsis", which is written as 3 dots. An ellipsis ("..." without the quotes) is a special operator which is only available inside a vararg function, meaning a function that can accept a variable number of arguments.

Every addon in WoW is in reality just a function called by the main UI environment, and by using the ellipsis operator we can access a lot of information sent to the addon by the game. The first 2 of the arguments passed to our addon is the name (directory) of the addon, and it's namespace. A namespace is basically a table, or array available to all the files of a specific addon. Meaning that you can send values between different Lua files within the same addon by using the namespace. This is a better way than using globals (variables available to all addons), as the namespace is local, and local variables are both faster, and you don't risk running into naming conflicts.

local frame = CreateFrame("Frame", nil, UIParent)

What we do here is to use a function native to WoW called "CreateFrame", to create a Frame. A Frame in WoW is a special type of table that represents an UI object. Allmost all objects you see in the UI - like unitframes, actionbuttons, bags, achievememts and so on - are Frame. You see them all the time, you just didn't know what they were until now. You can assign sizes and backdrops to the Frame if you like, or let it remain invisible like we have done. Frames are more than just a way to show graphics, they are also the only way to listen to Events, set up timers and basically make stuff happen. To learn more about the syntax of the CreateFrame() command, click here to visit wowpedia!

frame:RegisterEvent("ADDON_LOADED")

Remember we talked about Events in the previous tutorial on the addon loading process? What we did just now, was to tell our Frame to listen for the ADDON_LOADED Event. This Event fires whenever an addon has been loaded, and it's saved variables are available. This Event fires for all addons for every addon loaded, meaning if you have 30 addons installed, this Event will fire up to 30 times for your newly created Frame.

A frame is as mentioned a table. If an entry in a table is a function, you can call that function as a method of the table itself. This basically means that instead of just calling a function, you are calling a function that is aware of where it is. It knows it lives inside its table, which in our example is the Frame we created. As we stored the location of our frame in our local "frame" variable, this means that what we just did was to run the method "RegisterEvent()" on the Frame stored in "frame", and pass the argument "ADDON_LOADED" to this method. Confusing? Don't worry, it all makes sense. Eventually.

frame:SetScript("OnEvent", function(self, event, ...)


end)

Here we're running another method on our Frame, called "SetScript". Every Frame in WoW comes with a set of script handlers, meaning you can add snippets of Lua code to be run when specific things happen to that Frame. In our case, we defined the "OnEvent" script handler, which will be run every time an Event the frame has registered for fires.

The arguments passed to the script handler - which is always the case for all Event handlers, are "self" which refers to the Frame itself, "event" which is the name of the Event that fired, and the ellipsis "..." which represents all the remaining arguments, regardless of how few or how many they are.

We will be referring the various UI objects (like Frames) in WoW as "Widgets". You can check out all the Widget methods for each Widget type on the Widget API page on wowpedia. You can also study the various Widget Handlers, or script handlers for Widgets if you like, on the Widget Handlers page. If you haven't already, bookmark wowpedia's UI portal! It will be your number one resource for addon development. Soon you won't be needing me at all, you'll simply just find what you need there!

local arg1 = ...

What we do here is to assign the first returned value in the ellipsis to the local variable "arg1". We only want the first argument, because with the ADDON_LOADED Event, this argument is the name of the addon the Event fired for. You can check out the full listing of all the WoW Events and their return values over at wowpedia!

if (arg1 == addon) then


end

Here we're running a conditional statement. Meaning everything between the "if" and the corresponding "end", will only be run if the conditional following the "if" statement is true. The "==" operator in Lua is used to compare 2 values. We previously stored the name of the addon the ADDON_LOADED Event fired for in the "arg1" variable. At the start of our addon, we stored the name of our addon in the "addon" variable. So what we're doing is to simply compare those 2 names, to see if it indeed was our addon the ADDON_LOADED Event fired for.

local version, build, date, tocversion = GetBuildInfo()

The GetBuildInfo() function allows you retrieve various information about the game client version. You can read the full description of this function over at wowpedia.

print("Your game client is running WoW version " .. version .. ", build " .. build .. " - " .. date)

The command "print" simply displays the text you pass to it in the main chat window inside of WoW. Only you can see this text, it's not sent to anybody else. In Lua, quotes are used to encompass strings, meaning normal text. You can tie various strings together with the concatenation operator, which in Lua is written as 2 dots. So we basically just print to the screen the info we retrieved in the previous statement, and the result will be what we saw in the screenshot.

self:UnregisterEvent("ADDON_LOADED")

This last unregisters the Event "ADDON_LOADED" from our Frame, and it will no longer listen for it. We're doing this because we don't need it anymore. Neither will the Event fire again for our addon, nor would we wish to print the version info to the screen again even if it did. So we unregister the Event from our Frame, to sort of clean the room before we leave.

You might notice that we use "self:UnregisterEvent", while we registered the Event using "frame:RegisterEvent". We could have used the "frame" variable to unregister the Event instead of the "self" variable if we wanted to, but as the frame reference is passed to the function through the "self" variable, "self" will be faster and better to use.

Think of it this way; every time you start a new loop, or a new conditional statement, or a new function, you create a new namespace. You nest. When you look up a variable that isn't local to the current namespace, the client has to search all the variables of the parent namespace to find it, and if it's not there, it has to search the parent of that again, and so on. This slows down the addon, as the farther out the client has to go to find a variable, the more time it spends doing it. This is one of the main reasons you should always use local variables, because they are simply faster. We'll be covering this in detail at a much later stage in the tutorial, when we talk about optimizing your code. For now, just now that "the more local it is, the better"!

▲ Go back to the top

Last words

So that's it for now. Hopefully you managed to set up a working addon, and get a slight idea of how the addon environment in WoW works. In the upcoming parts of our tutorial, we will be taking a closer look at how Frames work, and also get a basic understanding of the Lua programming language. If you want to "skip ahead", feel free to check out the Lua Tutorial over at CoronaDocs. It's awesome. Boring, but awesome. The faster you learn to master Lua, the faster you can start focusing on all the cool things WoW addons alone can do instead!

Until next time, cheerio!

▲ Go back to the top

Read More
Saturday, February 1, 2014 - 18:00

Welcome to part 4 of my addon creation tutorial. We'll be taking a look at the addon loading process this time, to get an understanding of how and when the addon is loaded, and when various information will become available to it. Ready?

Table of Contents

  1. Events
  2. Addon Loading Process
    1. Order of events fired during loading
      1. ADDON_LOADED
      2. SAVED_VARIABLES_TOO_LARGE
      3. SPELLS_CHANGED
      4. PLAYER_LOGIN
      5. PLAYER_ENTERING_WORLD
    2. Load On Demand behavior

Events

Before we start, it is important that you understand what an Event in World of Warcraft is. In short Events are messages sent by the WoW client to the user interface mostly in reaction to things occurring in the game world. Events are how the addon know what's going on. To understand the loading process, you need to know when various Events fire off, and what this means for the user interface.

We'll be looking at how to read and respond to the Events at a later stage in the tutorial, for now you just need to know they exist, and what they mean.

Addon Loading Process

  1. When the client first starts, Interface\AddOns directory is scanned, and a list of files and addon dependencies are built.
  2. Addon code is executed after the player selects a character and presses 'Enter World'.
  3. After all addon code has been loaded, the saved variables are executed. The event ADDON_LOADED fires after each addon's saved variables have been loaded.

Order of events fired during loading

After the addon code has been loaded, the loading process can be followed by registering for various events, listed here in order of firing. This information is very important because many addons rely on information that is not available when addons first load, such as buffs, spells, talents, quests, pets, pvp information, etc. By monitoring one of the following events with a blank frame, you can trigger the appropriate "OnEvent" handler and execute code that is dependent on that information as soon as it is available.

  1. ADDON_LOADED
    • This event fires whenever an addon has finished loading and the SavedVariables for that addon have been loaded from their file.
  2. SAVED_VARIABLES_TOO_LARGE (Error Condition)
    • Generally will not fire. This event indicates an error state where the SavedVariables of an addon failed to load due to an out-of-memory error. (The old error state was a client crash!)
    • The upshot here is that your addon could be in a state where the saved variables did not load. This event's purpose is to indicate that you are in this error state.
    • If you are in this state your addon's SavedVariables will NOT be saved back to disk at the next logout. This was done with the reasoning that it will prevent valid data from accidentally being wiped by defaults.
    • It is possible for an addon's account wide SavedVariables to load, but for the character specific SavedVariables to fail, or vice versa. There is no way to detect the difference between no variables loaded and some.
  3. SPELLS_CHANGED
    • This event fires shortly before the PLAYER_LOGIN event and signals that information on the user's spells has been loaded and is available to the UI.
  4. PLAYER_LOGIN
    • This event fires immediately before PLAYER_ENTERING_WORLD.
    • Most information about the game world should now be available to the UI.
    • All sizing and positioning of frames is supposed to be completed before this event fires.
    • Addons that want to do one-time initialization procedures once the player has "entered the world" should use this event instead of PLAYER_ENTERING_WORLD.
  5. PLAYER_ENTERING_WORLD
    • This event fires immediately after PLAYER_LOGIN
    • Most information about the game world should now be available to the UI. If this is an interface reload rather than a fresh log in, talent information should also be available.
    • All sizing and positioning of frames is supposed to be completed before this event fires.
    • This event also fires whenever the player enters/leaves an instance and generally whenever the player sees a loading screen

Since Patch 3.0.2, VARIABLES_LOADED has not been a reliable part of the addon loading process. It is now fired only in response to CVars, Keybindings and other associated "Blizzard" variables being loaded, and may therefore be delayed until after PLAYER_ENTERING_WORLD. The event may still be useful to override positioning data stored in layout-cache.txt.

Somewhere around Patch 5.4.0, PLAYER_ALIVE stopped being fired on login. It now only fires when a player is resurrected (before releasing spirit) or when a player releases spirit. Previously, PLAYER_ALIVE was used to by addons to signal that quest and talent information were available because it was the last event to fire (fired after PLAYER_ENTERING_WORLD), but this is no longer accurate.

Load On Demand behavior

Load on Demand addons cannot rely on most of the event sequence being fired for them; only ADDON_LOADED is a reliable indication that the saved variables for your LoD addon have been loaded.

Last words

That's it for this time. Even though you haven't written a single line of addon code yet, you should already begin to get an understanding of how the World of Warcraft addon environment works. By tracking the correct Events, you can make your addon respond to almost anything that happens in the game. If you like you can take a look at the full list of available Events over at wowpedia. Don't let the massive amount of Events scare you, as you don't need to remember them all. That's what we have wowpedia's UI portal for!

Next time we'll be creating our very first addon!

▲ Go back to the top

Read More
13:55

Greeings fellow UI lovers, and welcome to part 3 of my addon creation tutorial! This time we'll be taking a look at the format of the required TOC file. Let's get to it!

Table of Contents

  1. The TOC format
    1. Syntax
      1. Tags
      2. Comments
      3. Files
    2. Official tags
      1. Interface
      2. Title
      3. Notes
      4. Author
      5. Version
      6. RequiredDeps, Dependencies, or any word beginning with "Dep"
      7. OptionalDeps
      8. LoadOnDemand
      9. LoadWith
      10. LoadManagers
      11. SavedVariables
      12. SavedVariablesPerCharacter
      13. DefaultState
      14. Secure
  2. Custom/metadata tags
  3. Example TOC file

The TOC format

.toc (Table of Contents) files contain information about a particular addon (such as its name, description, saved variables, etc), as well as instructions on how the addon should be loaded by the client (for example, the order in which lua and xml files should be loaded). The file must be present, and have the same name (plus extension) as its parent folder for the addon to be recognized by the client.

While most other files are reread on every client reload and thus can be changed while the game is running, the .toc file is only read once during the initial startup process. This means that any changes to the .toc file require a full game restart to take effect.

TOC files mainly consist of three types of objects; tags, comments and file references. Each new line is considered a new object(or command, if you prefer to call them that). It is ok to include blank lines, as any extra whitespace is ignored.

Syntax

Tags

Tags are the bread and butter of a TOC file. They tell the game which client version they were designed for, whether or not they require another addon to be present, and many other things. The format is as follows:

## TagName: Value

Comments

It's possible to enter comments into TOC files. Comments are skipped by the client, but can be useful for development purposes, and sometimes for 3rd party service like CurseForge.

### This is a comment, which is skipped by the client

Files

Anything not starting with a hashtag, is considered a file. You can include directory names here, and the path is relative to the current folder. You can only load XML and Lua files from within the TOC file. No media files can be listed here, as media can only be loaded through Lua commands from within Lua or XML files.

libs/myLib.xml
Bindings.xml
main.lua

▲ Go back to the top

Official tags

Interface

Specifies which client interface version the addon was made for. If the value of this tag does not match the client interface version, the addon is loaded only if the "Load out of date addons" option is enabled. The fastest way to get the current build and interface version of WoW is by typing "/run print(GetBuildInfo())" without the quotes in any WoW chat window, followed by the Enter key. This tag is required.

## Interface: 50400

Title

The value of this tag is displayed in the AddOns list. Localized versions can be included by appending a hyphen followed by the client locale name; the client automatically chooses a localized version if one is available. The value may also contain UI escape sequences, such as for example colors.

## Title: Waiting for Lars ## Title-frFR: En attendant Lars

Notes

Addon description that appears when the user hovers over the addon entry in the addons list. Like Title, this tag can be localized by appending a hyphen followed by locale name, and contain UI escape sequences.

Author

The AddOn author's name.

Version

The AddOn version. Some automatic updating tools may prefer that this string begins with a numeric version number, but you can enter pretty much anything you like.

RequiredDeps, Dependencies, or any word beginning with "Dep"

A comma-separated list of addon (directory) names that must be loaded before this addon can be loaded. If one or more are missing, the addon will not load at all.

OptionalDeps

A comma-separated list of addon (directory) names that should be loaded before this addon if they can be loaded. In this field you would typically put addons that when loaded affect the decisions made by your addon, or libraries that are embedded in your addon but also work as standalones.

LoadOnDemand

If this value of this tag is "1", the addon is not loaded when the user first logs in, but can be loaded by another addon at a later point. This can be used to avoid loading situational addons.

LoadWith

A comma-separated list of addon (directory) names that, when loaded, will cause the client to load this LoadOnDemand addon as well. Unlike RequiredDeps, this option also requires the listed addons to be LoadOnDemand. An example would be if you created an addon that required one of Blizzard's LoadOnDemand addons like the achievement UI to be loaded first. You would then use "Blizzard_AchievementUI " as the value for this field.

LoadManagers

A comma-separated list of addon (directory) names; if no addons on this list are loaded, the client will load your addon when the user logs in; if at least one addon on this list is loaded, your addon is treated as LoadOnDemand and the loading of it left to the specified LoadManager(s).

SavedVariables

A comma-separated list of variable names in the global environment that will be saved to disk when the client exits, and placed back into the global environment when your addon is loaded; the variables are not available before the ADDON_LOADED event fires for your addon. This is the only way to save anything between sessions, as addons are unable to write to the disc directly. Use caution when choosing variable names, as these are global and available to all other addons. Avoid simple or common names. I usually use the addon (directory) name with a "_DB" suffix to it.

SavedVariablesPerCharacter

A comma-separated list of variable names in the global environment that will be saved to disk when the client exits, and placed back into the global environment when your addon is loaded for a particular character. Note that PerCharacter saved variables are only loaded for the character for which they were saved.

DefaultState

This can have either the value "enabled"(default) or "disabled". If you set this to "disabled", your addon will be deactived/unchecked in the addon listing when first installed, and the user has to manually enable it. Addon packages like Deadly Boss Mods often use this for optional modules that most users don't want enabled by default.

Secure

If its value is set to 1, and it's an addon digitally signed by Blizzard, it's code is considered "secure". What this means is that it has unrestricted access any and all parts of the UI even during combat, which is something 3rd party addons can't. This option is only available to Blizzard addons, and not something you can enable for your own. We're listing it here only for reference purposes, as you're likely to come across it when studying the Blizzard interface code later on.

▲ Go back to the top

Custom/metadata tags

It is possible for addons to query values of any tags with a "X-" prefix. You can put pretty much anything you like here, though some apps like the Curse Client use the metadata tags to store extra information about each addon, like a list of embedded libraries, or the internal curse package version of the addon. All addons downloaded through either curse.com or the Curse Client includes custom tags.

Custom tags, and some official tags like "Title", "Notes" and "Version" can be retrieved from within the addons with the GetAddOnMetadata() command:

local value = GetAddOnMetadata("addon", "field")

In this example "addon" refers to the directory name of the addon, and "field" to the tagname you wish to read. The value is returned as a string.

▲ Go back to the top

Example TOC file

Here's the (more or less) current TOC file for the addon gUI3, as of WoW patch 5.4.2:

## Interface: 50400
## Name: gUI-v3
## Title: |cFFFF7D0Ag|r|cFFFFBB00UI|r|cFFFFFFFF3|r |cFF00FF96MoP|r
## Notes: Minimalistic UI replacement.
## Author: Lars Norberg
## Version: 1.0
## DefaultState: Enabled
## SavedVariables: gUI3_DB
## OptionalDeps: SharedMedia, LibSharedMedia-3.0, Bartender4, Dominos, RazerAnansi, RazerNaga, ElkBuffBars, SatrinaBuffFrame, AdiBags, ArkInventory, Bagnon, Baggins, BaudBag, cargBags_Nivaya, cargBags_Simplicity, Combuctor, famBags, OneBag3, OneBank3, TBag, Quartz, Chatter, Prat-3.0, ag_UnitFrames, PitBull4, ShadowedUnitFrames, XPerl, Aloft, DocsUI_Nameplates, Healium, Healers-Have-To-Die, Headline, knameplates, Kui_Nameplates, mNameplates, StarTip, TidyPlates, TinyTip, TipTac, AuctionLite, Auc-Advanced, Recount, Postal, DBM-Core, Omen, Skada, MikScrollingBattleText, Carbonite
## X-eMail: goldpaw@friendlydruid.com
## X-Website: http://www.friendlydruid.com

gUI-v3.xml

From this you should be able to see that gUI3 requires WoW 5.4.x to function, that it saves all its settings in a global file, and that it has a lot of optional dependencies that all will be loaded prior to gUI3. You should also see from this file that the TOC file only loads a single file, namely the gUI-v3.xml file. In reality gUI3 loads close to a hundred files, but they are all listed in various XML files, not the TOC file. More on that later!

I've also used custom tags here, listing a contact email and website. As mentioned these have no impact on WoW itself, and the client completely ignores them. They can however be retrieved with GetAddOnMetaData() from within the addon, and I like to have them there as reference for other addon authors.

The title/display name of the addon also uses color coding. Not that you'll be using this right now, but here's the format of that:

|caarrggbb...text...|r

In text printed to the screen in WoW, the | symbol indicates an escape sequence. What this means is that it "escapes" from the written text to perform one or more commands to modify the output. The |c escape sequence in WoW refers to a color modification. What follows is the alpha value, and the red, green and blue components of the color code. These are all hexadecimal values, so a value of FF0000FF would mean a fully opaque pure blue color, and all the text between the color code and the closing |r sequence would then be blue. You can't change the alpha value of text displayed in the addon listing though, so regardless of what you type in the alpha field, the text will be displayed fully opaque, as if the value was FF.

On a slight sidenote, the orange color used by both the "g" in the gUI text and the gUI logo, is the color #FF7D0A, which is the orange Blizzard uses for the Druid class color. And legendary quality items. So I didn't choose it on random!

Last words

That's it for this time. Next we'll be looking at the addon loading process, to get an understanding of how and when the addons are loaded, and when various info becomes available to them. Stay tuned, and until then, cheerio!

▲ Go back to the top

Read More
Friday, January 31, 2014 - 09:18

Welcome to the 2nd part of my WoW addon creation tutorial! Today we'll be looking at the file- and folder structure of WoW addons, as well as taking a look at the supported file- and media formats.

Table of Contents

  1. Addon file- and folder structure
  2. Supported file formats
    1. Table of Contents (.toc)
    2. UI definitions (.xml)
    3. Addon code (.lua)
    4. Images (.blp, .tga)
    5. Fonts (.ttf)
    6. Sounds (.mp3, .ogg)
      1. Can I make an in-game music player?

Addon file- and folder structure

Addons live inside the Interface\AddOns directory found within your World of Warcraft installation. This directory isn't created when the game is initially installed, but rather the first time you log into World of Warcraft on a computer. If you're unsure where your game installation is, the most common placements are:

Windows game client path:

  • either: C:\Program Files\World of Warcraft\Interface\AddOns
  • or: C:\users\public\games\World of Warcraft\Interface\AddOns (since Windows Vista)

Mac game client path:

  • /Applications/World of Warcraft/Interface/AddOns

Each addon has its own folder within the Addons directory, and the name of the addon's folder represents the internal name of the addon. If you created a folder named "MyAddon", the name WoW recognized your addon by would then be "MyAddon". This is case sensitive. In order to be recognized by the game client, an addon requires a folder, and a .toc file with the exact same name as the folder (plus the .toc extension) placed directly inside the addon folder.

Apart from this, you are free to place any number of subdirectiories and files within your addon folder.

▲ Go back to the top

Supported file formats

World of Warcraft addons accept a number of file formats. Addons can include fonts, images, sounds, defined UI elements through XML files, and Lua code. You can put whatever else you like into an addon folder, like pdf files and executables, but the game will ignore them and all other unsupported files completely. No executable will ever be run by WoW, and thus all addons are by definition "safe".

WoW only scans the AddOns directory once during startup, and any files not present then won't be recognized by the game. To discover new files, you need to completely restart the game. This is important to keep in mind when developing addons, and even when updating the addons you use. If you don't completely exit the game when updating addons, any new directories and files won't be discovered at all.

Changes to existing media-, Lua and XML files are however registered on every reload of the user interface. Keep that in mind when creating your own addons or modifying existing ones later on. Reloading is our most precious tool!

Table of Contents (.toc)

.toc (Table of Contents) files contain information about a particular addon (such as its name, description, saved variables, etc), as well as instructions on how the addon should be loaded by the client (for example, the order in which lua and xml files should be loaded). The file must be present, and have the same name (plus extension) as its parent folder for the addon to be recognized by the client.

While most other files are reread on every client reload and thus can be changed while the game is running, the .toc file is only read once during the initial startup process. This means that any changes to the .toc file require a full game restart to take effect.

We'll go deeper into the contents and format of the .toc file next time.

UI definitions (.xml)

All UI elements like graphic, textures, animations, fonts and sounds can be defined in special XML files. Any keybinds used by your addon is also defined using a special XML file called Bindings.xml, which must be place in the root of your addon directory. XML files can also be used to load other XML- or Lua files, and they can also include Lua code directly. XML files are strictly speaking not required, but they do hold certain benefits, like the ability to create templates.

We'll be covering XML files thoroughly at a later stage, but not today.

Addon code (.lua)

Do you remember these?

Most of the addon code run by WoW is stored in Lua files with the .lua extension. "Lua" (pronounced LOO-ah) means "Moon" in Portuguese. As such, it is neither an acronym nor an abbreviation, but a noun. More specifically, "Lua" is a name, the name of the Earth's moon and the name of the language. Like most names, it should be written in lower case with an initial capital, that is, "Lua". Not "LUA" in other words, as that's just wrong.

Lua is a powerful, fast, lightweight, embeddable scripting language. The entire Lua engine only occupies about 250KiB compressed and 960KiB uncompressed. This is so small that it would actually fit on an old 3.5" floppy disk, making it ideal for embedding in games and applications. Lua is used for UI scripting in several known programs and games such as Adobe Photoshop Lightroom and Warhammer Online and Rift.

Images (.blp, .tga)

World of Warcraft accept images in both Blizzard's own .blp-format, as well as standard .tga files. Transparency is supported. There are no advantages to using the .blp format in your own images, so I suggest you simply steer clear of this.

Even though WoW supports transparency in TGA images, actually creating this can be quite the hassle if done incorrectly. When exporting an image to TGA format from a program like Photoshop, the transparency is removed. You have to jump through hoops to make this work, so I found it much easier to simply export them as PNG, then use XnView to convert them to TGA with transparency later. XnView can also be used to view existing blp images, which is quite useful when browsing through the existing blizzard artwork.

The Internet is packed with cool images, art and illustrations. But just because you can freely download something doesn't mean you can freely redistribute it. Whenever you upload an addon to the Internet, it suddenly becomes a commercial product, regardless of how free it is. Make sure you only use public domain images, or images that have a licence that allows unlimited commercial redistribution.

Fonts (.ttf)

Pretty much any TrueType font in the world can be used in World of Warcraft. As in all other things though, make sure that you're actually allowed to use the font in your addon. Remember that even if you're not making any money from this, an addon is still regarded a commercial product, and anything you distribute along with the addon is therefore distributed commercially. So you can't simply include any fonts you like.

There are several pages on the web dedicated to font hosting. My personal favorite is dafont.com, as its selection is very big and diverse. As of writing this, the dafont database includes no less than a whopping 22881 fonts! It also allows you to search by both genre and licence type, the latter of great interest to somebody like me who uploads addons on a regular basis. Unless you're willing to pay for a commercial license that allows unlimited redistribution, the fonts you should be looking for are those listed as "Public Domain", and nothing but.

Sounds (.mp3, .ogg)

World of Warcraft accepts music and sound effects in either ogg or mp3 format. Just don't forget about the copyright laws, folks. I know this is probably starting to annoy you by now, but I just can't stress this enough. I know in these days of sharing most people don't think twice about what they share with friends or download from the Internet, since it really isn't that big a deal. But when it comes to commercial redistribution, sharing the wrong thing is a crime on a whole other level than downloading an mp3 for personal use. So make sure you are allowed to include what you include!

Can I make an in-game music player?

Even though World of Warcraft allows you to play mp3 sounds, this does not mean you can create a media player from within the game. There are several reasons for this.

First off, you can't pause music. You can only choose between playing, and not playing it. Also, as mentioned earlier addons can only access files from within the WoW folders, and they only recognize files that are present at the game startup. Also, you can't request a directory listing, you need to know the name and location of the file you wish to access. So if you feel like manually entering the names of the 5000+ songs in your mp3 library, go ahead. But I recommend that you simply... don't.

Last words

With this you should have a pretty good knowledge of the file- and folder structure in World of Warcraft addons. Next time we'll be diving into the TOC format, and learn how to properly set it up for your addon to work. Until then, cheerio!

▲ Go back to the top

Read More
Tuesday, January 14, 2014 - 18:12

One of the questions a lot of people keep asking me, is how I learned how to create World of Warcraft addons, and how they can achieve the same. I would love to give a simple answer to this, but there just isn't one. I didn't learn it from a single book, or a single website, there was no simple trick to it. I got all my knowledge in bits and pieces from a multitude of sources, and it took quite some time to make sense of it all. My goal is to make it a bit easier for you!

In these tutorials I will step by step teach you about the WoW addon environment, and how to create addons of your own. We'll be covering everything from getting a basic understanding of the Lua programming language, to advanced elements such as secure frames and animations. Don't worry if you have no clue what I'm talking about. In a few weeks you will!

Today we want be doing any actual coding, but rather clear up some common misconceptions about what addons can and cannot do, as well as get an overview over available online resources and what you need to get ready. So let's get started!

Table of Contents

  1. What are WoW addons
    1. Are they safe?
    2. Addons are copyrighted
    3. Blizzard's Addon Policy
  2. Things addons can't do
  3. Getting ready
  4. Useful resources
  5. Viewing Blizzard's interface code
    1. Extract the files from the client yourself
    2. Download the source code from the Web
    3. Browse the code online

What are WoW addons?

Addons are small pieces of software that extend parts of the World of Warcraft User Interface. They are written in Lua and XML, and can easily be modified or created by the end user, you. Addons do not replace any of Blizzard's original code, they can only add to it, therefore the name "addons".

Are they safe?

Addons are technically speaking scripts, not programs. They all consist of unencrypted text files, and are completely open to view and modify. They don't contain any executable code, nor do they have access to modify the filesystem, or connect to the Internet in any shape of form. Therefore they cannot contain viruses, trojans, or in any way harm your computer. So any rumors you've heard about people claiming to have been "hacked" after installing an addon... they're all utter nonsense. Account theft can happen in a number of ways, but putting a text file on your hard drive is NOT one of them.

Addons are copyrighted

You are free to study, analyze and modify any existing addon for personal use. Just keep in mind that even free addons are copyrighted software subject to copyright laws, and you may not redistribute them unless the addon license explicitly gives you permission to do so, or you have a written permission from the author. Never confuse "free" with "public domain", they are not the same things!

Left: standard UI with no addons loaded, Right: the UI with various addons including gUI3 loaded

Blizzard's Addon Policy

In 2009, Blizzard posted their official World of Warcraft User Interface Add-On Development Policy. The policy contain information about what you are allowed to put in an addon, and what you're not. As an example you are not allowed to advertise goods or products from within an addon, nor ask the user for donations.

Seeing how Blizzard in the past have changed their API several times to block the functionality of addons that were breaking the policy, and popular addon sites like WoWInterface and Curse will refuse to host your addon if it breaks the policy, you should consider taking a look at it if your intention is to release your addons to the puclic. You can read the policy here.

▲ Go back to the top

Things addons can't do

Even though addons can be very powerful, they are not bots. They cannot automate the gameplay or make decisions for you. Any and all character actions, or actions affecting the 3D world require a user action through real hardware input. Below is a list of things addons can't do, ever. The list is compiled by Phanx. Source: http://www.wowinterface.com/forums/showthread.php?t=42367

Addons cannot access anything outside of WoW.

  • You cannot read from or post to Facebook, Twitter, RSS, etc.
  • You cannot connect to Facebook chat, Skype, etc.
  • You cannot read from or write to files on the hard disk.
  • You cannot show what song is currently playing in Winamp.
  • You cannot show who's talking in Ventrilo.

Addons cannot load arbitrary URLs in the in-game browser.

  • The in-game browser can only display specific Battle.net account and support pages allowed by Blizzard.

Addons cannot change models, textures, spell animations, enchant glows, or any other 3D graphics.

  • Anything that is part of the 3D game world is off-limits to addons.

Addons can only know about the threat tables of mobs you or someone in your party/raid are targeting.

  • You cannot have a multi-target threat meter.
  • You cannot automatically mark mobs that nobody in your group is targeting.

Addons cannot change or even see minimap tracking dots.

  • You cannot have an alert when a tracking dot appears.
  • You cannot change herbs and mines to have different icons from each other.

Addons cannot target mobs by their raid target icon.

  • You cannot write an addon that lets you "target whatever mob has a skull on it right now".
  • This addon is the closest you can get.

Addons cannot tell which direction mobs or other players are facing.

  • You cannot have an addon that tells you if you can use Backstab right now.

Addons cannot tell whether mobs or players are within your line of sight.

  • You can only catch the "not in line of sight" error message and make assumptions about whether the same mob/player is still out of LOS in the future.

Addons cannot determine the position of mobs or players outside of your group.

  • You cannot tell exactly how far away something is from you.
  • You can only get a general idea by checking to see if spells are in range.

Addons cannot get Z-coordinates (height above ground or relative to objects).

  • You can only get X,Y coordinates.

Addons cannot determine the camera's direction and/or angle.

  • This is why AVR doesn't work anymore.

Addons cannot automatically perform secure/protected actions.

These actions require a hardware event, such as clicking a button on your mouse or pressing a key on your keyboard, and include:

  • Casting a spell
  • Stopping a spell cast
  • Cancelling a shapeshift type buff
  • Cancelling a non-shapeshift buff while in combat
  • Using an item
  • Targeting or untargeting any unit
  • Setting, clearing, or changing your focus unit
  • Running a macro
  • Stopping a macro
  • Editing a macro while in combat
  • Sending a guild invitation
  • Accepting a Dungeon/Raid/Scenario Finder or Battleground group
  • Completing a trade
  • Moving the camera
  • Moving your character
  • Requesting a duel
  • Accepting a duel
  • Removing someone from your group while in combat
  • Adding, removing, or changing key bindings while in combat
  • Changing action bar pages
  • Reloading the UI
  • Changing your character's title
  • Cancelling an automated logout, such as after you've been AFK for 30 minutes, while in an inn or major city (resting)

Addons cannot show, hide, move, or resize secure frames while in combat, except in response to certain limited conditions.

Secure frames are those which can perform one of the actions listed above when clicked on, such as action buttons or unit frames. The allowed conditions are the same as those usable in macros:

  • Your actionbar page changed
  • You entered/left combat
  • A specific unit became hostile/friendly/dead/alive/existent/nonexistent (eg. your target, or your focus)
  • You equipped a particular item type (eg. a shield, or a two-handed axe)
  • You entered/left an area where flying mounts are usable
  • You started/stopped flying
  • You joined/left a party/raid group
  • You entered/left an indoor/outdoor area
  • You pressed/released a modifier key (shift, alt, or ctrl)
  • You mounted/dismounted
  • You switched specs
  • You switched stances/forms
  • You entered/left stealth
  • You started/stopped swimming
  • You or the specified unit entered/left a vehicle

Note that health, mana, buffs, debuffs, and cooldowns cannot be checked in a macro conditional, and cannot be used to show/hide a secure frame.

▲ Go back to the top

Getting ready

In order to create your own addons, there are certain things you should have in place. First and foremost, you need a text editor. Any will do, but I would recommend those that allow syntax highlighting for various programming languages. I personally prefer Notepad++ for Windows. For Mac users I recommend TextWrangler.

Furthermore you should have some sort of error handler, as the default error frame in WoW is pretty much unusable for programmers. The two most common error handlers, are BugSack (which also requires BugGrabber), and Swatter. Swatter is a part of the Auctioneer Suite, but can be extracted and run on its own. I personally prefer BugSack/BugGrabber.

Last but not least, you should have a basic understand of the Lua programming language, and XML formatting. These are however not required to benefit from these tutorials, as we will be covering the basics, and you're likely to pick up a lot of essentials as you progress. If you're impatient and wish to dive into Lua as fast as possible, feel free to take a look at the official Lua Tutorial to get a basic understanding of the Lua programming language used by WoW addons!

Notepad++ has long been my text editor of choice

Useful resources

Last but not least there's a few online resources I would like you to take note of. We'll be using them all later on, some more than others. Feel free to take a look at them, but dont' worry much about what they are. For now I just want you to know about them, then we'll get into the details later!

▲ Go back to the top

Viewing Blizzard's interface code

You will learn alot about addon creation from these tutorials or similar, or by studying the code of other addon developers. But at some point you would want to study Blizzard's own interface code. All we know about addon development and the WoW API comes from doing just that, as Blizzard haven't released any public documentation on the subject, and probably never will.

There are several ways to gain access to Blizzard's code, and here are the most common ones.

1. Extract the files from the client yourself

This is how I prefer to do it, as this is the only way to guarantee I have the most up to date code available. I wrote a tutorial on how to do this here!

2. Download the source code from the Web

Addon developer Tekkub keeps an updated repository of the WoW interface source code over at GitHub. It's almost always perfectly updated, and you can download a zip-file of the entire thing to your computer. You can get it here!

3. Browse the code online

There are several hosted versions of the Blizzard interface code available online. My personal favorite is WowProgramming's online XML browser. I would strongly recommend downloading or extracting the code, though. Amongst many other good reasons, the ability to seek out specific line numbers in specific files will be an advantage later on, and you can't do that with the online browser.

Last Words

Whether you're completely overwhelmed by all the information, or just impatient and annoyed that I wasted your time with stuff you'd already figured out, this is it for today!

Next time we'll be taking a look at the addon folder- and file structure, and learn what file- and media formats are supported by World of Warcraft addons. Until then, cheerio!

▲ Go back to the top

Read More