I've been playing quite a bit of World of Warcraft Classic lately. I used to play way back in ~2005 and it's been a large part of my life. I've never developed any AddOns for WoW before, but I figured it'd be a fun experiment to document my progress learning how to create WoW AddOns.

The video for this article is on the way! Subscribe here to make sure you don't miss it.

WoW AddOns are created using the Lua scripting language and development can be done in the editor of your choice. I'm using Visual Studio Code for this with the WoW Bundle plugin installed for colorisation and other features.

With that said - let's dive right in and create our first AddOn!

Creating our WoW Addon

Start off by navigating to your World of Warcraft AddOns directory (this will be World of Warcraft/_classic_/Interface/AddOns in my instance) and make a new folder called HelloWorld .

This is where we'll be placing all of the code related to our AddOn.

Table of Contents

Make a new file here named HelloWorld.toc with the following:

## Interface: 11304 ## Title: HelloWorld ## Notes: Prints "Hello, World" to the chat. ## Author: YourName ## Version: 0.0.1 HelloWorld.lua

NOTE: The .toc file must have the same name as the AddOn's folder.

This is known as a Table of Contents file and allows us to provide metadata about our AddOn as well as files to be loaded at runtime. Here we're essentially stating that we want to load HelloWorld.lua and our AddOn is named HelloWorld .

The Interface number will match the current WoW patch and allows the WoW client to determine whether an AddOn is out of date. This number is different for Classic and Retail.

There are numerous ways to get the current Interface id, but the easiest way is to type the following in-game:

/run print((select(4, GetBuildInfo())));

Build Number: 11304

Alternatively, you could copy this from another AddOn that isn't out of date from within your AddOns folder.

If we boot up the game and click AddOns on the bottom left of the character selection screen, we should be able to see our HelloWorld AddOn!

Hello, World!

Before we test this with our AddOn, let's verify what we're expecting to see by running it as a /script message("Hello, World!") inside of the WoW Chat UI.

We should see a box come up on our screen saying Hello, World!

Great. We can now reproduce this with our HelloWorld AddOn.

Our AddOn will load the HelloWorld.toc look for the HelloWorld.lua that we've stated should be loaded at runtime. We can go ahead and create this in the same HelloWorld folder with:

message("Hello, World!")

Any time we make changes to our AddOn, we'll need to run /reload in the chat to be able to see our changes.

In this circumstance, because we've added a brand new file, we'll have to restart the WoW client.

If we've done everything correctly, we should see Hello, World in game without having to type anything in the chat!

Player Name

We can also make this a little more special by using the current player name by accessing the UnitName method:

local name = UnitName("player") message("Hello, " .. name .. "!")

This should now say, Hello {name}! where the name is equal to your player name. We can see this in action:

Slash Command

We could even add a slash command to make this more dynamic. What if we had a slash command that we could type /helloworld or /helloworld name and this would show a custom message?

We can update our HelloWorld.lua to support this:

SLASH_HELLO1 = "/helloworld" local function HelloWorldHandler(name) if(string.len(name) > 0) then message("Hello, " .. name .. "!") else local playerName = UnitName("player") message("Hello, " .. playerName .. "!") end end SlashCmdList["HELLO"] = HelloWorldHandler;

We now get one of two things:

If we pass nothing into /helloworld it'll show Hello, {playerName}! If we pass a name into /helloworld john it'll say Hello, John!

The SlashCmdList["HELLO"] will point any slash command registered with SLASH_HELLO{x} toward our HelloWorldHandler , so we could register another command such as /msg with and get the same result:

SLASH_HELLO1 = "/helloworld" SLASH_HELLO2 = "/msg" local function HelloWorldHandler(name) if(string.len(name) > 0) then message("Hello, " .. name .. "!") else local playerName = UnitName("player") message("Hello, " .. playerName .. "!") end end SlashCmdList["HELLO"] = HelloWorldHandler;

Finally, we can clean up our HelloWorldHandler to instead have a showGreeting(name) which stops our repetitive message call:

SLASH_HELLO1 = "/helloworld" SLASH_HELLO2 = "/msg" local function showGreeting(name) local greeting = "Hello, " .. name .. "!" message(greeting) end local function HelloWorldHandler(name) local nameExists = string.len(name) > 0 if(nameExists) then showGreeting(name) else local playerName = UnitName("player") showGreeting(playerName) end end SlashCmdList["HELLO"] = HelloWorldHandler

Summary

We've now made our first WoW AddOn! You can find the code for this article here: https://github.com/PaulHalliday/wow_addon_hello_world

Next up, let's make a Music Player in part two of this series!