Saturday, May 9, 2015 - 21:34

So I'm getting ready to start what I hope will be a YouTube series. A little thing I've been talking about called "Gold Farming For Dummies". But before I actually start it, I decided to try out a few experiments, see just how much I could dumb things down and still have solid gains. Looking fairly good so far.

Gold Farming For Dummies...?

Yeah. It's not meant as an insult or anything. It's more meant as a way for people that aren't overly fond of the auction house, market analysis, grinding or any other other time consuming geek stuff to earn enough gold to never worry about gold again in World of Warcraft. I guess "Gold Farming For Casuals" might have been a better title, but you know... humor and all.

I used to think gold farming was about maximizing profit. And sure, it sort of is. But these days I find myself more and more tilting towards the idea that it instead should be about minimizing effort. Because after all, what exactly is gold? Gold is a time sink. You need gold to raid, to upgrade your new gear with enchants and gems, to buy new buildings in your garrison, to buy followers and to buy heirlooms to easier level alts. You need gold to be able to spend less time preparing, and more time playing the so called game itself.

So naturally, if spending less time is the goal, then it wouldn't make much sense to expect people to spend a lot of time farming gold, now... would it? So what I'm trying to figure out is whether or not you with success can get rich playing like a moron, hardly spending minutes daily on the gold game. And it's looking good so far.

I'm using some rather advanced addons, but I only use the most brainless features in them. Because in the end it's all about keeping it simple.

So, anything that separates WoD from previous expansions?

Funny that you should ask. Because there are a few differences. The gaming is the same as ever before. Classes are imbalanced, we 3-shot each other in PvP, raids are never a challenge except that of managing the loot-hungry non-gamers in the raid group itself, questing is brainless, and everybody thinks they're better than everybody else, while in fact they're all at the level of the ghosts in Pacman. Or the ping-pong ball in Pong.

The difference is in the garrison. Your own little fort, your own little mini-city within the gaming world. This is both the single coolest and the single worst element they have introduced into the game so far.

Remember how I earned 1000g or more daily just by using my farm in MoP? Well, imagine what I earn simply by using a full freaking garrison with a mine, a herb garden, and tons of other profitable elements. I don't even need to spend much time. Nor do I need to understand any market at all. Though thruth be given, I did work in sales, retail and marketing for quite a few years, so my "no understanding at all" might not be the same as your "no understanding at all". To me WoW is a kid's game, and everything here including the gold game is easy. For people with a different background, it might not be so.

Single coolest and single worst?

The garrison pretty much turns it into a single player game, which I always considered it as anyway. But it also means that everything and anything that require a group effort, stands out as horrible in a much greater manner than before. The "game" caters more and more to those that expect something for nothing, and group management suffers from it. Apart from the really old guilds where mostly the really old members still recide, World of Warcraft has turned into a social nightmare. If you enter this game with good intentions, you might as well walk naked through a war zone with a sign saying "rape me" on your back. So get a guild, get a garrison, and stick with it.

From a gold farming perspective this is good news, though. It has always been my strong conviction that the only good way to farm gold was not to beat your competition, but avoid or eliminate it. Since everything in your garrison is instanced or phased, there will never be anybody but you and those you choose to invite in there. And all the resources are yours and only yours. Sure, there is still competition at the auction house, but that is where my "For Dummies" perspective will come in handy, not to mention my sales and retail experience. I don't see quite the same things as others see.

Since forever I have favored instanced farming. Either alone or grouped. But the point isn't simply that you're in an instance. It's that you are able to farm something that's in demand, without interruptions, without having to worry about kill stealers, ninjas, or higher level PvP players with tiny genitalia looking to compensate. Instanced farming can be planned, measured in gold per hour, or sometimes even gold per minute. It's a way for casuals like you and me to eliminate the stress factors, the uncertainties from the equations. It allows us to plan our success, to plan our income. Not unlike life itself. It allows us to spend our time and energy on other things that truly matters. Like your wife, or friends, or children. You know?

So your goal is... what?

My goal is to NOT spend time. We all want to be able to buy whatever the auction house or blizzard throws at us when we want it, or when we fool ourselves into thinking we "need" it. But do you really want to spend hours and days and weeks grinding for something in a game? If there are ways you can achieve the same without much thought or effort, just with some simple planning and measures?

This my friends, is my goal. Not to maximize profit, not to reveal revolutionary secrets or post horribly complicated guides and tutorials that require an economics major to even begin to understand. My goal is to eliminate the job altogether. To minimize stress. To allow us all to redirect our mental energies to where we truly want them to be.

For me that happens to be a sixpack of beer and a blonde at the local pub. So see you all around! I'll be starting my gold farming series in the near future. Either here, on YouTube, or both! SKÅL! :)

▲ Go back to the top

Read More
20:40

Yeah, that's pretty much my point of view, and has been for quite some time. World of Warcraft is not a game. And the people playing it aren't gamers, at least not if that is the "game" they spend the most time "playing".

What do you mean "not a game"?

Where are the goals? Where are the objectives? Where is there a single challenge you have to beat that doesn't include repeated grinding? Where is there a group challenge where the challenge isn't the group itself? Where are the experiences that permanently will truly improve you as a gamer? And don't tell me "raids" or "arena". That'll just reveal how much of a not gamer you are.

In games, the gamer becomes better over time. The gamer acquires skill. In Super Mario 3 I could jump like a god, I could take out advanced challenges simply do to my skills. In WoW, you don't get better. Your character gets better. That's pretty much the case with most MMOs, but WoW is by far the worst sinner. It's not even an attempt at a challenge, it's just an interactive movie, more or less. You hit your skill peak mere days or weeks after you start the game. And from there it's all about the grind.

I admit PvP at top levels can be a little more competitive and interesting than the rest of World of Warcraft. But are the classes balanced? Are the class combinations balanced? Can a good PvP'er pick any class and succeed just as well? Is the outcome decided by what people do in the match, or by weeks and months of planning? Are you a gamer or a freaking city planner? I'll take a game of chess or ping pong over an arena match any given day. THOSE are games!

So what is it then?

World of Warcraft is a social experiment. It introduces a tiny society with very few rules, where power and advantages over others are the main factors. And like all jobs and positions that give power and authority over others, it attracts bad elements. Just like every catholic priest is a pedofile waiting to happen, every WoW gamer is a potential sadist, a closet psychopath. Somebody who has a reason for doing this instead of something else. The exact kind of person that in fact should NOT be engaging in social experiments, unless you want it to end badly.

The people that troll you, ninjaloot, corpse farm, tea bag and whatnot, they're creeps in real life too. They probably hide it, like they hide behind their false penis enlarging toon name in-game. But they are.

But of course there are good people in there too. People that just consider it to be a fun social engagement with friends. A nice as any way to spend a Friday night or whatever. A way to spend time with nice folks without having to leave your couch, or dress up for. Because not every kindergarden teacher is a pedophile, and every cop isn't corrupt. There are good people everywhere. But they're getting kind of drowned out in environments that cater so much to the worst of us. Which is why people make guilds, and often have a pretty strict application process. Because they wish to create a safe little bubble in this ocean of madness. But it's still not a game. More like a tea party. Or possibly synchronized swimming. Raids can at times feel like just that. Synchronized swimming with tea parties in between the "hard" parts. But still not a game!

So why do you play it, then?

Well, do I? I farm gold, and I do this by never leaving my garrison. Ever. Gold used to be fun, now it's so easy to get I can't even see why I should bother anymore. I don't need to interact, I don't need to spend time or apply any sort of real skill. No gaming element in that whatsoever.

And of course I make addons. And it's my personal opinion that I'm getting pretty good at it. Feel free to disagree. I take pride in delivering the best user experience I can. Making my user interfaces and all the code and graphics that went with it was quite a challenge. That was fun. That was rewarding. That gave me a reason to stick around.

But that's pretty much all I do too. I don't really quest except when leveling alts for some experiment, or enjoying the solo content of the mini-game called "new expansion", which consists of 3 days of consistent questing which more often than not feels like an interactive movie, and then it stops. Then it's done. Then it's back to addons and the auction house.

And all my bnet friends are my addon users. All of them, actually. I don't interact with the general population anymore. Because in the end, I pretty much felt like I was talking to religious fanatics. Better to just not.

So... why should we care?

Who said you should? I'm just making a statement in my own little bubble here. Took me a few minutes on a laptop in a motel room. I felt like saying this, so I said it! Care or not, I care not! :)

▲ Go back to the top

Read More
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