Jump to content


Photo

WoW Addon Development - how to?


  • Please log in to reply
13 replies to this topic

#1 Moogul

Moogul

    ___facing so hard right now

  • Members
  • 4,173 posts

Posted 21 December 2007 - 11:46 AM

For a while now, I've been interested in trying my hand at building some WoW addons - both small trinkets for myself, and some larger more useful ones. I'm a programmer by trade, with experience in a variety of languages (though not Lua), and I've also used XML enough to know my way around it, so in theory I have the skills required to do it.

However, even though I can look at some decent Lua tutorials and pick it up very quickly, and whenever I open the source of some of the Mods I have, I can pretty quickly understand all the various functions in them, I find that I don't yet have the understanding to actually build a (sizable) mod from scratch. I've built a couple of test addons from some tutorials, but they seem to be on the level of 'hello world', which is pretty big leap from things that actually need to do substantial I/O, event handling, etc.

Now the point is, I know the theory behind all of this, what I need to know is the WoW specific bits. How exactly should I go about designing and implementing a prototype for a WoW Addon? Obviously the xml stores the data and the lua stores the code, but how should I go about structuring them? Any advice on which event handlers I should use for initialising data and such, any good tutorials for using saved variables, etc.

The other thing is the WoW interface API, is there a well documented version of the API somewhere? I've found some of it on WoWWiki, but it doesn't seem that complete. A good reference would really help. There are a lot of standard things in the WoW interface that I don't know how to do (ie. dragging spells to action buttons - sure I can create a button, but how do I change the action that the button is linked to? Are there onDrag event handlers or such? Can I then get the spell being dragged based on the event properties?)

So, to sum up this rather rambling post - Does anyone know a good WoW API reference, and a guide for the 'intermediate' - someone who knows programming and XML, but is new to making WoW Addons, that will give a good foundation for what kind of program an interface addon is?

#2 whuz

whuz

    Glass Joe

  • Members
  • 24 posts

Posted 21 December 2007 - 12:27 PM

WoWWiki has all the documentation you need: WoWWiki:Interface customization - WoWWiki - Your guide to the World of Warcraft

#3 Kalman

Kalman

    Super Macho Man

  • Members
  • 8,791 posts

Posted 21 December 2007 - 04:10 PM

And beyond that, most of the time when I start writing something, I go look at mods that handle similar things and check their structure for anything useful. DotDotDot contains significant portions of HotCandy's display methods and some of DoTimer's removal handling. Scrub's original output is ripped from oRA's ready check system. Etc. It's the old saying - why write something new if you can just 'borrow' from someone else?
Melador> Incidentally, these last few pages are why people hate lawyers.
Viator> I really don't want to go all Kalman here.
Bury> Just imagine what the world would be like if you used your powers for good.

#4 Antiarc

Antiarc

    Still alive

  • Members
  • 1,444 posts

Posted 21 December 2007 - 07:20 PM

The best place to start, really, is to look at the source of other mods (or even the stock Blizzard UI, though I'm of the opinion that the stock UI code is pretty mediocre to learn from) and find out how they do things. I learned a lot from CTMod when I was first getting into modding. After a while, I moved to the Ace framework, which comes with its own set of conventions, but abstracts a lot of the grunt work away from you.

The basics of it are basically something like this:

WoW looks under Interface/Addons for directories.
For each directory, it tries to open a file named <directory name>.toc. This provides addon metadata (name, dependencies, etc), and specifies which files to load.
Files are loaded and executed in the order specified.

XML files generally contain frames, or frame templates. Lua files contain all the business logic. You can avoid using XML files if you want, by doing your frame creation in Lua code, but that's a topic for another day.

Code in Lua files is executed as its loaded. Generally, you're going to want to have your various functions/methods, and then some kind of code to register an event to a function that initializes your addon. Most people use the PLAYER_ENTERING_WORLD event, as this fires pretty late in the loading cycle, and most things are available by that point. You initialize your addon and off you go.

Saved variables are done by just specifying a variable in the TOC, with a line like:

## SavedVarables: MySavedVar

Then, whatever you put into MySavedVar is serialized when you reloadui or exit the game, and is deserialized back into memory when you load WoW up (The event VARIABLES_LOADED fires after they've been deserialized) so that they are available to your addon.

Events are just registered to frames by using frame:RegisterEvent("EVENT_NAME") (where frame is a reference to some frame you've created), and then when that event fires, it'll hit the OnEvent script handler for the frame (which you define either in the XML, or via frame:SetScript("OnEvent", handler)). You can then take various action based on the event name and arguments.

To be honest, I'd recommend looking into a framework like Ace2/Ace3/Rock/Dongle, and developing on top of that. They move many of the "gotchas" out of your way, so you don't have to deal with them, and give you some nice tools. They'll also tend to produce better habits in your code than you might develop otherwise.

I throw together a small sample addon file that explains the basic addon lifecycle: Pastey.net - ace paste bin

#5 Moogul

Moogul

    ___facing so hard right now

  • Members
  • 4,173 posts

Posted 21 December 2007 - 08:44 PM

Thanks for the post + that addon code Antiarc, that's a big help.

One thing I'm a bit unsure about - code outside of functions? Is that executed automatically when the addon is loaded? (ie. the commands to make the frame and register the events) Does it need to be in a particular place in the lua file? Top? Bottom? Could I (if I had a perverse desire to) split it out in between each function and still expect it to work?

Do I have to use this non-function code to set things up, or is there some kind of 'main' function equivalent that gets called that I can use to create frames and register events?

#6 Cromfel

Cromfel

    Don Flamenco

  • Members
  • 462 posts

Posted 21 December 2007 - 09:04 PM

You may want to check AddOn Studio for World of Warcraft.

www.codeplex.com - AddOn Studio for World of Warcraft

****

Overview
AddOn Studio for World of Warcraft is an open-source development tool aimed to bring the Visual Studio experience to building World of Warcraft addons. This is the first release of the project and we have lots more ideas around how we can better improve addon development in the future.

Visual Design Surface - Includes a set of toolbox controls that you can drag-and-drop onto the designer to visually design the layout of your addon including popular Visual Studio features like Snap lines which enable you to visually align controls.

Lua Code Editor - Includes a powerful Lua code editing environment including syntax highlighting, colorization, collapsible functions, built-in IntelliSense support for Warcraft functions and events, IntelliSense Code Snippets for common Lua language constructs, code navigation features like bookmarks and Go To Declaration, and all IDE settings are customizable.


FrameXML IntelliSense - Provides built-in support for FrameXML schema validation for addon developers who want to manually edit and customize FrameXML markup.

Auto-Generate Table of Contents - Also takes the hassle out of building the Table of Contents (TOC) file by automatically building it based on what files are in your project.

Auto-Generate Lua Events - Property window shows all of the properties and events available for a Lua control or frame and enables one-click creation of event handlers like a button_OnClick event.

Other Goodies - AddOn Studio includes lots more features including project templates for creating Ace2 addons, automatic deployment to your Warcraft directory, Task Window, Error List for FrameXML and Lua parsing errors, TGA and MP3 file format support, powerful search-and-replace features, and its fully extensible so that developers can build additional tools and editors to improve addon development.

****

Im not so much of coder myself, so cant really say if the platform is better than just hard coding. But it sure seems like a pretty handy way to get into addon making.
.:. Retribution Paladin Hideout .:. http://cromfel.battlefield.fi/

#7 grimman

grimman

    Von Kaiser

  • Members
  • 31 posts

Posted 21 December 2007 - 09:07 PM

To clarify, the XML does _not_ store the data, but rather defines frames and lets you register certain events (OnLoad etc), which can be done within the Lua since 2.0 I believe. You don't need XML anymore as you can do all the frame creation etc through Lua.

The data is stored within Lua files in your account folder (WTF\Account\[AccountName]\SavedVariables and other folders in that tree). There really isn't a great deal to know if you're done programming in the past, and as the people above said, wowwiki is an excellent source of information!

#8 Antiarc

Antiarc

    Still alive

  • Members
  • 1,444 posts

Posted 21 December 2007 - 09:32 PM

Thanks for the post + that addon code Antiarc, that's a big help.

One thing I'm a bit unsure about - code outside of functions? Is that executed automatically when the addon is loaded? (ie. the commands to make the frame and register the events) Does it need to be in a particular place in the lua file? Top? Bottom? Could I (if I had a perverse desire to) split it out in between each function and still expect it to work?

Do I have to use this non-function code to set things up, or is there some kind of 'main' function equivalent that gets called that I can use to create frames and register events?


Yeah, non-function code gets executed as it is loaded. Lua files are basically just exec'd, so any non-function code gets run as it's loaded. The only restriction on ordering is that local variables and functions have to be earlier in the code than the code they're called by.

#9 Moogul

Moogul

    ___facing so hard right now

  • Members
  • 4,173 posts

Posted 21 December 2007 - 09:48 PM

To clarify, the XML does _not_ store the data, but rather defines frames


Myself, I'd call a frame definition 'data'. It's a simplified view, yes, but at a simplified level, the xml defines 'what you see', and the lua defines 'what it does'.

The only restriction on ordering is that local variables and functions have to be earlier in the code than the code they're called by.


Is there a way to prototype functions earlier if I want to have possible circular references, ala C? Or is this something that doesnt really come up in Lua?

#10 grimman

grimman

    Von Kaiser

  • Members
  • 31 posts

Posted 21 December 2007 - 09:59 PM

Myself, I'd call a frame definition 'data'. It's a simplified view, yes, but at a simplified level, the xml defines 'what you see', and the lua defines 'what it does'.


Roger. I was thinking about saved variables, which is addon output data. ;)

#11 Antiarc

Antiarc

    Still alive

  • Members
  • 1,444 posts

Posted 21 December 2007 - 10:00 PM

Is there a way to prototype functions earlier if I want to have possible circular references, ala C? Or is this something that doesnt really come up in Lua?


No, not particularly. If you end up with a circular reference issue, then just define your functions as table methods, and the problem goes away.

#12 Slake

Slake

    Great Tiger

  • Members
  • 885 posts

Posted 22 December 2007 - 04:10 AM

In general it's a good idea to code your addon as one large 'object' table with methods anyway, that way you don't pollute the global namespace with helper functions and methods that don't need to be seen outside of your addon.

As far as code-outside-functions goes, Antiarc is correct in stating that each lua file gets executed as it is loaded; the function definitions are literally just that, large statements with blocks that - syntactic sugar aside - are just loading definitions of a function into a variable somewhere. A lot of interaction with the game world cannot be done during this initial load, but any pure-data commands can be run. See Scrub in fact, all of the class files are essentially lists of table injections that get executed at load time.

#13 Anias

Anias

    Solution complicated; Dispense enlightening graph.

  •  Patrons
  • 4,621 posts

Posted 25 December 2007 - 04:40 AM

If you're interested in poking around the blizzard side of the files, consider http://wdnaddons.com/ - it's a very well maintained version tracker for wow.

If you're wanting a good place to start learning the development practices for wow, consider http://us.blizzard.c...articleId=21465 and the user interface customization tool. As it says, it's a place for advanced users to start to explore what's possible. The last time I installed it from scratch it included a readme explaining what each of the directories it was expanding did, and it was reasonably coherent.

Generally, if you're interested in developing for the wow UI, the best place to start is from blizzard's API and example code, as it provides a clearer presentation of ideas. Once you're familiar with the various ways the blizzard default UI functions, you'll have an easier time co-opting various pieces for your own development, as well as a more intuitive grasp of what your planned mod may break (and thus what you will have to do to prevent said breakage from causing the mod or game to malfunction).

There are several different ways to (for example) move a frame in wow dynamically, however many of those methods will break other portions of the UI if used inappropriately. The only way to understand what "inappropriately" means in this context is really to understand what is already going on.
First star to the right, and straight on till morning.

#14 Xinhuan

Xinhuan

    Von Kaiser

  • Members
  • 32 posts

Posted 01 January 2008 - 03:47 PM

Is there a way to prototype functions earlier if I want to have possible circular references, ala C? Or is this something that doesnt really come up in Lua?


If these functions are global functions (not locally scoped), this issue will not come up. If these functions are local, then you can either do what Antiarc suggested and put them in a table, or you can pre-declare them just like any other variable.

local abc, def

abc = function(x)
    return def(x-1)
end

def = function(x)
    return abc(x-1)
end

Of course, running this example will cause an infinite loop since there is no terminating condition. It will not result in a stack overflow because "tail calls" are used in this example. You can read up about tail calls in the PIL (Programming in Lua), an online free book written for people to start writing code in Lua with some background knowledge of programming.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users