-
Notifications
You must be signed in to change notification settings - Fork 0
Migration
Guide for addon authors moving from Ace3, LibSharedMedia, or standalone implementations to RGX-Framework.
RGX-Framework should make addon development easier, not force every addon into the same shape.
Your addon remains a normal addon table with its own branding, saved variables, features, and product logic. RGX provides reusable building blocks:
RequiredDeps: RGX-Framework- lifecycle helpers
- event, timer, and slash-command APIs
- minimap button creation
- options UI controls
- media, font, texture, and sound helpers
- theme/highlight tokens
- common gameplay callback modules
Use the existing RGX-native addons as references:
| Addon | Use As Reference For |
|---|---|
| ETL | lifecycle, Traveler's Log events, minimap launchers |
| SQP | options panels, UI controls, fonts, nameplate-heavy event wiring |
| RND | small utility addon structure with RGX events/timers/slash/minimap |
| BLU v7 | larger suite migration, sound categories, media registry pressure |
The intended migration is incremental: keep the addon working, move one repeated system at a time into RGX, and leave addon-specific behavior in the addon.
| Ace3 | RGX |
|---|---|
LibStub("AceAddon-3.0"):NewAddon(...) |
local RGX = assert(_G.RGXFramework, "Addon: RGX not loaded") |
:OnInitialize() |
RGX:OnReady(function() ... end) |
:OnEnable() / :OnDisable()
|
RGX:RegisterEvent("PLAYER_LOGIN", fn) / manual cleanup |
| Embedding mixins | RGX:Mixin(target, source) |
RGX does not use LibStub or embedding. Your addon is a plain Lua table — no framework base class required.
| Ace3 | RGX |
|---|---|
self:RegisterEvent("EVENT", handler) |
RGX:RegisterEvent("EVENT", handler, id) |
self:UnregisterEvent("EVENT") |
RGX:UnregisterEvent("EVENT", id) |
self:RegisterMessage("MSG", handler) |
RGX:RegisterMessage("MSG", handler, id) |
RGX requires an id string for targeted unregistration. This is a deliberate choice — it makes cleanup explicit and avoids the "which addon leaked this handler?" problem.
| Ace3 | RGX |
|---|---|
self:ScheduleTimer(fn, delay) |
RGX:After(delay, fn) |
self:ScheduleRepeatingTimer(fn, interval) |
RGX:Every(interval, fn) |
self:CancelTimer(timer) |
RGX:CancelTimer(timer) |
RGX timers use a native OnUpdate driver — no C_Timer dependency. The Every callback receives the timer reference as its first argument for self-cancellation.
| Ace3 | RGX |
|---|---|
self:Hook(target, "Method", handler) |
RGX:Hook(target, "Method", handler) |
self:Unhook(target, "Method") |
Not supported — RGX uses hooksecurefunc (unhookable) |
RGX hooks are post-only and permanent. If you need pre-hooks or unhooking, use your own wrapper.
| Ace3 | RGX |
|---|---|
self:RegisterChatCommand("cmd", handler) |
RGX:RegisterSlashCommand("cmd", handler, id) |
| Ace3 | RGX |
|---|---|
LibStub("AceDB-3.0"):New("MyAddonDB", defaults) |
RGX:DB("MyAddonDB", defaults) (basic) |
| Profiles, namespaces, char/realm scopes | Not yet available — see roadmap |
RGX's current DB is simpler than AceDB. Profile support is planned (see docs/ROADMAP.md).
| LSM | RGX |
|---|---|
LSM:Register("font", name, path) |
Fonts:Register(name, path, info) |
LSM:Fetch("font", name) |
Fonts:GetPath(name) |
LSM:List("font") |
Fonts:ListAvailable() |
RGX fonts carry richer metadata (family, category, license) and are grouped automatically in dropdowns by category then family.
| LSM | RGX |
|---|---|
LSM:Register("statusbar", name, path) |
Textures:RegisterBar(name, path, opts) |
LSM:Fetch("statusbar", name) |
Textures:GetBar(name) |
LSM:List("statusbar") |
Textures:ListBars() |
local Textures = RGX:GetTextures()
Textures:ImportLibSharedMedia()This pulls all registered LSM statusbar textures into the RGX registry. Fonts and sounds from LSM can be registered manually or via RegisterAddonFont / RegisterFontPack.
Before:
local fontPath = "Interface\\AddOns\\MyAddon\\media\\fonts\\MyFont.ttf"
myFontString:SetFont(fontPath, 14, "OUTLINE")After:
local Fonts = RGX:GetFonts()
Fonts:Apply(myFontString, "Inter-Regular", 14, "OUTLINE")
-- or
Fonts:Quick(myFontString, "Inter-Regular", 14, "OUTLINE") -- nil-safeBefore (manual UIDropDownMenu): 50+ lines of initialization, item creation, event wiring.
After:
local Fonts = RGX:GetFonts()
Fonts:AttachFontSelector(parent, db, "fontFamily", { label = "Font" })Before:
db.titleFont = "Inter-Regular"
db.titleSize = 14
db.titleFlags = "OUTLINE"
-- apply each separately
myLabel:SetFont(Fonts:GetPath(db.titleFont), db.titleSize, db.titleFlags)After:
Fonts:AttachStyleSelector(parent, db, "titleText")
-- db.titleText is now a style table: { font, size, flags }
Fonts:ApplyStyle(myLabel, db.titleText)BPU before:
addon:RegisterMedia("font", "Roboto", "Interface/AddOns/BattlePetUtility/media/fonts/Roboto.ttf")
local path = addon:FetchMedia("font", selectedFont)With RGX:
local Fonts = RGX:GetFonts()
local path = Fonts:GetPath(selectedFont)No per-addon font registration needed — RGX fonts are already available.
BPU before: Build font items manually for UIDropDownMenu context menus.
With RGX:
local fontItems = Fonts:CreateFontMenuItems({
current = db.fontFamily,
onSelect = function(name)
db.fontFamily = name
addon:RefreshFonts()
end,
})
-- dual-schema: func (BPU) + onClick (RGX), menuList (BPU) + children (RGX)BPU's saved variable keys are preserved:
-
fontFamily— font name string -
killFontFamily— font name string -
lootFontFamily— font name string -
percentFontFamily— font name string
These can be read by Fonts:ResolveName(db.fontFamily) which handles both name and path values.
Note: BLU is ~100% migrated to RGX-Framework (v8.0.1). The one remaining local piece is core/sounds/sharedmedia.lua, which will be replaced by RGXSharedMedia in the Tier 2 wire-up. This table maps each BLU system to its RGX equivalent.
| BLU System | RGX Equivalent | Status |
|---|---|---|
core/systems/database.lua |
RGX:NewDatabase(name, defaults, opts) — profile-aware proxy |
Done |
core/sounds/sharedmedia.lua |
RGXSharedMedia (enabled v2.0.0) + Textures:ImportLibSharedMedia()
|
Ready to wire |
core/events.lua |
RGX:RegisterEvent / RGX:RegisterMessage
|
Done |
core/runtime.lua |
RGX:After / RGX:Every / RGX:Hook
|
Done |
When migrating an addon to RGX-Framework:
- Add
## RequiredDeps: RGX-Frameworkto your TOC - Add
local RGX = assert(_G.RGXFramework, "AddonName: RGX-Framework not loaded")at the top of each file that uses RGX - Replace
C_Timer.AfterwithRGX:After - Replace manual
CreateFrame("Frame")event frames withRGX:RegisterEvent - Replace
SLASH_X1 = ...patterns withRGX:RegisterSlashCommand - Replace manual font path strings with
Fonts:GetPath(name) - Replace manual font dropdowns with
Fonts:CreateFontDropdownorFonts:AttachFontSelector - Replace hardcoded RGB values with
Colors:Get(name)/Colors:Wrap(text, name) - Wrap module-dependent init code in
RGX:OnReady(function() ... end) - Remove any embedded copies of Ace3/LibSharedMedia if no longer needed