Jahwo's AddOn Writing Guide

Jahwo's picture

In this guide I will give you a pretty extensive introduction on how to write your own World of Warcraft AddOns. While following this Guide you will write your first AddOn, called WoW-ProFit which keeps track of your money profits and deficits.

You don't need any programming experience if you want to follow this guide, but it would of course be helpful, as I can't possibly explain every nut, bolt and screw. Some talent for independent thinking might be useful, too. Sticking out tongue

If any questions or problems occur, please feel free to ask me via PM or Comment.

Table of Contents


This guide has been written for learning-by-doing, so roll up your sleeves and prepare for hard work!
No seriously, please don't just read the guide an try to memorize something, this would have absouletely no use and it would completely spoil the fun you have while writing your first own AddOn. (That's why the WoW-ProFit AddOn won't be available as a download!)

As you will see, the Guide is based on steps. The steps can consist out of three different "segments":

The green segment will have a short introduction on what will be done in this step
The grey segment is the place for XML code-snippets
The purple segment is the place for lua code-snippets
The blue segment contains the explanations for what has been done in the code.

The star means that there are some visible changes, so it might be a good idea to look at your AddOn in the game. Smiling

The little AddOn you will write during this guide will show you exactly how much money you have spent or earned in the current playing session. Additionally it keeps track over all the session since it's installation and can display the all-time profit/deficit. This is what it will look like:

WoW-ProFit includes pretty much everything that is needed for this "basic" introduction.

Nevertheless you have to note, that this Guide won't give you ALL information you need to write professional AddOns like Cartographer or TourGuide, but it is definitely a step in the right direction Eye

So never despair, keep cool and have fun!


Everything you need for creating your own AddOns is a simple text editor and, of course World of Warcraft to test you AddOns.

If you want you can follow this guide only with Window's Notepad but I really suggest to use a texteditor that supports syntax-highlighting. The one I recommend and use is

It's open-source software, and as such free to download. It supports syntax-highlighting for many many languages, including lua and xml, which we will be using. Also it has the possibility to record Macros and a lot of other handy things you will find out yourself Smiling

An other quite useful tool, which is completely optional for this guide, is
It's an XML-Editor by Microsoft which comes in really handy if you have to struggle with huge xml-files. I won't explain how it works exactly, so if you want to use it you will have to catch on with it yourself. NotePad++ will suffice for this guide as our xml file won't become too big.

What is an AddOn

As you probably know, an AddOn is a way to customize, modify and extend you User Interface.
Most people know that an AddOn consists at out of one folder and some files.
But only a few people know what is going on inside those folders and files, and that's where we will head in this guide.

AddOns are located in a AddOn folder. The path is:

World of Warcraft\Interface\AddOns\

Every AddOn has it's own folder in there and in every addon folder you will most probably find three different types of files:

  1. The .toc file:
    TOC is the abbreviation for Table of Contents and that's exactly what it is. It contains a reference to every file you want to include to the addon. Also it conatins some parameters which describe the addon to WoW. The name of the .toc file has to be the same as the name of the folder it is in.

  2. The .lua files:
    Those files contain (most of) the logic.

  3. The .xml files:
    Those files contain the "design" of your buttons, textures, frames etc.


Before we actually start coding we will prepare the file and order structure. As said above, all our files have to be in their own folder and our .toc file has to have the same name as this folder.

So, in your AddOns folder, create a new folder called "WoWProFit" and create the following files:

Now open the WoWProFit.toc file and write the following lines:
Every line with a ## in the front represents a parameter. There are lots and lots of them. If you really want to learn everything about the .toc file format I recommend you visit the wowwiki page about it.
Interface: tells World of Warcraft for which client version the AddOn was written. If you want to know how to get the current number look here Current Interface number: 30300 (07 January 2010)
Title: is the title of the AddOn that will appear in the AddOn list at the character select screen.
Note: is a description that will be shown under the title.
Author: your name Eye
The last two lines are the filenames of the files we want to include to our AddOn.

The Frame

Now we will create the background and borders for our AddOn. For this we will edit our .xml file and add a Frame. But first of all, a short introduction about XML:

Notes on XML:

If you never programmed before this might need some explanation. XML works with so called tags, you probably already met something similar here on WoWPro if you ever formatted some text.

A tag looks like this: <tag>.

Tags generally get opened and closed again. Closing tags have a slash (/) in the front: </tag>.

Tags can be closed in their opening tag, looks like this: <tag parameter="stuff" /> (note the slash at the end)

As you can see, it is possible (and often used) to add parameters in the tag.

Everything between the opening and ending of a tag will either influence it or will be influenced by it.

Don't worry if you have problems understanding this, it's not very hard. Just follow the guide and everything will explain itself. Smiling

Open the WoWProFit.xml file and write the following lines
The <Ui> element is the only really needed tag in the .xml file. It just has to be there Eye

The <Frame> element, how could it be different, represents the frame we are about to create.

We've already given our frame a specific name, with the name parameter. I called it "WoWProFit_MainFrame" because this name is really clear to everyone who reads it. If you somewhen write your own AddOns it'd be nice for you and other people if you give your stuff reasonable names.

A prefix like WoWProFit is not necessary, but again it increases the understandibility and prevents interferences with other AddOns.

There are three things we need to do before we can see our frame in the game: give it a size, anchor it to a point and create a backdrop. At first we will give it a size
The <Size> element contains the size information for the frame. This information can be give with different tags.

We use the <AbsDimension> tag which takes two parameters. The width of our frame as x and the height as y. The values given are in absolute pixel. Thats why it is called AbsDimension.

Another possibility would have been the <RelDimension> tag which, other than our tag takes the values relative to the screen, from 0 to 1. (Means x="0.5" and y="0.5" would be exactly the half of the whole screen)

The width doesn't really matter in our case, because we will have to set it dynamically later on, but for now we set it to 120 so we will see something. The height of 20 pixel is the final height for the frame!

Now we anchor the frame to the center of the screen
We added a new parameter to our frame, parent="UIParent". This means that our frame is the child of the UIParent, which represents the whole screen. We'll need this information in the next tags.

The <Anchors> tags contain all the anchors of the object. In our case it has only one.

Anchors place one point of an object (here the frame) on a point of another object. There are different "versions" of anchors but we just use the simplest of them.

Our <Anchor> element takes just one point parameter, which contains "CENTER". This means that the center of our frame will be anchored to the center of it's parent, which we defined before (the UIParent).

The next thing is the backdrop. This is a little bit more complex so we'll begin just with the background and leave the borders away.
We "create" the backdrop with the <Backdrop> element. The image-file is given in the bgfile parameter. The path we use shows to the background image of tooltips. The parameter tile="true" says that the background will be composed out of many tiles of the same size instead of stretching one texture to the needed size.

The size of those tiles is defined in the <TileSize> tag which works pretty much the same as the <Size> we used for the whole frame. The difference is that the tiles are squares and therefore we only need one dimension instead of two.
This means we use a tag called <AbsValue> which takes only one parameter called val. We choose a size of 16 * 16 pixel for our tiles.

Informations about how to find the paths to WoW-images can be found in the Appendix

Time for a test-run:

Save your files now and start your World of Warcraft client. Log in and check if this entry is ticked in the AddOns list:

Log into your favorite character and you should see a slightly transparent bar in the middle of the screen

If not, don't be upset, just go through the previous steps again. Adversity is the school of wisdom.

Next we want to add some borders to our frame. For this we need a file that contains all edges and sides and have to define their size
The edgeFile parameter contains the path to the file we want to use. This is what our file looks like:

As you can see it contains all possible sides and edges for a nice bordered rectangle. Because of this we need to define how the file has to be split.

We have to specify the size of the "tiles" we want to make out of this file with the <EdgeSize> tag. It works exactly like the <TileSize> element. We need to split the file into 16 * 16 pixel tiles.

If you look at your AddOn now in the game you would notice that the background is somehow visible outside of the borders. We can fix this by adding a new element that scales only the background.
The <BackgroundInsets> element is used to scale the background. It requires another tag:

The <AbsInsets> tag is similar to the other Abs tags we already used but it takes four arguments: left, right, top, bottom. Those specify how many pixel the approprate side moves to the center of the frame. The values given in the snippet above are perfect for our case.

Now there's only one thing left for the backdrop. If you compare your current frame to the screenshot in the Introduction, you can see that our background is much brighter. So now we change the color of the background.
The <Color> tag will change the color of the background. The color will be composed out of the r, g and b paramters. Those represent the parts of red, green and blue. The values go from 0 to 1. For example if all three parameters are 1 it would be white (what would actually have no effect to the texture), whereas 0 would be black. The a parameter is the alpha of the background, again from 0 to 1, where 0 is transparent and 1 is opague.

Very well, the frame is finished, though we'll have to make some dynamical changes to it later on. Nevertheless, be happy about what you've done so far. Smiling

A Button

In this chapter we will add the button that will allow us to display the all-time profit/deficit.

We can use most of the things we've already learned from the frame on the button as well, because it is derived from the frame element and therefore is a frame too.

We have to add a new element that will contain all Objects of the frame
Between the <Frames> tags will be all objects that are somehow derived from the Frame object. Those are for example buttons, as we will use one, scrollframes or editboxes. Of course we could also add other [=14]<Frame>s to the frame.

Every object in a <Frames> element has the frame it is in as a parent, in our case the WoWProFit_MainFrame (if we don't say otherwise with a parent parameter)

A button object can easily be added with the <Button> argument which in terms of size and anchors works exactly the same as pure frames.
The analogies of the <Button> element to the <Frame> element are obvious. It has inherited the same parameters and has the same embedded tags like <Size>

The $parent argument in the name of the button refers to the name of it's parent. As said above the parent is WoWProFit_MainFrame, and so the complete name of our button is "WoWProFit_MainFrame_Button"

Everything else you can see here should be clear. If not search the The Frame chapter for the here used tags.

Of course we can't save ourself from the anchoring and this time we need to specify an offset to make it look good in the end.
The point of the <Anchor> tag is "TOPLEFT" which only means that the topleft point of the button will be anchored to the topleft point of it's parent (our MainFrame, as explained above)

This time we opened the <Anchor> tag and inserted a new element, the <Offset>. It takes the already known <AbsDimension> tag. The given x and y values move the anchor-point to the right and the top, because the origin of the coordinate system is in the bottomleft corner of the screen.

We move the point 3 pixel to the right and 3 pixel down, so that our 15*15 pixel sized button is approximately vertically centered in our 20 pixel high frame.

Instead of a background we will use different textures for the different states our button can have (Normal, Highlighted, Pressed or Inactive). Let's begin with the normal texture
The path to the texture we want to use has to be given in the file paramter of the <NormalTexture> tag.

The problem with the texture we use is that it in fact is multiple textures in one file:

We only want to use the first blue circle thingy as our texture so we somehow have to cut it out. That's where the <TexCoords> tag comes in.

<TexCoords> with four arguments as we use it cuts out a part of the texture. The argument left defines where the left side of the piece is. The value given to it is a relative value that expresses a distance from the left side of the whole texture.
For example if it's 0.25 it would be one fourth of the width of the whole texture.

The same thing applies to the right parameter, only this one defines where the right side of the piece is.

Similar to this work top and bottom, only that it's relative to the height and from the top.

In our case we want to keep the left side, so left is "0". The right side is "0.125" because we have 8 different textures in the row and 1 / 8 = 0.125
The top stays the same, so "0". The bottom is exactly the half of the height.

If you have problems understanding this, just play around with the values and look at the results ingame, as you should see the button there by now.

We will use the slightly brighter blue button as our highlighted texture. This one will be shown if the mouse is over the button.
The principle of the <HighlightTexture> tag is completely the same as for the normal one, we only have to change the left and right parameters of the <TexCoords> so that it cuts out the second button.

Textures and FontStrings

Even the <Frame> element has an object it's derived from, the <LayoutFrame>. Now this object is also the parent of <Texture> and <FontString> objects, which we will use now. The fact that they are not derived from <Frame> means that they do not fit into the <Frames> element, we need something else...

FontStrings and Textures can be implemented in one of five Layers
The <Layers> element contains the different layers.

The <Layer> tag is similar to the <Frame> element, but it takes an parameter called level. With it you can define on which "height" the elements in it are placed. Elements in higher levels cover elements in lower levels.
The possible levels are, from highest to lowest:

The level ARTWORK is just fine for our case.

Let's begin with the text for the gold amount. We need a <FontString> object for this. There is not mouch new here so prepare for some more lines of code:
The <FontString> tag creates a new text label element. There are a few new parameters, but nothing too hard.

The name given in inherits is the name of a <Font> object, that defines which font is used and which size it has. You can find the by default inheritable fonts here, but I won't explain this file Sticking out tongue

The text that will be shown is given text parameter. We set it to "0", this will be changed dynamically later on.

JustifyV and JustifyH control how the text is justified. We want it to be horizontally on the "RIGHT" and vertically at the "TOP"

The <Size> and <Anchors> stuff should be clear in this case.

Because the profit at the beginnning of a session is 0 we want the text to appear yellow. We can use the <Color> tag for this again.

Now that we've got the text we want that little gold texture next to it
Not much new here again. We create the texture with the pretty straightforward <Texture> tag and provide a texture file in the file paramter.

Even though the files size is not 10 * 10 it will be adjusted automatically.

The anchoring for our gold texture is a bit more interesting as we don't want it to be anchored to it's parent and not even to the same point.
As you can see there are two new parameters in the <Anchor> tag.

The relativeTo parameter takes the object the Anchor will be relative to. We want the texture to be next to the text we made two steps before, so we give the name of the <FontString> object to the relativeTo parameter.

We also want the texture to be on the right side of the text. This can be accomplished easily if we anchor the topleft point of our <Texture> to the topright point of the <FontString>. We do this with the relativePoint parameter.

The small horizontal Offset is only for some distance between the two objects.

The silver <FontString> and <Texture> is only copy and paste work.
The only new thing here is that <Anchor> of the <FontString> object is relative to it's neighbor texture as well.

Changes have been made in the name of the <FontString> and <Texture> and the relativeTo parameter has been adjusted.

Of course the file of the texture has to be changed, too.

Only copy and paste work for the copper stuff.
Again there are changes in the name, file and relativeTo parameters.

Drag and Drop

Now it's time to implement some interactivity with the frame. As a beginning we want the frame to be dragable.

We have to add two parameters to our frame, so that it is movable and that we can use the mouse on it.
movable="true" makes the frame movable

enableMouse="true" allows us to retrieve mouse events like clicking, which we need in the next steps.

We want the frame to start moving if we press the mouse button down and we want it to stop moving if we realease it. So we now add two so called Even-handlers.
The <scripts> element contains all Event-Handlers for the object it is in. We want the frame to be dragable on click, so we put it into the <Frame> obejct.

<OnMouseDown> is such an Event-Handler. Everything between it's tags is actual lua-code and will be executed if the event is fired. For this tag it is fired if the user presses a mouse button down on the frame.

<OnMouseUp> is an event that is fired if a mouse button is released.

Now it's tmie to switch into our WoWProFit.lua file and write our first function. This one will make our MainFrame start moving.
The statement function opens a new function and WoWProFit_MainFrame_OnMouseDown is it's name. Again it's a matter of clearness, as this name explains exactly what it is for on the first view.

The two brackets () after the name is the place where we can add parameters for our function. We don't need any.

The end statement closes the function.

Our frame WoWProFit_MainFrame has member functions that will have an effect on it.
In the second line you can see how they are called. First there is the name of the frame followed by a colon and the name of the function with the brackets for eventual parameters.

The function StartMoving() causes our frame to move with the mouse cursor.

The function that makes the MainFrame stop looks pretty much the same
This time we call the StopMovingOrSizing() function which does exactly what the name says Eye

Now that we've written our functions we can call them in the Event-Handlers.
Every time the MouseDown event is fired, it will call our WoWProFit_OnMouseDown() function, and therefore make the frame start moving.

Same thing with MouseUp only that it will result in making the frame stop moving.


Some presets and stuff like that we need to sort out while loading the AddOn.

Three variables at startup
The WoWProFit_LastMoney variable will contain the money before it has been updated, so we can calculate a difference.

The WoWProFit_MadeProfit is a boolean variable. This means it can have the states true or false. We will use it to control if a new entry in the all time history has been made or not.

The curly brackets indicate that WoWProFit_History is a table. Tables are variables that kind of contain a list of other variables. We use it to store the all-time history of profits and deficits. It does not matter if the table contains something, because it will be overwritten with the saved data we create in the next step.

The WoWProFit_History table has to be saved, so that we can update it in every new plaing session. For this we need to edit our .toc file again.
The SavedVariablesPerCharacter parameter is a list of variables that will be saved for each character. We want our History to be saved.

The saved variable can be found in the file World of Warcraft\WTF\Account\ACCOUNTNAME\REALM\CHARACTERNAME\SavedVariables\WoWProFit.lua

The loading of the variable is one of the last things that happen during the initialization process. That's why we can define it as an empty table, because it will be overwritten with the saved data, if there is any.

Now we write a function that is supposed to be executed on startup.
In this function we give our LastMoney variable a value, so that we will have something to compare to on the first money update.

The function GetMoney() returns the current money of the player in copper. This means that for example 1 gold 12 silver 85 copper would be returned as 11285.

Let's give this function an Event-Handler
The <OnLoad> Event-Handler is fired on initialization, just as we need it.

We don't want our frame to be too long anymore, so we write a function that sets the width of our frame so that it perfectly fits with the width of the FontStrings and Textures.
We create a local variable. This means it is only available inside this function and will be deleted after it's execution. This is a very important way to save memory.

width has a startup value of 65. This is the sum of all fix width in our frame: The button of 20pixel width, the offset of 5pixel, five times the offset of 2 pixel and three times 10pixel wide textures.

Then we add the width of the texts to the total width. You have to know that the right side of an assignment is always calculated first. That's why we can use the same variable left and right.

The function GetStringWidth() of the FontString object returns the width the text has, not the object!

We do this three times, for the gold, silver and copper FontStrings.

Finally we set the width of our WoWProFit_MainFrame with the SetWidth() function. We give it our just calculated total width as a parameter.

Now we can use this function in our OnLoad function so that the frame has the correct width on initialization.

Money Matters

Finally it's time to make the AddOn do what it is supposed to do; keeping track of profits.

We do need a event that allows us to efficently update our AddOn. The event we will use is called PLAYER_MONEY and it's fired if the user somehow changes his wealth. The problem is that this event is not "included" to our frame, so we have no event handler for it. But don't worry, we can register it to our frame.
The RegisterEvent() function registers an event for our frame. This does not create a special event handler for it, but the so called <OnEvent> handler will be executed if the PLAYER_MONEY event is fired.

Let's add the <OnEvent> handler in out .xml file and let it call a function.
<OnEvent> is executed with every event that is registered to the frame. To distinguish which one has been fired there is the variable event, which contains the event's name and is available for everything in the event handler.

We'll write the WoWProFit_OnEvent() function in the next step.

We write the function we just called in the event handler. It has to check if the PLAYER_MONEY event has been fired.
An if clause is a way to check conditions.

The if clause begins with the if, followed by a condition. The event variable contains the name of the event that has been fired. With the double equality sign we check if it equals "PLAYER_MONEY".

If this condition is true, everything between the then and it's end statement will be executed.

We want to create a new entry in the History list, if it hasn't been done yet.
This if clause checks if the variable WoWProFit_MadeProfit is not true! This means the condition is true if the variable is false. We've set this varuable false in the initialization so this condition will be true the first time there is a money update.

If the conition is true this also means there has been no update before, and therefore we want to create a new entry in the WoWProFit_History variable. We do this with the table.insert() function.

We give it three parameters.
The first one is the table variable we want to insert a new element.
The second one is the position where the element is inserted. We choose the first position.
The last one is the value that is inserted, we set it to 0 because there has not been any profit until now.

Remember that now that we have changed the History variable, it will be saved with the new values if the player logs out!

Now that we definitely have a individual entry for the current session in our history table, we can calculate the money difference and add it to our history.
We can calculate a difference by subtracting the money we had before the change (WoWProFit_LastMoney) from the current money, which we get with GetMoney(). We save it in the local variable difference.

Now we add the difference to the current state in our history entry. The entry for the current session is the first one, as we added it above. An element of a table can be accessed with the squared brackets with a index number in between. 1 is the first element, which we need.

Finally we set the LastMoney variable to the current money, so we have the right value to compare to the next time.

All our "money variables" contain values in copper, but we want it to be seperated in gold, silver and copper. For this we write an own function.
Aww, maths... Eye

With the abs() function we calculate the absolute value of the commited parameter and store it in the variable absMoney.

Now we calculate the gold part of the money. We do this by dividing the coppers by 10000 and cutting of the decimals with the floor() function.

The silver is calculated pretty much the same, only that we divide by 100 and have to subtract the gold part in copper! Again we have to floor() it.

The copper part is the absMoney subtracted by the gold and silver parts in copper.

Now we return all three calculated values. This means we can say x, y, z = WoWProFit_ReturnMoney(money) where x would be gold, y silver and z copper.

If you did not understand everything, no problem, it's maths after all Eye Such things become clear if you begin developing your own code.

We use this function now to set the text of our FontStrings
We give our history entry to the function we've just written and save the returned values in some local variables.

We set the text of the gold FontString with it's member function SetText() to the gold variable.

It's exactly the same thing for silver and copper.

We changed our text, so it probably is necessary to change the size of the frame. Luckily we wrote a function for that, so we just have to call WoWProFit_ChangeSize().

You can try selling or buying something ingame now and you will see that the profits/deficits are displayed in the AddOn Smiling

One thing is miissing.. We don't know if we made profit or not. So we change the color of the FontStrings to green if it's a profit and to red if it's a deficit.
There are only two really new things here. The condition after the elseif statement is only checked if the conditions of the previous ifs or elseifs were false.

Same thing with the else statment only that it doesn't take a condition. It will be executed if everything before failed.

Oh and SetTextColor() sets the color of the text of the FontString. The parameters are r,g,b and it works like the <Color> tag Smiling

Money Matters II

Only one thing left, we want the AddOn to print the all time profit/deficit of the character in the chat window by clicking on the blue button.

We create an event handler for the button in our .xml file.
The <OnClick> event handler executes if the player clicks on the button.

Let's write the function in the .lua file. First o all we calculate the all time value with a loop.
We create a variable called alltime and set it to 0.

The loop we use is a so called for loop. The way we use it, it goes through every single element of a table.
The statement for initiates the loop. the function pairs() returns the key and the value of the table given in it's paramter element by element.
The key, whch is the index we used before to access the frst element, wll be saved in the k varuable.
The value is what the element contains for this key. It will be saved in v.

Now we can add all the values to our alltime variable.

After the loop is finished we have a variable that contains our all time profit or deficit.

We can use our previously written function to sperate this value to gold, silver and copper.
We use our WoWProFit_ReturnMoney() function to fill the local gold, silver and copper variables.

We check if we have a profit or a deficit and display a corresponding message.
If the value is negative it means we have a deficit.

DEFAULT_CHAT_FRAME is an object just like the Buttons or FontStrings we created ourselves. This one is a standard in the game and represents, how could it be different, the default chat frame. It has a member function called AddMessage(), which allows us to add a message to the chat frame.

The function takes a string as a paramter, and in this string we can use so called escape sequences. The one we use is to change the color of a particular part of the text. "|cFFFF0000" makes the folllowing text red. The values following the |c are a color code in hexadecimal notation (more information here).
The first two digits are the alpha value. The following six are for red, green and blue.

The sequence "|r" resets the color to default.

If we have a profit (else) we display a green "profit".

Finally we display the value.
We use the previously created gold, silver and copper variables to show a nicely colored output. Yellow for the gold value, grey for silver and something brownish for copper.

Well done! You've completed the developing of your own WoWProFit AddOn Smiling


What Now?
Now that you've finished this guide and have written the AddOn you should have learned enough to start programming your own AddOns, so be creative, think about what the WoW-Community could need and go to work.

There is only one problem, and that is that you can't possibly know anything you need just by following my guide. For this reason I will give you some links and ressources that helped me a lot when I learned about AddOn writing.

  • wowwiki.com - you probably heard about and used it before. The wowwiki does not only contain informations about game-play issues and lore, it is also a huge knowledge database about pretty much everything you could need for AddOn developing. Nearly every function or event or tag or whatever has an own article with much information. Nevertheless the information can sometimes be a bit cryptic or hard to understand, but you'll make it Eye

  • World of Warcraft API - This is a list on the wowwiki that contains all the WoW-side functions for your lua code.

  • Widget API - This is a list on the wowwiki that contains all the functions for the Widgets (buttons, frames etc.) for your lua code.

  • WoW UI XML Definition - A page by some nice guy who took the time to parse and format the Ui.xsd, which contains the definitions of all the XML Widgets. This is a very good site for loooking up anything concerning your XML code.

  • Google - Eye A very good site to look up basic lua stuff, like loops and so on, but also good for everything else, as you probably know Smiling

If you have no idea what you could do with your new knowledge you could try to imporve the WoWProFit AddOn, as it has some flaws:
The all-time deficit thing does not make much sense, as you might have noticed. If you use it from the creation of a character it would just show you your current amount of money Eye
You could try to change it so it only shows the last ten history elements. Furthermore you could implement slash commands for it. Or just completely redesign it. Do whatever you like with it, it's completely yours!
If you did improve the AddOn somehow I'd be really happy if you could somehow accord it to me.

Something Missing?

I'm really sorry to tell you but there are some pretty elementar things not explained in this guide. For example I did not explain how to implement slash-commands (/whisper stuff) and hotkeys.

You will have to work this stuffe up on your own. This should be no problem with sites like wowwiki.


Here is a short description on how to get the World of Warcraft internal images and how to get their paths.

First of all you need to get Blizzard's World of Warcraft AddOn Kit. You can get it from this page: Blizzard Support

Download the file for your system and install graphics package. After the installation is finished you will find a new folder in your World of Warcraft root folder called "Blizzard Interface Art".

This folder contains files of the type .blp. You won't be able to open those files with most of your standard image viewers.

The program I recommend you to use is XnView. It's a powerful and free image viewer that is able to display .blps in pretty high quality.

Now you can look at the images available for your use. The path you have to use in your AddOn is "Interface\" plus the path relative to the "Blizzard Interface Art" folder. The ".blp" ending has to be left away.

For example the file "Blizzard Interface Art\BankFrame\UI-BankFrame.blp" would be "Interface\BankFrame\UI-BankFrame"

by Jahwo

If you want to use this guide or parts of it on WoW-Pro extern websites, please be so kind to ask me first.


Working version for 5.1.0

I would be happy to send anyone a current working version of this if you are having trouble getting yours working.  There are a couple of changes  from the original, as documented below by  gleinnek.  Otherwise, for those who are wondering, it still does work in 5.1.0.  Send me a message if you would like a copy.

would love a copy

have the framing working, but cant seem to get an event fired... 

Giving AddOns a shot

was following your guide, but when I add the gold coin texture, it just comes up as a gold smudge across my box.. double checked all the code and syntax and content look good... did bliz change something in the icon file?

Updates for Cataclysm

I had to make the following changes for Cataclysm as "event" isn't a global anymore. I also noted the "PLAYER_ENTERING_WORLD" changes


In the WoWProFit.xml:

WoWProFit_OnEvent(self, event, ...)

and in the WoWProFit.lua:

function WoWProFit_OnLoad()

function WoWProFit_OnEvent(self, event, ...)
if event == "PLAYER_ENTERING_WORLD" then
WoWProFit_LastMoney = GetMoney()

if event == "PLAYER_MONEY" then

Hope this helps those of you attempting to learn about addons. I know this guide helped me learn about them. Gene

addon dont show up in game

hi mate I've followed this guide completely (.toc, .lua and .xml) ive updated toc for 4.3 and when you said to check background it worked this was the last time it showed up

ive up loaded my 3 files in a rar file to rapidshare heres the link https://rapidshare.com/files/3346172720/WoWProFit.rar

any help at all would be very greatfull THANK YOU ALL!!

Edit: i spotted the mistake on line 78 where i put + instead of = of the lua

Lycander's picture

WoWProFit help!

Heya, Jahwo. I'm having a couple of issues on the addon.

  • When it loads up, it shows my money at 0, 0, 0. It doesn't update until I buy or sell something, which leads into the next problem:
  • When I do, it shows the correct amount of money but it lists the whole amount money I have as profit, not just what I got from the item I sold.
As an example, say I have 1g on my character. I log in and the addon shows me as having 0 money. If I sell something for 1 silver, the addon will show that I've got 1g 1s 0c. However, if I click the button it says I've made 1g 1s 0c profit. If I log out and log back in, it shows 0 money again. If I sell something else for a silver, it will show me as having 1g 2s 0c but now my all-time profit is 2g 3s 0c, and all I've actually made is 2 silver.

Any idea what it could be? I've gone through the code twice and can't figure it out. Any help from anyone would be greatly appreciated. Thanks!

Money Issues

Hey, been having the same problems, and really throwing me for a loop. Had to do some serious troubleshooting, and found out that LastMoney was not initializing with the GetMoney() at the OnLoad(). So since it was starting out as Zero, when it got down to GetMoney()-LastMoney it would always show what was in your bag. Went round in circles trying to find out why it wasn't initializing, and ended up finding the answer on Wowwiki. On researching the GetMoney() command, it said that it didn't always initialize, and you should wait for "PLAYER_ENTERING_WORLD" before trying to get data from it. So set up another event handler for "PLAYER_ENTERING_WORLD" and put my LastMoney=GetMoney() initialization in there instead, and it worked fine for me.

Hope it works for you too. Smiling

Lycander's picture

Great Guide!

Hey, man. Great guide. I'm using it to try my hand at addons as well, or at least get a better understanging of them. Something I noticed, though.

In the second part of the "Drag and Drop" section you've got a typo. It says Even-Handlers and you refer to them as Event-Handlers the rest of the way.

Just a my two cents worth. The info and layout are top-notch! Thanks again.

Jiyambi's picture

Interface Options Config

Hey Jahwo.

I was wondering if you could give us some insight into using the default Blizzard Interface Options window for our addon configuration information. I am working on disecting the code for other addons that do this, but an explanation would be appreciated Smiling

Jiyambi's picture

Nevermind, found this

Nevermind, found this article about it on WoWWiki: http://www.wowwiki.com/Using_the_Interface_Options_Addons_panel

Just a note, make sure you have your lua file load before your XML file. I was pulling my hair out trying to figure out what I was doing wrong and stumbled across the problem by chance after several hours of frustration. Any "On Load" functions simply won't work if the xml file is listed before the lua one in the toc.

Jiyambi's picture

A more experienced review

Jahwo, I finally went through this primer as part of training myself to work on addons. I have to say you did a really amazing job with it. I noticed a few spelling mistakes here and there in your text, so you might want to run it through a spell checker. But all of the code worked flawlessly. I *especially* appreciated the little star symbol that told me when I could test my work. Testing as I went let me practice troubleshooting as well.

Thanks so much for making this. You rock!

Jahwo's picture

Hey, sorry for the late

sorry for the late answer, if you're still interested you can upload your Code to a one-click-hoster like rapidshare.com and send me the link either via PM or as a reply here. I'll give my best to find your mistake, because it most probably isn't in the guide, sorry Sad


Problem when "Button" is added

Im having the same problem here. Soon as I add the button part of the code it vanish's when I log ingame.

Any help would be very much apriciated

Regards Alex

Jahwo's picture

This guide is now up-to-date

This guide is now up-to-date for 3.3

Jiyambi's picture

Whoah, were'd you come from?

Whoah, were'd you come from? Laughing out loud

Jahwo's picture

Well, I've never been that

Well, I've never been that far away. My "Abitur" is coming closer and that means tons of work for me Sad. So as I saw that you guys were kinda getting inactive aswell my visits here somehow came to a minimum...
Still I want to keep my guides updated so thats what I did now Eye

Funnily enough it seems like right now all the "old members" are rediscovering WoWPro Laughing out loud


Puzzled Ok, so i just got to the end of the Textures and FontStrings part.. went to test my addon, and this happened:

Is it ment to look like that atm? or did i mis-type some coding? i had a few people scan to check it and they all seem to say that its as its ment to be.. Ty for any input

Drudoo's picture

Mine wont even show as yours

Mine wont even show as yours do :s

There was a few times i went

There was a few times i went ot see the addon ingame and it vanished, I found out i was using engliush spellings, like colour, its Color, and also, Capital letters do seem to make the difference of it working and of it not.

Drudoo's picture

Going crazy now!

Im starting to go crazy! wont work at all...

Here is my addon (this is where i should check it out at the first step) if anyone can check the code or upload there code i would be a huge help Laughing out loud


Try a capital N on Name

Try a capital N on Name

Try a small f on file

Caps wise thats all i can see, Try adding the spaces before the /> too maybe?

Drudoo's picture

Still not working... I have

Still not working...

I have a folder in my wow folder named "Blizzard Interface Art" and the path to that is "/Interface" right?

Really have no idea why it aint working...

Lycander's picture

I know this is late but ...

It looks like you're using a forward slash in front of the path. The pask should be "Interface\...\..."

Hope this helps.

Drudoo's picture

Still doesn't work :s could

Still doesn't work :s could u upload your version so i can see if that is working ? have checked mine twice and cant seem to find any errors...

Drudoo's picture

Dont work :s

I have made the whole addon, but when i install it, it doesn't show on my screen Sad
Anyone got the same problem?

Jahwo's picture

in your WoWProFit.toc file

in your WoWProFit.toc file try changing

## Interface: 30000


## Interface: 31000

According to WoWWiki,

According to WoWWiki, wouldn't it be 30100, not 31000?

freddy301's picture

yeah, according to wowwiki

yeah, according to wowwiki it is but since it is constantly changing i don't think it is up to date at all times as of now try with ## Interface: 30103
It would not really matter though you can enable it even if it is wrong interface code, in the addon button on the wow character selection screen

Nilz's picture


i'm at the first test ...when i make sure the addon is checked off in the addon screen it says incompatible is that supposed to happen?

Nilz's picture


I am confused about how to create a luafile or a TOC file. How do i make a file lua or TOC Puzzled

Jahwo's picture

Create a new file with your

Create a new file with your texteditor and use the "save as" function. Now enter "xxxx.lua" or "xxxx.toc" as filename (where xxxx is the name you want to give the file) and save it.

Nilz's picture


Ok thanks for clarifying

Jahwo's picture

The whole AddOn developing

The whole AddOn developing part is finished now. Only some things for the appendix ar left Smiling

By the way, will you have

By the way, will you have some section about the actual code and functionality?

I'm really looking forward to see this part Smiling

Jahwo's picture

Sure that's what's coming

Sure Smiling that's what's coming up next

Jahwo's picture

New chapter Textures and

New chapter Textures and Fontstrings completed. Smiling

Jiyambi's picture

Jahwo, this is just looking

Jahwo, this is just looking really nice. Very professional, top notch quality. If I ever have free time again, I am going to dive into this and play with addons! Too bad right now I just don't have the time Sad


I didn't read the whole guild yet, but after reading a bit I can say it's AMAZING!!! Smiling

I did write an addon for the Titan panel, a button that will hide the recount window (much like a similar built-in button for omen Smiling ) but while doing this there wasn't any introductory simple guild on how to start making one.. So it took a lot of reloads until I got all the errors out Smiling

I'd like to point out, that your guide is well structured, and for a beginner in coding and addon writing it is really easy to use. For an actual developer (I mean non WoW developer) it's also very informative and not boring(!)

Great job on both the actual contents, and the presentation Smiling


Jahwo's picture

This is a completely new

This is a completely new version of the guide I started before. I changed the concept a bit as well as the formatting.

Also the "example" addon is completely different because the old one was not suitable enough. This one gives me the possibility to explain every basic thing about addon writing.

Still this is only work in progress but again I decided to prerelease it to get feedback, as it is usable until the current end.

I hope you like it Smiling