WoW Forever Addon Developer Guide: Writing Addons with AI

Checked Beta reports from build 1.60.1.69913

Addon guide page 1 of 7

The constraints a language model needs before it writes code for World of Warcraft: Forever: the original Azeroth setting on the modern Mainline interface, without the Classic Era habits models memorized.

TOC interface
16001
Launch
Nov 4, 2026
API family
Mainline 12.1.5
Tested beta build
1.60.1.69913

The problem

Ask a model for a WoW addon and it writes Classic-era code. On beta build 1.60.1.69913, testers at WoW Forever Builds found GetSpellInfo and GetItemInfo gone, WOW_PROJECT_ID returning the Mainline value, and player health coming back as a secret value that addons cannot add to or compare. Warcraft Forever reports that CombatLogGetCurrentEventInfo is unavailable to addons. The beta has had newer builds since (1.60.1.70009 on September 23), so treat every observation as something to retest.

How to use this guide

Give the model explicit constraints before it generates anything. Read the client architecture patterns to see how Forever differs from Classic Era and Midnight. Use the API migration cheat sheet for C_Spell and C_Item signatures, check the common AI pitfalls, start from the starter files, paste from the addon prompts library, or inspect the Forever Beacon test addon, an unverified reference sample.

The golden rules

Ten rules for every AI draft that targets WoW Forever. Rules 3, 6, 7 and 8 are the ones Midnight guides leave out, because they are specific to the Forever beta.

  1. Interface: 16001.
    A Forever-only addon declares ## Interface: 16001, the Forever Beta value in the Warcraft Wiki TOC table. Classic Era uses 11509 and Midnight uses 120100. To ship one package to several clients, use a comma-separated interface line, a _Camelot.toc file (the wiki's Forever suffix), or a _Mainline.toc that Midnight and Forever share. Retest when the number moves at launch.
  2. Lua 5.1.
    WoW runs a modified Lua 5.1. No goto, no //, no bitwise operators and no _ENV. Bitwise work uses the bit library (bit.band, bit.bor, bit.lshift). The wiki notes that the operating system and file I/O libraries are not present, and require, dofile and loadfile are not in its function list. The .toc file is your module loader.
  3. Mainline family, not Classic.
    Blizzard told the WoW UI Discord that Forever shares Mainline's UI architecture, "including the vast majority of APIs available in 12.1.5", and that Midnight's addon disarmament, secrets included, is active (quoted by Wowhead). The Forever game type was called Camelot, to be renamed before launch. On the September 17 Q&A stream the developers said "we did opt for the modern API approach." Port a Midnight addon; do not port a Classic combat addon and hope.
  4. C_ namespaces.
    On build 69913, GetSpellInfo, GetItemInfo, GetSpellBookItemName, GetNumTalentTabs, GetTalentInfo and GetNumSkillLines were missing. C_Spell.GetSpellInfo returns one table; C_Item.GetItemInfo returns the same list of values the old global did. Both return nil until the record is cached. Check for nil, request the load (C_Spell.RequestLoadSpellData, C_Item.RequestLoadItemDataByID) and listen for the result event.
  5. Namespace everything.
    Every file begins with local addonName, ns = .... Shared state hangs on ns. The only globals you should declare are SavedVariables, slash command entries and the Addon Compartment callbacks named in the TOC. A frame named MainFrame becomes a global; name it after your addon or pass nil.
  6. Events, not the combat log.
    Use one frame, one OnEvent script and a table of handlers. Use RegisterUnitEvent when you only watch the player. On Midnight, registering COMBAT_LOG_EVENT_UNFILTERED throws an error, and Warcraft Forever reports the combat log reader unavailable on Forever. Blizzard said on stream that Forever includes a damage meter and a cooldown manager, and that a swing timer is "perhaps coming soon".
  7. Secrets are drawn, not solved.
    Testers saw player UnitHealth come back as a secret number: type() says number, and adding to it fails. Warcraft Forever reports unit names as possible secret strings and UnitCanAttack and UnitExists as possible secret booleans. Guard values with issecretvalue before you compare, branch or print them. Pass health straight into a StatusBar with SetMinMaxValues and SetValue. A blocked protected call can fail without a Lua error, and pcall will not clear it.
  8. Do not trust WOW_PROJECT_ID alone.
    Build 69913 reports 1, the Mainline value. A library that reads 1 as Midnight only, or anything else as Classic, takes the wrong branch. The Warcraft Wiki suggests pairing it with LE_EXPANSION_LEVEL_CURRENT, or a TOC variable for the game type. Add a capability probe, and expect the test to change before launch.
  9. No secure-snippet dependency.
    On build 69913, secure snippets failed to compile because the client had no loadstring_untainted. Click-casting and action-bar paging that use snippets failed with them. WoW Forever Builds calls it probably a bug. Do not ship healer frames that need it until a build fixes it. Your own buttons are the safe click path. Do not write secure attributes onto Blizzard unit frames.
  10. Whole files, correct load order.
    Always emit the .toc and every .lua file in full. Beta addons live in World of Warcraft\_classic_beta_\Interface\AddOns\. SavedVariables load after your files run and are ready when ADDON_LOADED fires for your addon. A September 21 forum report showed saved data written to disk but missing on the next login; a follow-up on September 25 says build 70009 loads it again.

Quick start

The smallest useful WoW Forever addon is two files. The folder name must match the TOC file name. Put them in World of Warcraft\_classic_beta_\Interface\AddOns\FirstLight\ and start the client. The character name is guarded because names can be secret.

FirstLight.toc
## Interface: 16001
## Title: First Light
## Notes: Smallest correct WoW Forever addon.
## Author: YourName
## Version: 0.1.0
## SavedVariables: FirstLightDB

FirstLight.lua
FirstLight.lua
local addonName, ns = ...

local function SafeName()
    local name = UnitName("player")
    if type(issecretvalue) == "function" and issecretvalue(name) then
        return "adventurer"
    end
    return name or "adventurer"
end

local frame = CreateFrame("Frame")

function frame:ADDON_LOADED(loaded)
    if loaded ~= addonName then return end
    FirstLightDB = FirstLightDB or { seen = 0 }
    ns.db = FirstLightDB
    self:UnregisterEvent("ADDON_LOADED")
end

function frame:PLAYER_LOGIN()
    ns.db.seen = ns.db.seen + 1
    print("|cffd4a85a[" .. addonName .. "]|r online, " .. SafeName() .. ". Session " .. ns.db.seen .. ".")
end

frame:SetScript("OnEvent", function(self, event, ...)
    if self[event] then
        self[event](self, ...)
    end
end)

frame:RegisterEvent("ADDON_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")

What is confirmed versus what was only observed

ClaimSource and status
Forever uses the modern addon APIConfirmed. Blizzard developers, September 17 Q&A stream, 01:20:52
Built-in damage meter and cooldown managerConfirmed. Same stream, 01:21:51
Swing timer"Perhaps coming soon" on the same stream. Not a commitment
Shares most 12.1.5 APIs; Midnight disarmament and secrets activeReported. Blizzard statement on the WoW UI Discord, quoted by Wowhead
Interface 16001Reported. Warcraft Wiki TOC table, Forever Beta row
UnitHealth is a secret number; secure snippets fail to compileReported. WoW Forever Builds, build 69913. Retest
WOW_PROJECT_ID is 1Reported. WoW Forever Builds, build 69913. Retest
SavedVariables written but not restoredUnverified. Forum reports from September 18 to 21; a September 25 reply says build 70009 fixed it

Beta access runs September 17 to October 21, 2026. Blizzard's launch date is November 4, 2026 at 3:00 p.m. PST, level cap 60. Any build between now and then can change the API. See the beta reference and systems overview for the game rules around it.

System prompt for AI models

Paste this block into your AI session before you ask for addon code. The task prompts, porting prompts and review prompt are on the AI prompt library.

System prompt
You write World of Warcraft: Forever addons. The client is not Classic Era and it is not a private server.

Facts you must obey. Checked September 28, 2026 against Blizzard's statements, the Warcraft Wiki, and community tests on beta build 1.60.1.69913 (the beta has since moved to 1.60.1.70009). Launch is November 4, 2026. Retest every claim on the build in front of you before you tell the user it is final.

- The Forever beta TOC interface is 16001. A Forever-only addon uses exactly: ## Interface: 16001
- Lua is 5.1. No goto, no //, no bitwise operators, no _ENV. Bitwise work uses the bit library (bit.band, bit.bor, bit.lshift).
- There is no require, dofile, loadfile, io library or os library. Load order is the .toc file. Shared state lives on the addon namespace.
- Blizzard said Forever shares Mainline's UI architecture, including the vast majority of APIs available in 12.1.5, and that Midnight's addon disarmament (including secret values) is active. Forever and modern WoW are two game types in the Mainline family. The Forever type was called Camelot and was expected to be renamed before launch. Do not target Classic Era interface numbers (11500s).
- WOW_PROJECT_ID has been observed returning 1, the same value as Mainline. Never choose a Classic code path from that number alone. Probe select(4, GetBuildInfo()), LE_EXPANSION_LEVEL_CURRENT, and the presence of the API you need.
- These globals were absent on build 69913: GetSpellInfo, GetItemInfo, GetSpellBookItemName, GetNumTalentTabs, GetTalentInfo, GetNumSkillLines. Use C_Spell and C_Item. C_Spell.GetSpellInfo returns a table. C_Item.GetItemInfo returns multiple values, like the old global. Both return nil until the data is cached. Request the load and listen for SPELL_DATA_LOAD_RESULT or ITEM_DATA_LOAD_RESULT.
- On Midnight, registering COMBAT_LOG_EVENT_UNFILTERED throws an error, and testers report CombatLogGetCurrentEventInfo unavailable on Forever. Do not build a damage meter, healing meter, or combat-log boss mod. Blizzard ships a damage meter and a cooldown manager. A swing timer was described as perhaps coming soon, not as a promise.
- Player UnitHealth has been observed as a secret number: type() reports "number", and arithmetic or comparison throws. Unit names can be secret strings. UnitCanAttack and UnitExists can be secret booleans. Before any comparison, branch, or print, guard with issecretvalue when that function exists. Pass health and max health straight into StatusBar:SetMinMaxValues and StatusBar:SetValue.
- pcall does not make a protected call safe. Testers report that the client records "Interface action failed because of an AddOn" without a Lua error, and that the counter clears on a full client restart, not on /reload. Do not call ChatFrame_OpenChat, ChatEdit_ActivateChat, or C_SuperTrack.SetSuperTrackedUserWaypoint. Do not write secure attributes onto Blizzard unit frames. Shift-click links go through HandleModifiedItemClick. Map pins go through C_Map.SetUserWaypoint with a UiMapPoint.
- Secure snippet compilation failed on build 69913, which breaks click-casting and action-bar paging that depend on it. Treat that as a beta defect to retest, not as a design you should depend on. Use your own buttons.
- SavedVariables load after the addon's files run. Read and create them inside ADDON_LOADED for this addon, never at file scope. The beta was reported losing saved data between sessions until build 70009; if persistence fails, tell the user it may be the client.
- Every Lua file starts with: local addonName, ns = ...
- Handle events with one frame and a handler table keyed by event name. Do not grow an if/elseif chain. Do not poll with OnUpdate when an event exists.
- Check InCombatLockdown() before you show, hide, or move a protected frame. Queue the closure and run it on PLAYER_REGEN_ENABLED.
- Skin and inform. Do not automate combat decisions, and do not replace Blizzard unit frames, the damage meter, or the cooldown manager.
- When asked for an addon, emit a complete .toc and every .lua file. No fragments. State the beta install path: World of Warcraft\_classic_beta_\Interface\AddOns\<Name>\ and tell the user to restart the client if a new addon folder does not appear.
- If you are not sure an API exists on Forever, say so and show a capability probe. Do not invent C_ functions.

Verification checklist

Run this checklist across every file an AI model produces before you test it in game:

The rest of the guide

Each page covers one job:

Questions addon authors ask FAQ

What interface version do WoW Forever addons use?

The Warcraft Wiki lists 16001 for the Forever beta. Confirm it on your client with /dump select(4, GetBuildInfo()) in the chat box.

Can an AI write a WoW Forever addon?

Only if you give it explicit constraints first. Without them, models tend to emit old globals like GetSpellInfo, a retail interface number such as 110207, and COMBAT_LOG_EVENT_UNFILTERED. The system prompt and the checklist above catch most of these before you test in game.

What is Camelot in the beta client?

Camelot is the internal name of the Forever game type in the Mainline code family, per Blizzard's WoW UI Discord statement. Blizzard said it would be renamed before launch. The Warcraft Wiki already lists _Camelot.toc as the Forever TOC suffix, so check that suffix again after launch.

Every fact, with its source

  • TOC interface Changed16001 in the Forever Beta row of the Warcraft Wiki TOC table; confirm with /dump select(4, GetBuildInfo())Classic: Classic Era lists 11509 on the same table.
  • Addon API ChangedForever uses the modern addon API, with Midnight's combat restrictionsClassic: Classic Era keeps the older API with the combat log open to addons.
  • Launch New in ForeverNovember 4, 2026 at 3:00 p.m. PST, level cap 60
  • API family ChangedShares Mainline UI architecture and "the vast majority of APIs available in 12.1.5"
  • Tested beta build New in Forever1.60.1.69913; later builds (70009 on September 23) may differ
  • Built-in tools New in ForeverDamage meter and cooldown manager included; swing timer "perhaps coming soon"

Sources

  1. World of Warcraft Developer Q&A (September 17 stream), add-on answer at 01:20:52Blizzard Entertainment (YouTube)
  2. WoW: Forever Will Have Addon Changes from MidnightWowhead
  3. Addons in WoW Forever? Blizzard Devs Just Addressed the Big QuestionIcy Veins
  4. TOC formatWarcraft Wiki
  5. What the WoW Forever beta breaks for addons: secret health values, dead secure snippets, new APIsWoW Forever Builds
  6. AddonsWarcraft Forever
  7. WOWF Beta: Addon SavedVariables appear to write correctly to disk but are not restored at startupWorld of Warcraft Forums (player bug report)
  8. World of Warcraft: Forever What's Next Panel RecapBlizzard Entertainment
  9. Secret ValuesWarcraft Wiki
  10. Patch 12.0.0/API changesWarcraft Wiki
  11. WOW_PROJECT_IDWarcraft Wiki
  12. Lua functionsWarcraft Wiki
  13. Saving variables between game sessionsWarcraft Wiki
  14. Blizzard · Developer Q&A, 01:21:51