• Dear Guest,

    You're browsing our forum as a Guest meaning you can only see a portion of the forum in read-only mode.
    To view all forum nodes and be able to create threads/posts please register or log-in with your existing account.

    TwinStar team

Addon making advice

Gourmandises

New Member
Joined
Oct 29, 2014
Location
Illinois
As the title says, where would one start to begin making addons for our good ol' WoW (1.12.1 specifically)
I have some free time on my hands and would like to learn; I'll make some small time things and hopefully get better.

I know I could google how to make addons or something of the sort but I don't know how large the differences are (if any) between each version of the game. So I come to you guys for help, as I see lots of great people here making stuff.

I offer a please and thanks in advance for any information as I am going to bed for work as soon as I post this.
 
(...)
I don't know how large the differences are (if any) between each version of the game.
(...)

WoW API varies greatly between each expansion of the game. From top of my head I can think of very limited combat/unit information, global arguments for events, non existing whisper channel for addons.
Some functionality wasn't even officially documented at all and then removed in later versions of the game.

As for the developing process itself you can start with this:
Addon Development
Event API Documentation

And as a final advice: check first how blizzard's developers do things, then other addon authors. Go play around with your favorite addons!
 
Maybe I'll write a tutorial at some point. The minimal setup to get anything running at all is a folder with a .toc file with the same name as the folder containing the names of your code files to be loaded. I would completely avoid xml from the beginning and only use lua.

This is the vanilla API: http://vanilla-wow.wikia.com/wiki/World_of_Warcraft_API

Here you can find the blizzard interface code for vanilla: https://github.com/AtheneGenesis/Vanilla_enUS_FrameXML

It is useful to look at the blizzard code for examples of how to use the API, to find out how to extend the default interface and also because it may be useful to reuse some functions defined there. I would definitely not call it an example of good coding though. For that I would rather look to retail addons and modern vanilla addons (old vanilla addons tend to have nightmarishly bad code).

About organizing/modularizing your code: Unfortunately wow does not include the lua module system (old or new). The blizzard code defines tons of global variables which is something you definitely should not do. Many wow addons use ace/libstub, but that's really just a thin wrapper around using a module table with some version control added which is pointless unless you're writing a library. Also I don't much like the idea of using ancient abandoned libraries, so I found it most useful to try and stick to (non wow) lua conventions. Here are some (I think) reasonable options:

1) locals only
Except for some rare cases where the wow API requires globals you can just declare every variable/function as local in your file. Further you can define locals withing a limited scope using do end blocks. Locals also happen to be very efficient to access for lua. There are two problems with this though. It doesn't work for modularization as you can't access them from other files and you have to either worry about the order of declarations or predeclare every function at the top of the file (which is annoying to keep synchronized). Still, a good option for single-file addons at least.

2) Module-table
This is probably the most common approach also used by the new lua module system. Conventionally the table is called M. So basically you would put "local M = {}" at the top of a file and then define functions as "function M.foo() end". If you want to use the functions from another file you can just assign the module table to a global variable.

3) custom env
This is a variation of the module-table option. Using setfenv you can change the file's environment from the global one to your table. You probably want to do something like this:
Code:
local _G, _M = getfenv(0), {}
setfenv(1, setmetatable(_M, {__index=_G}))
This way the global variables are still visible in your env (to write globals you need to use _G).
This method has the advantage that you don't need to prefix your functions with "M.". Also you cannot accidentally define global variables. Whether to use explicit module tables or this is mostly a matter of taste. Anyway, this is my preferred method for single-file addons.

4) simple encapsulation
If you don't want to expose every function of your file you can combine local declarations and globals/module tables. If you find locals too annoying you can also define a second module table for private functions.

5) write your own module system
The new lua module system cannot be implemented but the old one can be quite easily. It is somewhat similar to the "custom env" method above, except that it abstracts away the setting of the env. If you like perfect encapsulation such things can be achieved with extensive use of metatables. Many would say this is overkill but I like it. I've written a module system for aux that does this: https://github.com/shirsig/aux-addon/blob/master/libs/module.lua. Here you can see how it's used: https://github.com/shirsig/aux-addon/blob/master/core/history.lua.

6) object orientation
The standard way to do this in lua is with plain tables. There's syntactic sugar (semicolon) for passing the object to its methods. Defining a function like so: "function t:foo() end" is equivalent to "function t.foo(self) end" and calling a function like so: "t:foo()" is equivalent to "t.foo(t)". This offers no encapsulation. Simple encapsulation for object orientation can be achieved with closures: "function new() local self, private = {} {} function self:method1() end return self end. There are two problems with this though. For every new instantiation every function has to be redeclared which is very inefficient and also the table containing the public functions can be edited after creation. In the top of this file is an implementation of object orientation with perfect encapsulation which is still reasonably efficient: https://github.com/shirsig/aux-addon/blob/master/util.lua. I'm not actually using it anywhere at this point though.
 
Super thanks guys! I'm going to keep a slow and thorough nose to the grindstone.

Sorry for the answer threads already existing too, I was using the search function but with the wrong words
: P
 
Top Bottom