Gregity22934@legacy41543543 (talk | contribs) (Moved the Intro page to this sub page to better lay out the series of pages) |
(Redirected page to Design: Lucent Ametrine) |
||
Line 1: | Line 1: | ||
+ | #REDIRECT [[Design: Lucent Ametrine]] |
||
− | == Introduction == |
||
− | World of Warcraft UI programming is simple and daunting at the same time. |
||
− | |||
− | It is simple in that it uses some very simple programming constructs and a well-defined method of creating visual elements. |
||
− | |||
− | It is daunting because there is so much to learn, so much detail available, but very little in the way of guides through the forest. |
||
− | It is also daunting because the inevitable errors which crop up can be so hard to find. |
||
− | |||
− | The goal of this "Addon programming" tutorial is to teach by examples and by didactic instruction, leading the new Addon programmer |
||
− | from the very simpliest Addons to complex interactions with the XML user interface. |
||
− | |||
− | These pages have their genesis in the frustration of an experienced programmer in trying to make his way over the myriad of obstacles that |
||
− | others have already passed and forgot. Where to find this, how to do that. Some of the most basic stuff should be covered, but is left out |
||
− | of most other presentations encountered. As this author encounters the pits and barbs and finds solutions and resources they will be shared in |
||
− | this Addon programming tutorial. So, let's get on with this. |
||
− | |||
− | |||
− | == Square One == |
||
− | 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. |
||
− | |||
− | |||
− | == See Also == |
||
− | === More pages in this tutorial === |
||
− | * [[Addon programming tutorial]] - The Index page to this tutorial series |
||
− | |||
− | |||
− | === Here on WoWWiki === |
||
− | * [[Interface Customization]] - Portal to nearly everything having to do with UI programming in World of Warcraft |
||
− | * [[TOC format]] - Extra details on the .toc file |
||
− | * [[Lua]] - Lists several resources for Lua coding |
||
− | * [[XML basics]] - Basic introduction to XML |
||
− | * [[XML user interface]] - More details on XML |
||
− | * [[AddOn]] - A primer about AddOns |
||
− | * [[:Category:HOWTOs]] - Other How To Do tasks in WoW programming |
||
− | |||
− | |||
− | === External Sources === |
||
− | * [http://www.lua.org/manual/5.1/ Lua 5.1 Reference Manual] - The definitive LUA |
||
− | * [http://www.lua.org/pil/ Programming in Lua (first edition)] |
||
− | * [http://www.w3.org/XML Extensible Markup Language (XML)] - The definitive XML |
||
− | * [http://tools.decisionsoft.com/schemaValidate XML Schema Validation] |
||
− | |||
− | |||
− | [[Category:Interface customization]] |
||
− | [[Category:UI]] |
Revision as of 15:28, 26 February 2011
Redirect to: