Addon Concepts

While addons are designed to fulfill many different purposes, there are some common themes that arise in their design. This section covers a few of these themes, including potential "gotchas" as well as tips on how to best work with them.

Addons vs. Full Applications

The most basic concept of an addon is, as its name implies, that it's built on top of something else. In this case, that "something else" is the WAR client. This can be important for a number of reasons:

  • Interaction is limited to the methods the client provides.
  • Reinventing the wheel is bad. The client may already doing calculations or processing to get results you're interested in - if possible, use that.
  • Your addon is unlikely to be alone. Playing nice with other potential addons is important.

Hooking

Hooking is an extremely powerful tool for addons that are looking to modify or extend existing functionality. Going hand-in-hand with this, however, they must also be used with care - reckless or improper hooking can have detrimental effects including potentially breaking other addons besides your own.

The basic concept of a hook is that you are going to sit "in between" a particular function and the code that calls it, and potentially do some of your own processing whenever the original function would be called:

  • Without hook: Function A calls Function B.
  • With hook: Function A calls Function C. Function C calls Function B.

In the example above, Function C is referred to as the "hook" function, and Function B is said to be "hooked" by Function C.

Why might we want to hook a function? Generally, there are 3 possible reasons why we might desire to hook:

Addition/Extension
In this case, we want to do something extra each time a given function is called. For instance, perhaps whenever the function to show the player's inventory is called, we also want to show our own window that's related to the inventory.
Modification
In the case of modification, we want to change something about how the function we're hooking operates. Since we sit in between the function for both directions of the call (both calling it, and returning values), we can modify either. Perhaps we want to tweak a color value to make it different from what the function normally sets.
Filtering
We even have the power to choose whether we call the original function or not. This can be useful if we want to "filter" when the original function is called - perhaps to hide certain announcements from being shown, or prevent updating of something that we'd like to update on our own.

One of the most important concepts with regards to hooking is being friendly to other addons. There is no guarantee that your addon will be the only one hooking a function, and thus there are certain guidelines that can help your addon "play nice" with others.

The first is preserving the hook chain. Let's say that by default, Function A calls Function B, and there are two addons that want to use Function C and Function D respectively to hook Function B.

If the first addon didn't care about being friendly, it might just never call Function B at all from inside Function C - perhaps it just replicates Function B's results on its own. The problem arises when Function D was already hooking Function B, but Function C tries to take over - since it never "passes through" to the rest of the chain, Function D no longer gets called, either: the chain gets changed from A > D > B to A > C.

Instead, Function C should use Function B (by calling it as part of its code), and simply modify either the inputs, results, or both to suit its purposes. That way, any other hooks are preserved as part of the call chain: from A > D > B we get A > C > D > B.