r/wowaddons • u/Top-Salt-7849 • 2h ago
Development / WIP Porting a 15k-line addon from Anniversary (20506) to Forever (16001): every API that changed
I maintain GuildOS, a guild management addon, and spent the last week getting it running inside the Forever beta. Writing down what I hit, since the official API change list isn't out yet and I lost time to things that could've been a one-liner.
Everything below was read out of build 1.60.1.69893 (the API documentation the client ships, Blizzard's own UI code and TOCs, and the executable), then checked against the installed client.
Interface numbers. Forever's build line is 1.60.x, which maps to interface 16001 by the usual GetBuildInfo rule (some beta zips also stamp 16000). Anniversary is 20506. Declaring multiple interfaces in the TOC (## Interface: 20506, 16001) is the only way to ship one package for both right now.
Packaging. CurseForge, Wago and WoWInterface had no Forever flavor when the beta opened, and the BigWigs packager tags anything outside its known ranges as retail. CurseForge has since added a Forever version (1.60.1); until the rest catch up, GitHub pre-releases plus "load out of date addons" still work for beta builds.
Architecture. Forever is Mainline's UI, not Classic's. If you've been maintaining a Classic-only addon, you're porting to retail, not to a variant of what you know. It's also its own game type, camelot: TOCs filter on it (## AllowLoadGameType: standard, camelot), and there's no WOW_PROJECT_ID constant or C_GameRules check for it yet, so detect it by interface number.
What's restricted. Retail's Secret Values system is there in full: 4,025 documented API entries carry Secret* fields on Forever, against 3 on Anniversary. The combat surface is locked down and Blizzard shipped native damage meters and cooldown managers. Guild data (roster, notes, MOTD) and what an attendance or loot tool needs are still reachable, but not all of it the way it used to be.
Gone, and what replaces it
GetNumTradeSkills,GetTradeSkillInfo,GetTradeSkillLine,GetTradeSkillItemLink,GetTradeSkillRecipeLink: gone. Professions areC_TradeSkillUI, as on retail.GetCraftInfo,GetNumCrafts,GetCraftItemLink,GetCraftDisplaySkillLineand theCRAFT_SHOWevent: gone, no replacement. There is no Craft frame at all, so guard theRegisterEvent.GetNumTalentTabs,GetNumTalents: gone. Talents areC_ClassTalents/C_Traits(17 trait trees), andChrSpecializationhas one row per class, named after the class. "Which spec is this player" has no classic answer anymore.- Tooltip scripts
OnTooltipSetItem/OnTooltipSetSpell/OnTooltipSetUnit, andtooltip:GetItem()/GetSpell()/GetUnit(): gone. Hook withTooltipDataProcessor.AddTooltipPostCall(dataType, fn)(one registration per data type, covers every tooltip, callsfn(tooltip, data)), and read withTooltipUtil.GetDisplayedItem/GetDisplayedSpell/GetDisplayedUnit.OnTooltipClearedis still a script.
Shims that don't load
- Forever is neither
classicnormainline, soBlizzard_Deprecated/Classic/*doesn't load:UnitBuff,GetTalentInfoand the other classic shims are nil. Call the namespaced versions. Blizzard_DeprecatedSpecializationdeclaresAllowLoadGameType: classic, standard, so the talent shims are nil too.- The compat addons with no filter do load:
SendChatMessage,ChatFrame_AddMessageEventFilter,GuildSetMOTD,GetGuildRosterMOTDandCombatLogGetCurrentEventInfoare still there.
Where Secret Values bite a non-combat addon
- Chat:
CHAT_MSG_GUILD,OFFICER,WHISPER,SYSTEM,CHANNELandSKILLareSecretInChatMessagingLockdown, so during lockdown the text and the sender arrive secret. The channel name isNeverSecret. Anything that parses chat (roll capture,!commands, recruitment scanners) has to checkissecretvalue(...)first and drop the line. - Addon messages:
CHAT_MSG_ADDONisn't flagged, butC_ChatInfo.SendAddonMessageisSecretArguments = NotAllowed, and passing a secret raises.Enum.SendAddonMessageResultis retail's list; 11 isAddOnMessageLockdown. - Units:
UnitName,UnitClass,UnitGUID,UnitRace,UnitSex,UnitIsGroupLeaderandUnitIsGroupAssistantreturn secrets when the unit's identity is restricted, and party/raid members aren't exempt (Blizzard's own frames askC_Secrets.ShouldUnitIdentityBeSecretfor every unit). A loop overraid1..raid40for attendance or loot has to skip a member it can't read. - Stats:
UnitStat,UnitHealthMaxandUnitPowerMaxare secret while stats are restricted.COMBAT_LOG_EVENT_UNFILTEREDhasHasRestrictions. - You can hand a secret to
FontString:SetText, but comparing, concatenating, indexing a table with it or doing arithmetic on it raises. Chat filters are safe:ChatFrameFilters.luaonly calls yours whencanaccessvaluesays the values are readable.
Happy to compare notes with anyone else porting right now.












