World of Warcraft
The War Within
Patch 11.2
Tips for new interface modders
With new folks entering the beta, it seems like a good time to start a thread on how to get started with modding, rather than have people field the same questions repeatedly. There was a similar (shorter) thread posted by Blizzard in the Alpha forum but it doesn't seem to have been repeated here... yet!

Here are some basic steps for getting started, followed by some tips that would have helped me when I stareted. I hope some of the more experienced modders out there will share their thoughts as well.

Once you're started modding (whether or not you read the rest of this post), PLEASE read and follow the guidelines in Rav's "Interface Modification Guidelines" post. Not only they will help you avoid bugs, but they will help modders better understand each other's code and also make your script easier to integrate into the everything script, should it turn out to be popular.

Getting started
Probably the best way to learn is to read existing scripts. They show the power and flexibility of the UI scripting engine, and can help you find out what functions are provided to you by the back end code.

Once your eyes hurt or you're ready to actually do some coding, here's what's next.

The first thing you need to know is how scripts and frames get loaded.

There are 3 basic file types that are involved. The two files you will deal with most are .xml files and .lua files. The .xml files define the structure of the windows/panels/frames and buttons, set up various event handlers, and make references to the .lua script files. The .lua files are the scripts/code where you provide any new core functionality that you need. Finally there's the FrameXML.toc which contains a list of all the files that the interface will try to load at startup or reload time. There's also a bindings.xml file that has a semi-special structure and you can use it to add your own key bindings for your mod.

When the UI engine loads, it looks for the Interface\FrameXML\FrameXML.toc file. Each file listed will get loaded. Lines beginning with a "#" are commented out and those files are not loaded.

For each file the UI loads, including the FrameXML.toc file, the code appears to do a search starting from multiple locations. First it looks for the file using a path relative to the WoW root directory. For example when it looks for Interface\FrameXML.toc, the first place it really looks (on my computer) is f:\World of Warcraft\Interface\FrameXML. Then it searches other places for built-in or Blizzard-provided versions of this file. All this really means is that you make an Interface\FrameXML directory, and stick your files in there, and life is peachy. What this file searching algorithm means to you, though, is that since you have to override the defaults on a per-file basis, there is some ugliness when you want to download and run multiple mods on the same machine since almost every mod overwrites FrameXML.toc and/or bindings.xml. This was the whole impetus for putting together EverythingScript; to avoid forcing people to manually merge the most-commonly-used mods together.

So if you want to create a new UI panel, you should make a new .xml file and put its name and path at the end of the FrameXML.toc file. Order is not important to the code, but everyone should put user mods at the bottom so that it's easier to see what has changed and how to merge your changes with the changes for another mod.

To get a new .lua file to load, you need to reference it in a .xml file. Add a child node to the main <Ui></Ui> node that looks like this (or change an existing one to point to your own file)

<Script file="myMod.lua"/>

That should get all your files loaded.

UI element structure

UI elements defined in the .xml file follow a recursive structure. At each "main" level of the structure you have something that looks like this (some elements may be optional)

<Frame name="..." ...>\

<Size>...</Size>

<Anchors>...</Anchors>

<Layers>...</Layers>

<Frames>...</Frames>

<Scripts>...</Scripts>

</Frame>

Buttons and checkboxes follow the same format but the node is named "Button" or "CheckButton" rather than "Frame".

Size Pretty much self-explanatory. Sets the size of this frame/button.

Anchors Contains a list of <anchor> nodes that control how this frame's position relates to other frames. An Anchor describes 2 reference points (well not literally points), one point on the frame/button you're defining and another one either on another frame/button or a global reference point. Then the anchor describes how the two points should relate, and the UI engine plops your control down in the right spot for that to happen.

Layers This is where you define your textures for the window edges, backgrounds, etc. There are typically up to 3 layers, BACKGROUND, BORDER, and ARTWORK. Each one is displayed over top of the preceding one.

Frames
This is where the recursive nature comes up. This node's children are all frames (or buttons), and each of them has the same structure as I'm describing here. Sadly, this recursion makes the XML file pretty tough to read in a text editor, but is necessary in many cases.

Scripts
This is where you put your event handlers. The most Common handlers are OnClick, OnEnter, OnLeave, OnLoad, OnEvent, and OnUpdate. The first three are mouse-related handlers. OnLoad gets called when the frame is loaded at UI startup or restart. OnEvent happens any time a game event occurs (chat message received; a unit's health or mana changes; and many, many more). OnUpdate is the "idle" event and it gets called almost continuously, presumably about once per rendered frame. arg1 tells you how long it has been, in seconds, since the last time it was called. There are many more events, just read some sample scripts. The contents of each event handler's node is fully interpreted each time the call is made, so if your event handling is very simple you may not even need to have a LUA file.

One important thing to note in this section is that the "small" or single-line comment ("--") does NOT appear to work correctly under all circumstances inside script handler blocks. You must use the "large" or multi-line comment syntax if you want to comment any of this code out. ("--[[ comment ]]")

Tips
Here's a few of the tips that I think will help you get up and running quickly, and/or avoid the biggest pitfalls I've run into.

  • The last line of FrameXML.toc must end in a carriage return. If you add a new line, and don't end it with a carriage return, your file will not be loaded. I swear this gets me every time.
  • You don't have to reload WoW to reload your UI files. If you open the console and type "reloadUI" (case-insensitive), the entire UI reloads from scratch. This way you can just alt-tab, edit your files, then alt-tab back and test them very quickly. For frequent minor edits this saves SO much time.
  • Check out the official LUA 5.0 user manual at http://www.lua.org/manual/5.0/.
  • If you program in C or C-like languages, watch out for the "then" and "do" keywords you will invariably leave out of if and for statements. I can't count the number of times I've forgotten to put these in. Don't be like me. It gets old fast.
  • Be very careful to avoid typos (or capitalization errors) in variable names. Because lua is an interpreted language, when it runs into this typo it will just make up a new variable with that name but with 'nil' as its value, which is almost never what you want. This gets old fast, too. And it's harder to track down. So don't do it.
  • Boolean values: Don't use 0 and 1 as if they were true and false. Any numeric value (even if it's 0) is treated as "true". The only values treated as false are nil and (obviously) false. It takes forever to debug this the first time you accidentally do it.
  • Comment syntax. There are 2 kinds of comment syntax in LUA. One is the "short" comment, started by the string "--", which goes to end of line (like C++'s // syntax). The other is the "long" comment, which is started by "--[[" and goes til the end-of-comment marker "]]". Don't end the comment with "]]--" unless you really mean to comment out the rest of the line that the comment-end marker on. (The LUA manual does not decribe this especially clearly. Eschew obfuscation!)
  • Remember that only the last error that happened has a popup. You may be having multiple errors happening in a row and not know it. This means that syntax errors can be "masked" by later load-time errors.
  • The first time you add new files or replace existing files with modified versions, you may have to reload WoW from scratch to get them to load properly. Typing reloadui in the console reloads the exact same versions of each file that was loaded when WoW was first launched, except for FrameXML.toc which is not re-read.
Happy scripting!

Datenschutz / Impressum / Umweltschutz / Privatsphäre

© 2003-2025 - 4Fansites, Weiterverwendung von Inhalten oder Grafiken nur mit Erlaubnis.

World of Warcraft, The Burning Crusade, Wrath of The Lich King, Cataclysm, Mists of Pandaria, Warlords of Draenor, Legion, Battle for Azeroth, Shadowlands, Dragonflight, The War Within and Blizzard Entertainment are trademarks or registered trademarks of Blizzard Entertainment in the U.S. and/or other countries.