# coa-ace3 Canonical [Ace3](https://www.wowace.com/projects/ace3) bundle for the CoA Guild 'Exiles' addon forks. Lifted from upstream [WoWUIDev/Ace3](https://github.com/WoWUIDev/Ace3) at commit [`52e5f2c`](https://github.com/WoWUIDev/Ace3/commit/52e5f2c7101b6edb02b48ea232bdda2df09d2960) (2026-05-17), with a small stack of CoA-compat patches on top (see below). Every fork in the `Exiles` org should converge on this bundle so the runtime LibStub resolution is predictable and addons can't quietly regress when one of them is disabled. ## CoA-compat patches on top of upstream | # | Issue | Fix | |---|-------|-----| | 1 | Upstream Ace3 calls `Texture:Set*Texture()` with numeric FileDataIDs in 42 places across `AceGUI-3.0/widgets/*` and `AceConfigDialog-3.0`. FileDataIDs are a retail-only API (post WoD/Legion). On the WoW 3.3.5-based CoA client, `SetTexture` only accepts string paths — passing a number silently fails and the engine renders a red placeholder. Symptom: solid-red squares where color swatches / checkboxes / window chrome should be. | Each FDID call was substituted with the string path that already lived in the trailing comment, e.g. `colorSwatch:SetTexture(130939)` → `colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")`. | | 2 | `AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua` Constructor parents its frame to the global `InterfaceOptionsFramePanelContainer`. On the CoA reworked FrameXML that global is nil at AceGUI widget-construction time, and `CreateFrame("Frame", nil, nil)` is fine, but downstream code that calls `:SetPoint` against the parent / `:Show` it via the options tree relies on a real parent. Symptom: every addon that registers a Blizzard Interface Options panel via AceConfigDialog errors during load. | Guard at line 102: `local _parent = InterfaceOptionsFramePanelContainer or UIParent` and pass `_parent` to `CreateFrame`. Widget behaviour is unchanged on retail; on CoA the panel parents to `UIParent` so the rest of the widget works. | | 3 | `AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua` `:AddToBlizOptions` uses the Dragonflight+ `Settings.*` API (`Settings.GetCategory`, `Settings.RegisterCanvasLayoutCategory`, `Settings.RegisterCanvasLayoutSubcategory`, `Settings.RegisterAddOnCategory`). The `Settings` table doesn't exist on the 3.3.5-based CoA client, so every AceConfig-driven options panel errors out the moment it's registered. | Wrap the whole `Settings.*` block in `if Settings and Settings.GetCategory then … else … end`. The `else` branch falls back to the WotLK-era `InterfaceOptions_AddCategory(group.frame)` after stamping the category name via `group:SetName(name or appName, parent)`. | ## Versions | Library | MINOR | |-----------------------|-------| | LibStub | 2 | | CallbackHandler-1.0 | 8 | | AceAddon-3.0 | 13 | | AceEvent-3.0 | 4 | | AceTimer-3.0 | 17 | | AceHook-3.0 | 9 | | AceDB-3.0 | 33 | | AceDBOptions-3.0 | 15 | | AceConfig-3.0 | 3 | | AceConfigRegistry-3.0 | 22 | | AceConfigCmd-3.0 | 14 | | AceConfigDialog-3.0 | 92 | | AceGUI-3.0 | 41 | | AceLocale-3.0 | 6 | | AceConsole-3.0 | 7 | | AceComm-3.0 | 14 | | AceSerializer-3.0 | 5 | | AceBucket-3.0 | 4 | | AceTab-3.0 | 3 | `AceTimer-3.0` calls `C_Timer.After` at load — confirmed available on the CoA Beta client. ## How to consume ### Option 1: source bundle (preferred for forks) Each `Exiles/coa-*` fork should rsync the libs it embeds from this bundle, so the diff is uniform: ```sh rsync -a /path/to/coa-ace3/AceAddon-3.0/ /path/to/coa-foo/Libs/AceAddon-3.0/ ``` Or replace the entire `Libs/Ace3/` tree in one go. ### Option 2: standalone addon Drop the contents (except `README.md` / `.gitattributes`) into `Interface/AddOns/Ace3/` and the loadable `Ace3.toc` will register every library at top priority via LibStub. Useful for non-bundling forks (`chatter`, `sexymap`, `clique`, …) to get Ace without each one carrying its own copy. ## Sync policy Bumping upstream means a single commit here, then a sweep across every fork that embeds these libs. Note the new upstream commit in the README's commit-pin line above, and re-apply the CoA-compat patches listed above against the new revision (the FDID one is mechanical — see `/tmp/fix_fdid.py` history). Keep patches **minimal and documented in this README**; prefer fixing them upstream where reasonable.