The constraints a modern language model needs to target World of Warcraft: Forever: the original Azeroth setting running the modern mainline interface, without the obsolete Classic assumptions AI models memorized.
The problem and the silo
Ask any AI model for a WoW addon and it writes code from 2015. On beta build 1.60.1.69913, testers found GetSpellInfo absent, the combat log unavailable to addons, WOW_PROJECT_ID returning the mainline value, and friendly health becoming a secret value that rejects arithmetic or string concatenation. Those observations can change before launch.
To write testable Forever addons, give the model explicit constraints before generation. Review the core client architecture patterns to understand how Forever differs from Classic Era and Midnight. Review the API migration cheat sheet for modern C_Spell and C_Item signatures, inspect the common AI pitfalls to intercept hallucinations, start from paste-ready starter files, paste from our addon prompts library, or inspect the Forever Beacon test addon as an unverified reference sample.
The golden rules
These ten rules are non-negotiable for every AI draft targeting WoW Forever. Rules 3, 6, 7, and 8 are the ones Midnight guides omit because they are specific to the Forever beta environment.
- Interface: 16001 — A Forever-only addon declares
## Interface: 16001. That is the Forever beta interface on the Warcraft Wiki TOC table. Classic Era numbers in the 11500s mark the addon out of date. Midnight's 120100 is a different game type. If one TOC must feed both modern clients, list 16001 in the comma-separated interface line and retest when Forever's number moves at launch. - Lua 5.1, frozen — The sandbox is still Lua 5.1. No
goto, no//, no bitwise operators (&,|,~,<<,>>), no_ENV, noutf8library, and noload()with an environment parameter. Bitwise calculations require thebitlibrary (bit.band,bit.bor,bit.lshift). There is norequire,dofile,io, oros. The.tocfile is your module loader. - Mainline family, not Classic — Blizzard confirmed to the WoW UI Discord that Forever shares Mainline's UI architecture, including the vast majority of APIs available in patch 12.1.5, and that Midnight's addon disarmament — secrets included — is active. Forever and Midnight are two game types in one code family. The Forever type was called Camelot in development and was expected to be renamed before launch. Port a Midnight addon; do not port a Classic combat addon and hope.
- C_ namespaces, table returns — On beta build 1.60.1.69913,
GetSpellInfo,GetItemInfo,GetSpellBookItemName,GetNumTalentTabs,GetTalentInfo, andGetNumSkillLineswere removed.C_Spell.GetSpellInfoandC_Item.GetItemInforeturn a single table, ornilif the record is not cached. Check fornil, request the load withC_Spell.RequestLoadSpellData, and listen for the result event. Multi-return Classic snippets are hallucinations. - Namespace everything — Every file begins with
local addonName, ns = .... Shared state hangs onns. The only globals you should declare are SavedVariables and the Addon Compartment callbacks named in the TOC. A frame namedMainFramebecomes a global; name it after your addon or passnil. - Events, and no combat log assumption — Use one frame, one
OnEventscript, and a table of handlers. UseRegisterUnitEventwhen you only monitor the player. Community testing foundCOMBAT_LOG_EVENT_UNFILTEREDandCombatLogGetCurrentEventInfounavailable on build 69913, so retest rather than designing around them. Blizzard is shipping a built-in damage meter and cooldown manager so that players do not require addons to participate in group content. - Secrets are drawn, never solved — Friendly
UnitHealthhas been observed as a secret number: Lua reports its type as number, then throws an error if you add, compare, format, or print it. Unit and creature names can be secret strings.UnitCanAttackandUnitExistscan be secret booleans. Guard every value withissecretvalue. Pass health values straight into aStatusBarviaSetMinMaxValuesandSetValue. A blocked protected call may fail silently without throwing;pcallwill not clear it, and the AddOns panel records the failure until the client restarts. - Do not trust WOWPROJECTID — Beta build 69913 reports
1, the Mainline retail ID. Any addon library that assumes1means retail-only, or that anything else means Classic, takes the wrong branch on Forever. Detect the client using the interface number fromselect(4, GetBuildInfo()), or with a capability probe, and expect that test to adjust before launch. - No secure-snippet dependency — On the observed beta, secure snippets failed to compile. Click-casting and action-bar paging that inject those snippets failed with them. That may be a beta defect rather than intentional design, but you should not ship healer frames requiring
loadstring_untainted. Your own buttons are the safe click path. Do not write secure attributes onto Blizzard unit frames. - Whole files, loaded on start — Always emit the
.tocand every.luafile completely. Addons live inWorld of Warcraft\_classic_beta_\Interface\AddOns\and are indexed when the client boots. SavedVariables remainniluntilADDON_LOADEDfires for your specific addon. The beta has also been observed writing SavedVariables correctly but failing to restore them on next login. Code the correct pattern, and do not blame user configurations if the beta client fails to reload them.
Quick start
The smallest valid WoW Forever addon requires two files. The folder name must match the TOC file name. Place them in World of Warcraft\_classic_beta_\Interface\AddOns\FirstLight\ and launch the client. The character name is guarded because a secret string cannot be concatenated.
## Interface: 16001
## Title: First Light
## Notes: Smallest correct WoW Forever addon.
## Author: YourName
## Version: 0.1.0
## SavedVariables: FirstLightDB
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
| Claim | Source and Status |
|---|---|
| Addons are allowed, with Midnight-style restrictions | Confirmed by Blizzard, WoW UI Discord, mid-September 2026 |
| Shares most APIs from patch 12.1.5, secrets included | Confirmed by Blizzard in the same technical statement |
| Built-in damage meter and cooldown manager | Confirmed by Nora Mills, 17 Sept 2026 live Q&A |
| Swing timer built-in | Mentioned as under consideration. Not a binding commitment. |
| Interface 16001 | Published for Forever beta on the Warcraft Wiki TOC table |
| UnitHealth is a secret number; secure snippets fail to compile | Observed on beta build 69913. Needs retesting each patch. |
| WOWPROJECTID is 1 | Observed on beta build 69913. Retest on newer builds. |
| SavedVariables write but do not restore | Community reproduction on the beta. Not a Blizzard promise. |
The beta opened 17 September 2026 and Blizzard described testing through 21 October 2026. Launch cited by Blizzard is 4 November 2026 at 3:00 p.m. Pacific, level cap 60. Raids scheduled for 9 December 2026 include Barrow Deeps, Hyjal Summit, and Onyxia's Lair. Review the beta reference and systems overview for surrounding game rules.
System prompt for AI models
Paste this prompt block into your AI session before requesting addon code. The full collection of task prompts, porting instructions, and review checklists lives on the AI prompt engineering guide.
You write World of Warcraft: Forever addons. The client is not Classic Era and it is not a private server.
Facts you must obey. Researched 26 September 2026 against public Blizzard statements and hands-on notes for beta build 1.60.1.69913. Launch is 4 November 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, no utf8 library. Bitwise work uses the bit library (bit.band, bit.bor, bit.lshift).
- require, dofile, loadfile, io, os, and the debug library do not exist. 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. Internally 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. Probe select(4, GetBuildInfo()) 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. They return tables, and they return nil until the data is cached. Request the load and listen for the result event.
- Community testing on build 69913 found COMBAT_LOG_EVENT_UNFILTERED and CombatLogGetCurrentEventInfo unavailable to addons. Do not build a damage meter, healing meter, or combat-log boss mod without retesting. Blizzard is shipping a damage meter and a cooldown manager. A swing timer was described as a possible later built-in, not as a promise.
- Friendly UnitHealth has been observed as a secret number: type() reports "number", and arithmetic or comparison throws. Unit and creature names can be secret strings. UnitCanAttack and UnitExists can be secret booleans. Before any branch, concatenation, format, 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. The client can record "Interface action failed because of an AddOn" without a Lua error, and that 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.
- Secure snippet compilation has failed on the observed beta, 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 are nil until ADDON_LOADED fires for this addon. Never read or create them at file scope. The beta has also been observed writing SavedVariables and failing to restore them. Still use the correct pattern, and tell the user if persistence fails 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 restyle 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 that the addon list is read when the client starts.
- 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 testing in game:
- TOC Interface: Does the
.tocdeclare## Interface: 16001or include 16001 in a multi-client list? - Lua 5.1 compatibility: Are there any instances of
goto,//,_ENV,require,io,os, or native bitwise operators? - Namespace isolation: Does every
.luafile begin withlocal addonName, ns = ...and keep private functions local? - C_ namespace APIs: Are spell and item lookups routed through
C_Spell.GetSpellInfoandC_Item.GetItemInfowithnilchecks? - No combat log calls: Is the code free of
COMBAT_LOG_EVENT_UNFILTEREDand combat-log string parsers? - Secret value safety: Are health, power, and unit names checked with
issecretvalueprior to math, string formatting, or printing? - No project ID branching: Is code free of Classic branches predicated on
WOW_PROJECT_ID? - No secure snippet injection: Are secure attributes omitted from Blizzard unit frames?
- SavedVariables timing: Are saved tables initialized inside
ADDON_LOADEDrather than at file scope? - Combat lockdown queue: Are protected frame modifications deferred to
PLAYER_REGEN_ENABLED?
The AI addon guide spokes
Explore each spoke in the content silo for targeted code patterns, pitfalls, and copy-paste templates:
- Forever patterns — Architectural differences between Classic Era, Midnight, and Forever, secret value handling, and safe addon surfaces.
- API cheat sheet — Replacements for dead globals, async data loading, secret-safe unit queries, and event registrations.
- Pitfalls — The twelve most frequent hallucinations generated by AI models and how to write the correct code.
- Code templates — Starter templates for Hello World, SavedVariables, guarded status bars, addon compartment menus, and combat queues.
- AI prompts — The standing system prompt, specialized porting prompts, error diagnosis, and pre-flight review prompts.
- Forever Beacon — An inspectable reference sample with downloadable
.toc,.lua, and.zipfiles.
Questions players and authors actually ask FAQ
Will Classic addons work in WoW Forever?
Most Classic addons will not load as-is. Blizzard confirmed that Forever shares Mainline's UI architecture and the Midnight combat disarmament rather than Classic Era's combat API. Cosmetic, bag, map, and quest addons are worth evaluating for a port, while combat-log damage meters are not.
What interface version do WoW Forever addons use?
The WoW Forever beta client uses interface 16001. You can confirm the version on your client by running /dump select(4, GetBuildInfo()) in the chat box.
Can an AI write a WoW Forever addon?
Only if you provide explicit constraints before generating code. Untutored models emit deprecated globals like GetSpellInfo, interface 110207, and COMBAT_LOG_EVENT_UNFILTERED. Using the standing system prompt and verification checklist prevents these errors.
Are addons banned in WoW Forever?
No. Blizzard confirmed addons are supported, with the restrictions introduced for Midnight including secret values in combat. Blizzard's stated goal is that addons remain optional, with a built-in damage meter and cooldown manager provided in the base client.
What is Camelot in the beta client?
Camelot was Blizzard's internal working name for the Forever game type within the Mainline client family during early development. Blizzard stated the internal identifier would be normalized before launch, so addons should not hardcode Camelot as a public project identifier.