I never experienced World of Warcraft. I played other Blizzard games, both before and after its release, including the original Warcraft series and Diablo. I skipped over WoW for reasons I can’t completely recall. During the hype around “classic” I tried “retail” for a moment and abruptly stopped due to a move to a new home. I was tempted to play again after learning about “vanilla” servers but had already mentally committed myself to wait for the official servers. Classic finally launched on August 26, 2019 and I joined in as to not miss out on the twice in a lifetime experience.
Minutes passed during my group’s first play of the game and the chatter started about all the addons they just had to install. Unlike me they had played on and off for the last fifteen years, both vanilla and retail. Not having a clue, I played for a few sittings before getting the itch. What addons were out there and what they could do for me? Everyone had so much experience I thought it was only fair that I bridge the gap. I installed quite a few addons while feeling like a kid in a candy store. With all my handicaps addressed I was firmly hooked.
Then, out of nowhere, my curiosity got the best of me. How do these things work?!
This article assumes you have at least some basic knowledge in software development and are at least interested in how the World of Warcraft addon system works. I’m a software engineer by trade but I’ve never written a game addon before, so it’s not a requirement that you have either. If you’ve used or written a macro in game you’re already ahead.
Setting up the Development Environment
We’re going to need an editor to develop this addon. Older tutorials will recommend you the most basic of text editors, which will work, but we can do better than that. If you don’t already have a preference I would recommend downloading Microsoft Visual Studio Code. That should be more than enough for this journey and enable future programming endeavors. I have crossed paths with vscode plugins touting both Lua and World of Warcraft support but the editor is sufficient out of the box for what is needed here. Do explore the available extensions and make your own decision on their usefulness.
Creating a Folder for the Addon
How you manage your project long term is up to you. I’d recommend using GitHub to manage your code and only update your local addon directory when you are ready to test a new version, possibly with a deployment script. For now, since we are just getting started, let’s just work out of the Addons
directory.
Provided you haven’t changed the default install location the World of Warcraft
directory will either be located in C:\Program Files
or C:\Program Files (X86)
on Windows or the /Applications/
on a Mac. Depending on what you have installed you will may see _classic_
and _retail_
and _ptr_
folders in that directory. Open _classic_/Interface/Addons
and create a Sandbox
folder. An addon is born!
Creating the Table of Contents
In the Sandbox
folder create a new text file named Sandbox.toc
. This file provides the information required about the addon to the WoW client. If you’ve ever looked at package.json in a JavaScript project for example, this serves a similar purpose.
Add the following to the file:
## Interface: 11302
## Title: Sandbox
## Notes: A place to experiment.
## Author: haxorjim
## Version: 1.0
Sandbox.lua
The correct value for Interface
can be found in game by running the following command: /run print((select(4, GetBuildInfo())));
At the time of writing classic is currently 11302. If you intend on targeting retail or vanilla instead be sure to update that value.
Following that, I believe Title
, Notes
, Author
and Version
are self explanatory. There are quite a few other values that I’ve observed in toc files, I would recommend peeking into other addons to discover those.
The final line Sandbox.lua
is a pointer to where the actual code will be stored. At least one file is required, but for larger plugins multiple files can be referenced here and all will be loaded at runtime.
Out of curiosity I played around with changing directory names, file names and removing more details from the toc file. There wasn’t much that really caused the addon to fail to function. It’s definitely going to be good practice to have a detailed table of contents file, so the above is what I’d recommend as the minimum.
Writing Some Code
World of Warcraft addons are written in Lua which touts itself as “a powerful, efficient, lightweight, embeddable scripting language.” Lua should not be much effort to pick up if you have at least one language under your belt. If not, it will still be an excellent first language to learn.
To begin coding in Lua, create a Sandbox.lua
file in the Sandbox
folder that we created earlier and add the following code:
Sandbox = { }
function Sandbox:HelloWorld()
message("Hello World!")
end
function Sandbox:HideGryphons()
MainMenuBarLeftEndCap:Hide()
MainMenuBarRightEndCap:Hide()
end
Additionally select one of the following samples of code and add it to the very end of the file:
Option A:
Sandbox:HelloWorld()
Option B:
Sandbox:HideGryphons()
Trying It Out
Time to boot up the game… No playing! Focus! When you enter the game one of two things should happen. If you selected Option A you should see “Hello World!” displayed in a graphical window:
If you selected Option B the results are a bit more mysterious. Where have the gryphons gone?
Congratulations! Your first addon is complete!
Beyond the Basics
There’s a lot more general programming that can be done within a addon but I won’t be going deep into Lua here at all as there are plenty of books already available to reference for the subject. There are even books such as Beginning Lua with World of Warcraft Add-ons and World of Warcraft Programming: A Guide and Reference for Creating WoW Addons specifically for World of Warcraft.
Finding out how to create or modify different elements in the WoW client is challenging and requires knowledge of the available API. The best resources for the API I’ve found so far are Wowpedia and WoWWiki.
Additionally a great way to learn how to do things is to take a look at Lua files in existing addons either that you have installed or those available on the web. Do be advised, mileage will vary with what is supported in different World of Warcraft client versions.
Limitations & Workarounds
There were a couple of interesting limitations I found while writing this article. The first is to call out to a url to GET or POST data. If it did exist, could have some pretty serious malicious abuses, so I’m not surprised it’s not there. It would have definitely been useful for some slick addons.
Another limitation is the inability to save data to an external file or read from an external file. This isn’t too limiting to addon developers as you have access to saved variables and can load as many Lua files as you please. Some plugins like CensusClassicPlus are getting around this limitation by having users upload files from their SavedVariables
folder after logging out of the game.
Despite not being able to communicate directly over the Internet, addons still appear to be able to communicate with each other with some tricks. For example RealMobHealth and ClassicThreatMeter are using in game chat to send data between users in the current group who also have the addon installed.
Finally, not so much a limitation but a consideration is the variances betwen capabilities in the API between game versions. Since now we have classic, vanilla (which is multiple versions in itself) and retail the API is not always the same. Plugins will need to be tested and coded to work on all platforms, or only on a specific platform as not all are created equal. One way to adapt would be to switch addon executation paths programatically based on the game version retrieved from GetBuildInfo()
.
Debugging
While you are developing it will be useful to stay logged into the game. This allows you to switch in and out to make some changes to the addon, run /reload
to restart the UI and continue debugging. Majority of the time your changes will be reflected unless you are doing something with changing files names or the toc file. It will also be useful to execute /console scriptErrors 1
during your coding session so that when Lua errors occur they are displayed immediately. Just don’t forget to turn it off using /console scriptErrors 0
before you go back to normal gameplay. As always, print
and message
functions will be your friend! Finally, there are also some interesting looking addons that may be of additional assistance including BugSack and BugGrabber which “eases the process of viewing bugs”.
Testing
While your addon may not grow large enough to justify any robust testing patterns it is a good idea to consider at least some basic testing strategies before things turn into spaghetti. The structure that was snuck into the example addon it allows for manual testing of functions by running manual commands, for example:
/run Sandbox:HelloWorld()
A surprising option that is available is WowUnit which “allows you to easily write unit tests for your World of Warcraft addons and provides an interface to monitor them”. This is probably the best choice for the majority of addons that require testing.
Lastly, for addons with considerable internal logic, it is very possible Lua itself could be used to test the addon without requiring the WoW client to be running. This would require mocking out parts of the WoW API and using a Lua interpreter to run your tests. While the most advanced option it would also be the most extendable.
Publishing
I assumed addons would need to manually acquired and installed by hand. However the Twitch client can automatically install addons for you as well as keep them in sync across machines using their client. You don’t have to be a streamer to use it. It works in conjunction with Curseforge, a directory of addons for multiple games. With millions of downloads for the most popular addons I would definitely recommend publishing to get exposure. In addition I’d again recommend using GitHub to allow others to collaborate and help maintain your addon. If you end up being inspired to create an addon, here are the instructions for creating and submitting a project.
Final Thoughts
I started this article to learn more about how addons worked inside World of Warcraft. What I discovered was a robust framework with all the tools I would expect from a development environment available to me. I’ve found myself torn between playing the game and continuing to look under the hood. There are numerous addons already available for WoW but nothing I’ve come across has felt like the end all be all. Much more could be done and there is considerable room for improvement. If the feedback to this article is positive I would absolutely consider writing a series of articles on this topic.