Skip to content

Getting Started

R edited this page Jun 1, 2026 · 1 revision

Getting Started

Part of the Foundry API reference.

New to WoW addons? This page takes you from an empty folder to a working Foundry-based addon, and defines the handful of terms the module reference pages assume you already know — frames, events, payloads, controllers, dispatch. If you've shipped an addon before, skip to §4 or go straight to a module page.

The module pages (like Foundry.Commands) are written for authors who already have a basic addon running. This page is the shared on-ramp those pages link back to, so they don't have to re-explain the basics each time.


1. What every WoW addon needs

An addon is a folder under your WoW installation, plus a .toc ("table of contents") file that tells the game what your addon is and which files to load. AddOns live one folder per addon:

World of Warcraft/_retail_/Interface/AddOns/MyAddon/

The folder name, the .toc filename, and the addon's internal name should match (MyAddon/MyAddon.toc). A minimal .toc:

## Interface: 120005
## Title: My Addon
## Version: 1.0.0

MyAddon.lua
  • ## Interface: is the game build you target. It changes each patch; if it's stale the game flags your addon as out of date (it still loads). Read the current value in-game with /run print(select(4, GetBuildInfo())).
  • ## Title: is the name shown in the AddOns list.
  • Lines that don't start with ## are files to load, in order, relative to the .toc.

After editing files, /reload reloads the UI and picks up your changes — you don't have to quit.


2. Frames, events, and payloads

The module pages talk about frames, events, and payloads as if you already know them. The short version:

A frame is the basic object the game gives addons. Some are visible (a button, a window); many are invisible and exist only to do something. The one thing every frame can do is receive game events.

A game event is the game telling you something happened — the player logged in, a bag changed, a unit took damage. Your addon asks to be notified of an event, and when it fires the game calls your handler function.

Some events carry extra data describing what happened — which unit, which item, the text of a message. That data is the payload, delivered to your handler as extra arguments (often written ... in examples). PLAYER_LOGIN has no payload; CHAT_MSG_SAY carries the message text, the speaker, and more.

You rarely need to wire up event frames by hand — that boilerplate is exactly what Foundry's Events module wraps. But it helps to know the shape underneath: a frame receives an event, and the handler reads the payload.


3. Where event names come from

Foundry doesn't define events — it relays the game's own events, so you use the names Blizzard uses. To find the right name and its payload:

  • Warcraft Wiki's event list documents events and the arguments each one delivers. The usual starting point.
  • /eventtrace opens a live in-game log of events as they fire — useful for discovering which event corresponds to something you just did.
  • /dump and the built-in DevTools let you inspect values and API results from the chat box.

We don't reproduce an event list here; it's long, and those sources stay current with each patch.


4. Making Foundry available to your addon

Foundry is itself an addon. Your addon declares it as a dependency so the game loads Foundry first, then exposes it at runtime under a global name.

In your .toc:

## Dependencies: Foundry-1.0

In your Lua, grab the handle and fail loudly if it isn't there:

local F = _G.Foundry_1_0
if not F then
    error("MyAddon requires Foundry-1.0. Please install or enable it.")
end

The runtime global is _G.Foundry_1_0 (note the 1_0 — Foundry is versioned in its global name).

A note on that guard: with a hard ## Dependencies, the game won't even load your addon if Foundry is missing or disabled — so in practice this branch rarely fires. It's cheap insurance that mainly catches misconfiguration (for example, declaring Foundry under ## OptionalDeps instead, where it really can be absent); keep it.

Foundry installs automatically as a dependency through the CurseForge App when someone installs your addon. On its own it does nothing — it only runs when an addon depends on it.


5. Hello world: a complete addon

The smallest whole Foundry addon that does something visible. Create a folder MyAddon/ with these two files.

MyAddon/MyAddon.toc

## Interface: 120005
## Title: My Addon
## Version: 1.0.0
## Dependencies: Foundry-1.0

MyAddon.lua

MyAddon/MyAddon.lua

local F = _G.Foundry_1_0
if not F then
    error("MyAddon requires Foundry-1.0. Please install or enable it.")
end

-- A slash command: /myaddon hello
local cmd = F.Commands:New({
    name = "MyAddon",
    slashes = { "/myaddon", "/ma" },
    description = "MyAddon: a tiny example.",
})

cmd:Register({
    name    = "hello",
    help    = "Say hello.",
    handler = function() print("MyAddon: hello!") end,
})

-- Event handlers. The handler's first argument is always the event name;
-- any payload follows it.
local events = F.Events:New("MyAddon")

events:Register("PLAYER_LOGIN", function(event)
    print("MyAddon loaded. Type /myaddon hello to test it.")
end)

-- CHAT_MSG_SAY's payload is (text, author, ...) — after the event name.
events:Register("CHAT_MSG_SAY", function(event, text, author)
    print("MyAddon heard " .. author .. " say: " .. text)
end)

Drop the folder in Interface/AddOns/, enable My Addon and Foundry in the AddOns list, and log in. You'll see the login line print; /myaddon hello prints on demand; and saying something in /say prints the speaker and text — the event's payload in action.


6. Vocabulary

The module pages use these terms without re-defining them:

  • Controller — the object a module's :New(...) returns, which you hold (for example, the cmd and events locals above). It owns that module's registrations for your addon, and you call methods on it (:Register, :Destroy, and so on).
  • Dispatch — the controller's job of routing each incoming event or command to the right handler you registered. You describe what should happen; the controller does the matching and calling.
  • Composition by reference (vs. mixin) — Foundry hands you a controller and you call its methods. It does not attach its methods onto your addon object the way some libraries "mix in" behavior. The difference matters: with Foundry the library's surface is always reached through an object you can see at the call site, never silently grafted onto your own.

7. Where to go next

  • Foundry.Commands — slash commands, subcommands, auto-help, guards, and dispatch.
  • Foundry.Events — owned event registration with automatic cleanup, scoped to your addon.
  • Home — the module index, runtime access, and roadmap.

Foundry is MIT-licensed, and you only ever pull in the modules you use. Pick a module, hold its controller, and build.

Clone this wiki locally