|
|
| Line 1: |
Line 1: |
| == Introduction ==
| |
| World of Warcraft UI programming is simple and daunting at the same time. | | World of Warcraft UI programming is simple and daunting at the same time. |
|
| |
|
| Line 15: |
Line 14: |
| this Addon programming tutorial. So, let's get on with this. | | this Addon programming tutorial. So, let's get on with this. |
|
| |
|
| | | == Index to pages in this series == |
| == Square One ==
| | * [[Addon programming tutorial/Introduction|Introduction]] - The basic of the basic. A trivial Addon built. |
| You have to start someplace, and the traditional place to start is with "Hello, World".
| |
| To accomplish this first task you will need the following items:
| |
| * World of Warcraft installed (DOH!)
| |
| * An editor that can work with and save pure text.
| |
| | |
| An Addon lives in a very specific place. To find that place, first go to the World of Warcraft directory (also sometimes called a folder) using
| |
| whatever file management software you have available. On a Windows platform, that would be Windows Explorer (not Internet Explorer).
| |
| The program is usually installed on the C: drive of the computer, under the directory named "Program Files".
| |
| From pretty much any address bar, simply type "C:\Program Files\World of Warcraft" and press enter.
| |
| | |
| On a Macintosh system, you would use finder (is that still the name? I'm not a Mac user) and on Linux there is a similar mechanism.
| |
| Whatever you use, you are looking for the installed location for World of Warcraft.
| |
| | |
| Once you find the World of Warcraft directory, there is another directory called Interface and within that is another called Addons.
| |
| Addons is the home of all Addons in WoW. Each Addon has its own directory under the Addons directory.
| |
| | |
| Now go ahead and do these steps:
| |
| * Create a directory for your Addon named "HelloWorld"
| |
| * Create three files named: HelloWorld.toc, HelloWorld.lua, HelloWorld.xml
| |
| Note that the only difference in the names is the suffix. These denote, in order, [[TOC format|Table of Contents]], the [[Lua]] code file, and the [[XML user interface]]
| |
| visual elements file. The name of your Addon directory and the name on the .toc file must match.
| |
| | |
| Now to put something into each of these files and this is where the editor that works with text files comes in.
| |
| The files must be saved as text, not as some document format.
| |
| Notepad is a pure text editor, but it is very limited. There are many out there, some of which can help with your programming efforts by
| |
| understanding the syntax of the [[Lua]] language (more on that later). My personal favorite text editor is [http://www.ultraedit.com UltraEdit]. (list some more here and provide links to them).
| |
| | |
| | |
| === The .toc or Table of Contents ===
| |
| This file tells WoW about your Addon: what files to load and what order to load them in. Later you will want to peruse the [[TOC format]] page
| |
| for all of the gory details about what you could put into this file. For now we are just going to give you some basic stuff to include.
| |
| | |
| Using your trusted text file editor, place the following into the HelloWorld.toc file:
| |
| ## Interface: 20400
| |
| ## Title: Hello World!
| |
| ## Notes: My first Addon
| |
| ## Dependencies:
| |
| HelloWorld.lua
| |
| HelloWorld.xml
| |
| | |
| Immediately I need to tell you the above is probably wrong. See the line with ## Interface: 20400 in it? By the time you try to follow this
| |
| tutorial, that value will probably have changed and you will need to put in the current value. If you already have some Addons installed, | |
| you can just look into their .toc file and see what they used. Another way is to visit http://wowcompares.com and look there.
| |
| You will want the TOC Build number for the latest Public Server version listed.
| |
| | |
| What is this number? It is the user interface (UI) version for the Addon. The "20400" is version 2.04.00 (or 2.4.0). This number tells WoW
| |
| that your Addon is compatible with Blizzard UI level 2.4.0. If your UI number does not match the Blizzard UI number, your Addon will be
| |
| considered out of date. This is to minimize problems caused by old UI modifications hosing Blizzard's UI.
| |
| | |
| So, what is it that we are saying with this information? Starting from the first line we are saying:
| |
| # The UI version for this Addon is 20400 (or 2.4.0)
| |
| # The Title for the Addon (seen in the addon list in the game) is "Hello World!"
| |
| # The Notes for anybody reading the Addon
| |
| # Any Dependencies on other Addons that this Addon may have.
| |
| # That the HelloWorld.lua file should be read and processed.
| |
| # That the HelloWorld.xml file should be read and processed.
| |
| | |
| For more details on stuff you can put in here, please visit the [[TOC format]] page.
| |
| | |
| | |
| === The .lua or Lua code file ===
| |
| The .lua files are where the main "what to do" instructions for the Addon reside. You will see a variety of terms for this such as logic and
| |
| executable code (or simply "code"). Lua logic, or executable code or a script, does its thing in response to something that happens in the game.
| |
| Things that happen in the game are called Events.
| |
| | |
| ==== Events ====
| |
| There are two basic kinds of events. The first kind of event is when something happens in the game. This might be somebody saying something,
| |
| something happening to your character, another character's stats changing, nearly everything that happens in the game causes events.
| |
| The second kind of event is when you do something to a UI Element (a UI Element is something on the screen and is affectionately called a widget.
| |
| We'll get to that more in the next section). This second kind of event might be clicking on something in your bags or button bar.
| |
| There is a technical difference between the two types of events, and we will discuss that as the tutorial progresses.
| |
| For more detail on the first kind of event see [[Events (API)]] and for the second see [[Widget handlers]].
| |
| | |
| This discussion of events is extremely important because absolutely nothing happens in the game happens except in response to an event.
| |
| Further, should you happen to write a piece of code that runs for an extended time (perhaps forever) absoultely nothing new will happen in the game.
| |
| Your screen will be frozen and nothing will move. That would be classified as "not good".
| |
| | |
| So, how do you tell World of Warcraft that you are interested in a particular event? There are two ways: First, you can tell World of Warcraft which
| |
| code to run when a particular event happens. This is called registering your event. Second, you can tell the XML to run a piece of code when a
| |
| UI Element is manipulated (such as clicking on it or moving your mouse over it).
| |
| These pieces of code that run in response to events are called functions.
| |
| | |
| ==== Functions ====
| |
| Functions are groupings of code that accomplish a specific purpose. There are numerous pre-defined functions provided by World of Warcraft called
| |
| API functions and you can make your own user-defined functions. While there are multiple ways to create functions in Lua the easiest to understand
| |
| looks like this:
| |
| | |
| <local> function ''function_name''(<zero or more arguments>)
| |
| ... code ...
| |
| end
| |
| | |
| The <local> is an optional keyword that limits the visibility of the function to a particular scope. Scope will be covered in more depths shortly.<br>
| |
| The ''function_name'' is simply a name you make up so you can reference your function from other parts of your Addon.<br>
| |
| The <zero or more arguments> are ways to pass information into the function. This is what gives functions their power.<br>
| |
| Each time you call the function, you can supply a different set of arguments and get different results based upon them.<br>
| |
| The ... code ... is where the work gets done in a function. Here is where you do calculations, comparisons, call other functions, etc to get the
| |
| task of the function done.<br>
| |
| The end simply marks the end of the definition of the function.
| |
| | |
| Note that this only defines or declares the function. The function is not
| |
| actually run until some other piece of code references (or calls) it.
| |
| | |
| For more information on functions, please see the [http://www.lua.org/manual/5.1/ Lua 5.1 Reference Manual] or
| |
| [http://www.lua.org/pil/ Programming in Lua (first edition)]. Also see the [[Lua]] page which lists more Lua resources.
| |
| | |
| ==== HelloWorld.lua ====
| |
| Now to continue with our Hello World code example. Please include the following into your HelloWorld.lua file and save it.
| |
| | |
| function HelloWorld()
| |
| message("Hello World!");
| |
| end
| |
| | |
| You should understand everything in here by now. This function is named HelloWorld and it has zero arguments. The code part is simply the
| |
| 'message("Hello World!");' portion. And it ends with end.
| |
| | |
| This is a fine piece of code, and by itself is useless unless something calls the function. Onward to UI Elements (aka Widgets).
| |
| | |
| | |
| === The .xml or XML visual elements file ===
| |
| UI Elements, or Widgets, are all of the tiny bits of graphics that make up the User Interface.
| |
| World of Warcraft uses XML to layout everything that you see on the screen. Additionally, when things happen (called Events, remember?) to
| |
| the widgets on the screen, Widget Handlers can be called to perform whatever action you want. We will see shortly how we tell WoW which
| |
| widgets we are interested in and which Events we want handled by which Widget Handler.
| |
| | |
| ==== Blizzard XML format declared ====
| |
| For those of you who don't know, XML stands for eXtensible Markup Language and is a means of tagging content with identifiers.
| |
| What the identifiers are and how they are organized can be defined in something called a Schema. In our case, we want to create
| |
| XML documents that WoW will understand, so we will use the Schema provided by Blizzard for the Wow User Interface.
| |
| | |
| We declare that our document conforms to the Blizzard schema with the following bit of magic:
| |
| | |
| <nowiki><Ui xmlns="http://www.blizzard.com/wow/ui/"
| |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| |
| xsi:schemaLocation="http://www.blizzard.com/wow/ui/
| |
| ..\..\FrameXML\UI.xsd"></nowiki>
| |
|
| |
| </Ui>
| |
| | |
| The exact meaning of all of the above is beyond the scope of this tutorial. Consider it a magic formula that you always put in every
| |
| .xml file you will create for the WoW user interface. For those of you that like to reformat things, the first three lines can be
| |
| merged to line line (use spaces), but the fourth line (..\..\FrameXML\UI.xsd"> ) needs to be on a line by itself starting in column 1.
| |
| | |
| There are a few general notes that you need to know about concerning XML, particularly as it is used by WoW.
| |
| The generalized format of a tag is:
| |
| | |
| <tagname attribute="attribute value" anotherattribute="anotherattribute value">
| |
|
| |
| </tagname> | |
| | |
| A tag must have a tagname, and it may have zero or more attributes along with the attributes' associated values in double quotes. | |
| The tag is everything between the ''''<tagname'''' and the trailing ''''>''''. The tag is closed by an end tag with the same name as
| |
| tag: ''''</tagname>''''. Tagnames do not have spaces, are case sensitive, start with a capital letter, and additional words are also capitalized.
| |
| A valid tagname might be 'BackgroundWidgets', while 'backgroundwidgets' would not be valid. Blizzard defines all valid tagnames in their UI.xsd.
| |
| The [[XML user interface]] page has a good list under [[XML user interface#Widget Elements | Widget Elements]] which will aid you until we get further along.
| |
| | |
| Everything between the tag and the end tag is content to the tag. Everything. Even other tags along with their content.
| |
| In the case where there is no content to a tag, the end of the tag has ''''/>'''' instead of just ''''>'''' and there is no separate end tag.
| |
| A complete tag with no content looks like:
| |
| | |
| <tagname attribute="attribute value" anotherattribute="anotherattribute value"/>
| |
| | |
| Using the above piece of magic as an example, we can see that it is a tag with the name ''''Ui'''' and it has three attributes
| |
| (the funny forth line is a part of the prior attribute).
| |
| Content is represented by the space between the end of the tag (the ''''>'''' on the fourth line) and the ''''</Ui>'''' end tag.
| |
| | |
| ==== HelloWorld.xml ====
| |
| Now to continue with our Hello World XML example. Please edit your HelloWorld.xml file copy and past this bit of magic into it:
| |
| | |
| <nowiki><Ui xmlns="http://www.blizzard.com/wow/ui/"
| |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| |
| xsi:schemaLocation="http://www.blizzard.com/wow/ui/
| |
| ..\..\FrameXML\UI.xsd"></nowiki>
| |
|
| |
| </Ui>
| |
| | |
| World of Warcraft connects everthing to a frame, even other frames. So, in order to create something that WoW will interact with,
| |
| we create a frame:
| |
| | |
| <Frame name="HelloWorldFrame">
| |
|
| |
| </Frame>
| |
| | |
| The tagname is ''''Frame'''' and we have used the ''''name'''' attribute and given the attribute the value of ''''HelloWorldFrame''''.
| |
| | |
| Our frame tag is included as content to the Ui tag and so goes between the start Ui tag and the end Ui tag.
| |
| To help keep track of what is surrounding what, we indent the content with respect to the enclosing tags like this:
| |
| | |
| <nowiki><Ui xmlns="http://www.blizzard.com/wow/ui/"
| |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| |
| xsi:schemaLocation="http://www.blizzard.com/wow/ui/
| |
| ..\..\FrameXML\UI.xsd"></nowiki>
| |
| <Frame name="HelloWorldFrame">
| |
|
| |
| </Frame>
| |
| </Ui>
| |
| | |
| It is very important that you do not mix up the various end tags and indenting helps keep things straight. Notice that the ''''Frame''''
| |
| tag (both the start and the end) are completely surrounded by the ''''Ui'''' tag.
| |
| | |
| Inside the frame, one of the many things we can define are Scripts. Scripts are nothing more than small pieces of Lua code. Where we place the
| |
| script determines when it will be invoked. Because Scripts live within a Frame we include the ''''Scripts'''' tag inside the ''''Frame'''' tag.
| |
| | |
| <Frame name="HelloWorldFrame">
| |
| <Scripts>
| |
|
| |
| </Scripts>
| |
| </Frame>
| |
| | |
| The various widgets have several Events that can occur and if we want to declare a Widget Handler to process the event we include the event name
| |
| under the Scripts tag of the widget we are interested in. Not every widget has the same set of events. In this example, we are interested in
| |
| an event named ''''OnLoad''''. The OnLoad event happens when the widget is loaded into the UI. For this example, we want the OnLoad event to
| |
| run the script named HelloWorld. This script was defined in the HelloWorld.lua as a function.
| |
| | |
| <Scripts>
| |
| <OnLoad>
| |
| HelloWorld();
| |
| </OnLoad>
| |
| </Scripts>
| |
| | |
| Take a look at the [[Widget handlers]] page for a list of widgets and the events you can write widget handlers for.
| |
| | |
| The complete HelloWorld.xml file should look like this:
| |
| | |
| <nowiki><Ui xmlns="http://www.blizzard.com/wow/ui/"
| |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| |
| xsi:schemaLocation="http://www.blizzard.com/wow/ui/
| |
| ..\..\FrameXML\UI.xsd"></nowiki>
| |
| <Frame name="HelloWorldFrame">
| |
| <Scripts>
| |
| <OnLoad>
| |
| HelloWorld();
| |
| </OnLoad>
| |
| </Scripts>
| |
| </Frame>
| |
| </Ui>
| |
| | |
| There is an important item you should note in the above. The '''''HelloWorld();''''' is the only piece which is NOT a tag or an attribute.
| |
| It is important to note that content in a WoW .xml UI document is always a piece of code if it is not another set of tags and their associated
| |
| attributes. The only valid place for a piece of code is under the tag for an event.
| |
| | |
| Having gotten this far, it is time to run your new Addon.
| |
| | |
| === Running your HelloWorld addon ===
| |
| You should have a directory under your Addons directory named "HelloWord" and in that directory should be three files named HelloWorld.toc,
| |
| HelloWorld.lua, and HelloWorld.xml. The contents of these three files should be EXACTLY as noted above.
| |
| | |
| Now start World of Warcraft and log into your account, but don't select your character yet.
| |
| Please click the red ''''AddOns'''' button on the lower left of the character selection screen to see all of the addons WoW has detected.
| |
| There will be one for every folder in your Addons directory except for the addons starting with Blizzard_.
| |
| | |
| You should see your new HelloWorld in this list. The name should be yellow, and the checkbox to the right should be checked.
| |
| | |
| If the name is Red and you see an '''Out of date''' message to the right, you probably didn't change the '''## Interface: 20400'''
| |
| value as described above under [[#The .toc or Table of Contents | The .toc or Table of Contents]]. Please review that section and make the appropriate change.
| |
| I do not recommend running your addons with the 'Load out of date AddOns' checkbox checked. That's asking for trouble as an Addon that
| |
| attempts to use old UI features can corrupt a new UI. Nearly every patch that changes the UI level has had problems with old Addons that
| |
| have not been updated to conform to the new UI standards.
| |
| | |
| If you don't see the name at all, make sure that you have placed the HelloWorld directory in the AddOns directory which is in the Interface directory
| |
| under the World of Warcraft installation location. On my system (Windows) it is 'C:\Program Files\World of Warcraft\Interface\AddOns\HelloWorld'.
| |
| The files inside that directory should all start with 'HelloWorld' and have the .toc, .lua, and .xml endings.
| |
| | |
| Please note the CaSe of the names. While Windows is insensitive to case for directory and file names, the case is important to other systems (e.g. Mac, Linux)
| |
| Also, inside the game itself, World of Warcraft is sensitive to the case for the names of it's variables and filenames.
| |
| Keep the case the same to avoid problems.
| |
| | |
| Now, you have a yellow HelloWorld! showing up in your addon list. Note the ! in the name. The name of the addon shown in this list is taken from
| |
| the '''## Title: Hello World!''' line in the HelloWorld.toc file. In the future, we will see how to change colors and languages.
| |
| | |
| If you move your mouse cursor over the HelloWorld name, you should see a tool-tip pop up with two lines in it. The first line is the same as the
| |
| Title, and the second line is taken from the '''## Notes: My first Addon''' line in the .toc file. This can also be customized for color and language.
| |
| | |
| Cancel out of the AddOns display and enter the world with any of your characters.
| |
| Once your character loads, you should see a big message box in the middle of your screen that says '''Hello World!''' with a red '''Okay''' button.
| |
| | |
| Success!!
| |
| | |
| | |
| == Review ==
| |
| You have created your first addon and have successfully run it. Now let's review a bit about what was accomplished.
| |
| | |
| The 'Hello World!' text is taken from the line in the HelloWorld.lua file that reads 'message("Hello World!");'.
| |
| Wrapped around that is a function named message which is responsible for drawing the box around your message and placing the 'Okay' button on it.
| |
| | |
| The message function is inside a function we created called HelloWorld that had no parameters. Our function will do the same thing every time
| |
| it is called.
| |
| | |
| You should then recall that the name of our function was placed in the HelloWorld.xml file as the action to be taken when the ''Onload'' event
| |
| of the ''Scripts'' tag of the Frame we created. We placed the name of our function in this specific place because we wanted our function to be
| |
| executed (run, called, processed) when our Frame was fully loaded.
| |
| | |
| World of Warcraft knew that it should create our Frame because we placed the name of the .xml file into the .toc file.
| |
| The .toc file must have the same name as the addon's directory and is the first of the files in our addon that Blizzard processes.
| |
| | |
| Inside the .toc file is where we tell World of Warcraft about our addon (the ## statements) and what files that need to be loaded.
| |
| Every line that does not start with a ## is a file to be processed by World of Warcraft.
| |
| The order that the file names appear is important because World of Warcraft processes the file in order listed.
| |
| | |
| Knowing that, we place the .lua file before the .xml file because we want the function HelloWorld declared (or defined) before we try to
| |
| call it in the .xml file.
| |
| | |
| Even though this is a trivial example of an addon, important concepts and information have been covered.
| |
| Further pages in this tutorial will cover other areas and expand upon topics initially presented here.
| |
| | |
|
| |
|
| == More == | | == More == |
| * [[User:Gregity/Sandbox/Addon programming - TrackMe|TrackMe]] - A slightly more involved example illustrating basic concepts
| |
| * [[Interface Customization]] - Portal to nearly everything having to do with UI programming in World of Warcraft | | * [[Interface Customization]] - Portal to nearly everything having to do with UI programming in World of Warcraft |
| * [[TOC format]] - Extra details on the .toc file | | * [[TOC format]] - Extra details on the .toc file |
| Line 331: |
Line 25: |
| * [[AddOn]] - A primer about AddOns | | * [[AddOn]] - A primer about AddOns |
| * [[:Category:HOWTOs]] - Other How To Do tasks in WoW programming | | * [[:Category:HOWTOs]] - Other How To Do tasks in WoW programming |
| | * [[:Category:Interface customization]] - useful links to items |
| | * [[:Category:UI]] - useful links to items |
|
| |
|
| === External links === | | === External links === |
| Line 340: |
Line 36: |
|
| |
|
| [[Category:Interface customization]] | | [[Category:Interface customization]] |
| [[Category:FAQs]]
| |
| [[Category:UI]] | | [[Category:UI]] |