WoW addon architecture patterns for BlazDamage — Engine/UI layer split, secure frame restrictions, event-driven updates, TOC metadata, SavedVariables, and common Lua pitfalls. Use when writing or reviewing any WoW addon code.
This skill covers WoW addon architecture patterns specific to BlazDamage. It translates the abstract layer rules in .github/architecture-rules.md into concrete WoW Lua patterns.
"Would this code run unmodified in a standalone Lua 5.1 interpreter with no WoW API?"
- YES →
Engine/orConfig/- NO →
UI/
This single question resolves all placement debates. When in doubt, run the code mentally without WoW and see if it breaks.
| Layer |
|---|
| What goes here |
|---|
| What's forbidden |
|---|
Engine/ | Damage formulas, stat math, description parsing, metric computation | Any WoW API: C_Spell.*, GetHaste(), CreateFrame(), etc. |
UI/ | Frames, hooks, events, overlays, tooltips, actionbar discovery | Inline damage formulas — must call Engine functions |
Config/ | Constants, saved variable defaults | WoW API, frame references |
Data/ | Static lookup tables (override data) | WoW API, Engine logic |
Engine functions take plain Lua values (numbers, strings, tables) as input. The UI layer calls WoW APIs, converts the results to plain values, then passes them to Engine.
-- ✅ Correct pattern
-- UI/StatCollector.lua
local crit = GetSpellCritChance() -- WoW API in UI layer
local avg = BD.Calculator.calculateAverage(base, crit, critMult, vers) -- plain values to Engine
-- ❌ Wrong pattern
-- Engine/Calculator.lua
local crit = GetSpellCritChance() -- WoW API call in Engine — VIOLATION
For the full list of forbidden patterns, see .github/architecture-rules.md.
WoW uses a "taint" system to prevent addons from interfering with protected (combat-relevant) actions.
Key rules:
hooksecurefunc attaches a callback to a protected function — the callback runs in a tainted contextBlazDamage is read-only (overlay display, tooltip enrichment) — it never calls protected actions, so taint is not a major concern for v1:Click(), :UseAction(), etc.ActionButton_Update and ActionButton_OnEvent are safe functions to hook via hooksecurefuncDiscovery pattern (safe for blaze): hook ActionBarButtonMixin.OnLoad or hooksecurefunc("ActionButton_Update", ...) to discover button frames and attach overlays.
Register events on a dedicated frame, not on action button frames:
-- UI/EventHandler.lua
local addonName, BD = ...
local EventHandler = {}
BD.EventHandler = EventHandler
local frame = CreateFrame("Frame")