# benilla.toc — the built-in interface, as an ordinary addon manifest. # # The reference's own interface ships as `FrameXML.toc`; ours was a hand-ordered Rust array until # decision 1178. It is parsed by the same `.toc` parser any third-party addon will be # (`benilla-ui/src/toc.rs`), and that is the point: a privileged built-in UI is how addon support # rots. If our own interface loads through the addon path, the addon path works — it is exercised # by every single run. If it keeps a private door, that path is untested by construction. # # The order is LOAD order and it is load-bearing: a template must be defined before the frame that # inherits it, and a later file paints on top of an earlier one. Every entry's comment is why it # sits where it sits; those comments are knowledge, not decoration. # # The FIRST entry is the font-object registry, and the loader splits there: it alone loads at # startup, ahead of the glue screens that share our one glyph atlas, and everything after it # materializes on entering the world (decision 1051). ## Interface: 11200 ## Title: benilla # The named virtual Font objects (decision 0084) — must load first so any FontString's # `inherits="GameFontNormal"` resolves against a registered object. Fonts.xml # The reference's own second file, in its own position: TEXT/message/_ERRORMESSAGE, the # ScriptErrors dialog, and the DialogBoxFrame + DialogButton*Texture kit it is built from. # Straight after Fonts.xml because those are the only things it needs (GameFontRedLarge, # DialogButtonNormalText/HighlightText) and everything above it in FrameXML.toc is engine. BasicControls.xml # The `SetItemButton*` family (ref ItemButtonTemplate.lua) — script-only, no frames and no # dependencies of its own, so it sits as early as it can be read. Every window that paints an item # slot calls these, ours and third-party alike: their absence is what left the director's Bagnon # window with a title, a gold line and no bag slots at all (see the file's own header). ItemButtonTemplate.xml # The reference's money-frame kit: MoneyFrameTemplate/SmallMoneyFrameTemplate + MoneyTypeInfo # + the MoneyFrame_* API. Needs only Fonts (NumberFontNormal/NumberFontNormalLarge) — and it must # come BEFORE UiPanels.xml, because the shared StaticPopup's coin row is a child frame declaring # `inherits="SmallMoneyFrameTemplate"`, which is resolved at LOAD (decision 1580). That is the # reference's own order too (FrameXML.toc: MoneyFrame.xml l.10, StaticPopup.xml l.23); this file # used to sit 140 lines lower, beside the other shared widget kits, which was only ever tenable # while nothing above it showed coins. AuctionFrame far below is laid out on it as well (its price # columns need a money TYPE, which the other kit has no notion of); our other eight coin displays # still run on MerchantFrame.xml's BenillaMoney_* slot kit, and MoneyFrame.xml's header is where # the two are reconciled. MoneyFrame.xml # The UIPanel slot manager (decision 0084 §2): script-only, no frames of its own — must load # before any panel frame (Gossip/Merchant today) so ShowUIPanel/HideUIPanel already exist # when those frames' OnLoad/OnEvent reference them. UiPanels.xml # The managed bottom-stack positions (decision 0272): script-only — # UIPARENT_MANAGED_FRAME_POSITIONS + UIParent_ManageFramePositions, the ref # UIParent.lua mechanism that re-anchors the cast bar / chat over the bottom bars. # Loaded early so the stance bar's OnShow/OnHide can call it; applied once by the # loader's post-load bootstrap (ui_script/manifest.rs). UIParent.xml # The tooltip: a hover window the bag/merchant/loot/unit frames drive. Loaded before them so # `GameTooltip` + its verbs exist when their OnEnter handlers fire (runtime, so order # is not strictly required — but it keeps the dependency legible). It also declares the two # virtual templates (GameTooltipTemplate, ShoppingTooltipTemplate), which IS an order # requirement: ItemRef.xml below expands one, and so do the 27 corpus addons that name # GameTooltipTemplate in an XML inherits=. GameTooltip.xml # The dropdown kit (0203 phase 2's closing sub-slice, widened for 0434 phase 5): # UIDropDownMenuTemplate + DropDownList1/2 + the UIDropDownMenu_* API — before its # first customers (the unit popups below, the world map's pickers, the trainer filter). UIDropDownMenu.xml # The unit right-click popups (0434 phase 5): UnitPopupMenus/Buttons + UnitPopup_ShowMenu # — after the dropdown kit it drives, before the unit/party frames whose DropDown # children's OnLoad initialize into it. UnitPopup.xml # The chat-link click router (SetItemRef): item links → ItemRefTooltip:SetHyperlink; a # player name → left-click whisper / right-click FRIEND dropdown. After GameTooltip.xml — # ItemRefTooltip inherits=GameTooltipTemplate, so this order is now REQUIRED, not just legible # (GameTooltip_OnLoad was the old, runtime-only reason) — AND after the dropdown kit + # UnitPopup, since its FriendsDropDown inherits UIDropDownMenuTemplate and opens a UnitPopup # FRIEND menu. ItemRef.xml # The shared status-bar numerals machinery (decision 1082): TextStatusBar_* + the opt-in # template — before its customers (the XP bar in ActionBar.xml today; the unit-frame # health/mana numerals are the ref's other users, when that slice lands). The ref's own TOC # loads TextStatusBar right before its unit frames, same seat as here. TextStatusBar.xml UnitFrames.xml # The combo-point dots (decision 0869) — anchored to TargetFrame, so after # UnitFrames.xml; its fade chain needs UiPanels.xml's UIFrameFade above. ComboFrame.xml # The center-screen scrolling combat text (decision 0578) — the Blizzard_CombatText # transcription; consumes COMBAT_TEXT_UPDATE + the regen/health/power events, needs # only Fonts.xml (CombatTextFont) + UIParent before it. CombatText.xml # The party member frames + the PARTY_INVITE popup + its event driver (decision 0434 # phase 2): a StaticPopup registry entry, so after UiPanels.xml. PartyFrame.xml # The death arc's dialogs + event driver (decision 0308): registry entries on the shared # StaticPopup engine, so after UiPanels.xml. DeathFrame.xml # The two duel dialogs + their event driver (decision 0633): registry entries on the same # StaticPopup engine, and DUEL_OUTOFBOUNDS leans on its per-tick countdown branch. DuelFrame.xml # The two enchant-apply confirms + their event driver (decision 0928): the same StaticPopup # registry again. Not CraftFrame's — the gate that raises them is the generic item-target # bind, reached by a poison or a sharpening stone with no profession window open. EnchantConfirm.xml # The innkeeper's bind confirm + its event driver (decision 1331): the same StaticPopup registry. # Not GossipFrame's, and the wire is why — the server closes the gossip menu BEFORE it asks, so # this dialog is free-standing by the time it shows. Needs only UiPanels.xml, far above. BinderConfirm.xml # The class trainer's respec confirm + its event driver (decision 1580): the binder confirm's twin # one line up, free-standing for the identical reason — the server closes the gossip menu before it # asks. The only entry in the registry that raises a money frame, so it needs MoneyFrame.xml (far # above, ahead of UiPanels.xml) as well as the StaticPopup engine itself. TalentWipeConfirm.xml # The shared CooldownFrame_SetTimer (the ref's Cooldown.lua file split) — before its # consumers (ActionBar's buttons, the multibars, the stance bar, BagFrame's slots). Cooldown.xml ActionBar.xml # The four OPTIONAL extra bars (bottom left/right 61-72 / 49-60, vertical right/left # 25-36 / 37-48), all shipping hidden until the player ticks their row (decision 1500): # pure XML/Lua over ActionBar.xml's shared button template + handler set. Loads right # after it, and the order is a REQUIREMENT, not tidiness: it inherits # BenillaActionButtonTemplate, anchors to ActionButton1, its buttons join the # BENILLA_ACTION_BUTTONS roster ActionBar.xml declares, its grid verbs call that file's # ActionButton_ShowGrid/_HideGrid, and its BENILLA_MULTIBARS table reads that file's # *_ACTIONBAR_PAGE constants at FILE SCOPE. UIParent.xml (far above) owns the manage pass # MultiActionBar_Update ends with, and the PLAYER_ENTERING_WORLD seed that fills the four # SHOW_MULTI_ACTIONBAR_* globals from the server's byte. MultiBars.xml # The stance/shapeshift bar: hidden until `crate::ui_shapeshift`'s feed pushes a # non-empty form list (a formless class never shows it). After Cooldown.xml # (CooldownFrame_SetTimer) + ActionBar.xml (BENILLA_FALLBACK_ICON, the MainMenuBar # anchor target). StanceBar.xml # The pet action bar (decision 0982): hidden until `crate::ui_pet`'s feed reports a bar, # i.e. until the server sends `SMSG_PET_SPELLS` for a live pet or charm — so a class that # never has one never sees it. Right after the stance bar, whose row it shares (either # one showing raises UIParent.xml's managed "pet" delta), and after Cooldown.xml # (CooldownFrame_SetTimer), ActionBar.xml (the `MainMenuBar` anchor target), # GameTooltip.xml (its hover), Fonts.xml (NORMAL_FONT_COLOR_CODE, which wraps the binding # a token slot's tooltip appends) and UIParent.xml (GetBindingText, which renders it). # It is also the pet ARC's file, so decision 1066's three # right-click-menu dialogs (ABANDON_PET / RENAME_PET / PETRENAMECONFIRM) register here — # which adds UiPanels.xml to its dependency set, already far above. PetActionBar.xml # The micro-button row in the bar's right-hand recess (the ref's own file split, its TOC # loads MainMenuBarMicroButtons right after MainMenuBar). After ActionBar.xml: it anchors # into MainMenuBarArtFrame by name and seats itself with that file's # BenillaActionBarArt_SeatAbove. It must come BEFORE the panels it toggles, because each of # their OnShow/OnHide calls the `UpdateMicroButtons` this file defines (the panel frames # themselves are read back through getglobal, so the reverse dependency is call-time). MicroMenu.xml # The HUD minimap cluster (decision 0203 phase 1): the chrome around the engine-rendered # widget hole (`crate::minimap` fills it). After GameTooltip (its zone-text # hover uses the shared tooltip). MinimapCluster.xml # The minimap's time-of-day indicator (GameTimeFrame): the reference's own file split — its # TOC loads GameTime.xml right after Minimap.xml. After MinimapCluster (its parent) and # GameTooltip (the hover tooltip); driven by the app's game clock (`minimap::feed_game_time`). GameTime.xml # Print screen's UI half (decision 1487): the centred "Screen Captured"/"Screen Capture Failed" # line, and the `TakeScreenshot()` the SCREENSHOT binding runs. Needs Fonts.xml (SystemFont) and # UIParent.xml (its seat) — both far above — and nothing else; seated beside ZoneText.xml, whose # AutoFollowStatus is the same full-screen-frame-with-a-centred-line shape. ScreenshotStatus.xml # The zone-entry splash (decision 0287): ZoneTextFrame/SubZoneTextFrame + the inlined # FadingFrame kit, driven by the ZONE_CHANGED family `crate::area` fires. Needs only # Fonts (ZoneTextFont/SubZoneTextFont) + UIParent; kept by the minimap cluster — the # other consumer of the zone-text host globals. ZoneText.xml # The faux-scroll kit (decisions 0247/0250/0251): BenillaScrollBarTemplate (the draggable # Slider scroll bar) + FauxScrollFrameTemplate + the reference's own FauxScrollFrame_* # API (Update/GetOffset/SetOffset/OnVerticalScroll + ScrollFrame_OnLoad) — # before its first customer (the trainer list) below. ScrollTemplates.xml # The reference's SHARED widget kit (decision 1203's queue): UIPanelButtonTemplate, # UICheckButtonTemplate, UIPanelCloseButton, InputBoxTemplate, the UIPanelScroll* family and # their siblings, under the reference's own names — the templates a third-party addon names in # `CreateFrame(kind, name, parent, "Template")`, which nothing in benilla's own XML consumes # yet (each of our windows still carries its private copy; see the file's header). After # ScrollTemplates.xml because UIPanelScrollFrameTemplate's OnLoad is that file's # ScrollFrame_OnLoad, and this file supplies the two remaining handlers of that same kit # (ScrollFrameTemplate_OnMouseWheel, ScrollFrame_OnScrollRangeChanged). UIPanelTemplates.xml # The reference's shared OPTIONS widgets: OptionsCheckButtonTemplate / # UIOptionsCheckButtonTemplate / OptionsSliderTemplate / OptionsButtonTemplate / # OptionFrameBoxTemplate. Straight after UIPanelTemplates.xml — two of them inherit its # UICheckButtonTemplate and UIPanelButtonTemplate. Not benilla's own options window # (OptionsFrame.xml, far below): these are the shared names addons build panels out of. OptionsFrameTemplates.xml # The shared colour dialog + its opacity slider (`ColorPickerFrame`, `OpacitySliderFrame`, # `ColorPickerOkayButton`, `ColorPickerCancelButton`). Last of the "shared FrameXML surface with no # benilla consumer yet" cluster that runs from UIPanelTemplates.xml down — the same posture as # MoneyFrame.xml above, and for the same reason: 86 of the 218 corpus addons reach this window (64 # of those files are `Dewdrop-2.0.lua`, which drives THIS one rather than rolling its own), and # nothing we ship opens it. The seat is a REQUIREMENT, not tidiness: its Okay/Cancel buttons # `inherits="GameMenuButtonTemplate"`, which is resolved at LOAD, and that template lives in # UIPanelTemplates.xml six lines up (it moved there from GameMenuFrame.xml — the reference's own # file for it — precisely because GameMenuFrame.xml is deliberately LAST). Everything else it needs # is far above (Fonts' GameFontNormal/…Small trio; UiPanels' ShowUIPanel/HideUIPanel, its # UISpecialFrames entry and the ESC rung that cancel-clicks it). UIDropDownMenu.xml, which owns the # colour-swatch row that OPENS this window, sits above too — but that direction is call-time only # (`UIDropDownMenuButton_OpenColorPicker` reaches `ColorPickerFrame` by name when the swatch is # clicked), so the two could sit either way round. ColorPickerFrame.xml # The fullscreen world map (decision 0203 phase 2), over the worldmap host API # (`crate::ui_world_map` feeds it); the 'M' binding (ui_script/input.rs) calls its # ToggleWorldMap(). WorldMapFrame.xml # The cast bar (decision 0137 phase 1) — the extracted 1.12 CastingBarFrame, driven by # the SPELLCAST_* events `crate::ui_cast` fires. Only needs Fonts before it. CastingBar.xml # The mirror timers (decision 0874): the breath/fatigue bars at top-center, driven by the # MIRROR_TIMER_* events `crate::ui_mirror` fires. Needs only Fonts (GameFontHighlight) # before it; kept beside the cast bar, whose border art it shares. MirrorTimer.xml # The always-up world-state readout (decision 1586, report B190): the tower/flag/base counters an # outdoor-PvP zone or a battleground shows at top-centre, driven by the UPDATE_WORLD_STATES event # `crate::world_state_ui` fires. Needs Fonts (GameFontNormalSmall) and GameTooltip; sits beside the # mirror timers, which share its top-centre lane. WorldStateFrame.xml # The player buff/debuff bar (decisions 0255/0257 — the player aura arc): the HUD row of # aura icons under the minimap, driven by the UnitAura feed (`crate::ui_aura`). Needs Fonts # (its FontStrings) and ActionBar's `BENILLA_FALLBACK_ICON` global (both already loaded). BuffFrame.xml # The durability alert (the "armor guy"): under the minimap beside BuffFrame, driven by # UPDATE_INVENTORY_ALERTS off the same inventory push the character window reads. Needs # MinimapCluster (its anchor) — loaded above. DurabilityFrame.xml ErrorsFrame.xml BagFrame.xml # The stack-split spinner (decision 0216 §6/slice 2): loaded beside BagFrame, whose slot # click handler (`BenillaBagSlot_OnClick`) calls `OpenStackSplitFrame`. Order between the # two doesn't matter for correctness (Lua globals resolve at call time, and neither file's # XML `inherits=` reaches into the other's templates) — kept adjacent for legibility. StackSplit.xml # Our ADAPTERS over the reference's own `Interface\\FrameXML\\ContainerFrame.lua`, which this # client EXECUTES off the patch chain rather than transcribing (`ui_script::reference_ui`) — see # that file's header for the rule. Must load AFTER the sourced reference file (every builtin does) # and after BagFrame/StackSplit, whose globals it leans on. ContainerFrameAdapters.xml # The character window (decision 0208 phase 1a): the C-key paper doll. Loaded after BagFrame # (needs nothing from it, but keeps player-state windows grouped) and before the NPC session # windows (Gossip/Merchant/Quest*) — it depends only on Fonts/UiPanels/GameTooltip, all # already loaded above. CharacterFrame.xml # The Pet tab (decision 1057): the same separate-top-level-file shape as SkillFrame below, # and ahead of it because it is the earlier tab. It leans on CharacterFrame.xml for real — # the `(unit, prefix)` stat setters, the `BenillaStatRow`/`BenillaMagicResistanceFrame` # templates and the tab row it raises tab 2 of — all of which only exist once that file has # loaded, so this order is a requirement here, not just tidiness. PetPaperDollFrame.xml # The Reputation tab: the same separate-top-level-file shape as the two pages around it, seated # BETWEEN them because that is the real client's tab order (Character 1, Pet 2, Reputation 3, # Skills 4 — ref CharacterFrame.xml:79-168), and the page's `id=` is that slot. Its hard # dependencies are all far above: CharacterFrame.xml (the anchor target it is pinned to by name, # and the tab row it raises tab 3 of), ScrollTemplates.xml (the faux list + its trough template), # UIPanelTemplates.xml (`UIPanelCloseButton`, the detail popup's X — this page is that shared # template's first benilla consumer), OptionsFrameTemplates.xml (`OptionsCheckButtonTemplate`, two # of the three detail boxes), GameTooltip.xml (the column newbie tips) and Fonts.xml. One # dependency runs the other way and is worth naming: the WATCH BAR half of the reference's # ReputationFrame lives in ActionBar.xml (entry 94) beside the MainMenuBar frames it drives — that # file's own comment carries the justification — so `FACTION_BAR_COLORS` and # `ReputationWatchBar_Update` are already defined when this page paints a row or ticks the # "Show as Experience Bar" box. ReputationFrame.xml # The Skills tab (decision 0437 phase 4): a CharacterFrame child page, but a separate # top-level file (SkillFrame.xml's own header comment — this engine has no cross-file # `parent=` attachment, so it's positioned by name via `` instead). Loaded after CharacterFrame.xml so it paints ON TOP of # it (later file = higher z) and so `CharacterFrame` already exists for that anchor to # resolve against — seated at the real client's own tab 4, between Reputation above and # Honor below. SkillFrame.xml # The Honor tab: the same separate-top-level-file shape as the three pages above it, and LAST of # them because it is the last of the tabs (the real client's 5, ref HonorFrame.xml:5) — which # CLOSES the row: the character window's five tabs are now the reference's five, in its order, at # its numbers, with nothing left past the end. Its hard dependencies are all far above: # CharacterFrame.xml (the anchor target it is pinned to by name, the tab row it raises tab 5 of, # and the `CharacterNameText` its level line hangs under), GameTooltip.xml # (`BenillaTooltip_AddNewbieTipFor`, which all five of its hovers go through) and Fonts.xml # (GameFontGreenSmall/GameFontRedSmall carry the honorable/dishonorable colouring, and # HIGHLIGHT_FONT_COLOR the tip titles). # It must come BEFORE InspectFrame.xml, and that order is a REQUIREMENT rather than tidiness: the # inspect window's own honor page inherits the five `HonorFrame*ButtonTemplate` row templates # declared here, and `inherits=` resolves at LOAD. The reference has the identical edge — its # `HonorFrameTemplates.xml` is ``d by `HonorFrame.xml` and inherited by the LoadOnDemand # `Blizzard_InspectUI`, which loads later still. HonorFrame.xml # The inspect window (decision 0631): another player's paper doll. Beside the character # window it mirrors — it needs the same three (Fonts/UiPanels/GameTooltip) plus # `CharacterFrameTabButtonTemplate` from UiPanels.xml, and nothing from CharacterFrame.xml # itself (its slot template, handlers, and booth slot are all its own — the two windows # share only the reference's art). ONE cross-window dependency does bind, and it is on the # entry directly above: this window's honor page inherits HonorFrame.xml's five row templates # and calls its two shared painters, the same sharing the reference does. InspectFrame.xml # The dressing room (decision 1060): the ctrl-click item preview. Loaded right after the # windows whose slots feed it (the character window above, the bags before that) and before # everything else that ctrl-clicks into it — order is legibility only, since `DressUpItemLink` # is a global resolved at call time. Needs UiPanels (the panel manager, its left-slot row) and # Fonts; its booth pane needs nothing loaded at all. DressUpFrame.xml # The spellbook window (decision 0216 §8, slice 5): the P-key window, the spell SOURCE # for the cursor-payload arc. Loaded right after CharacterFrame (the same "player-state # windows grouped" posture, same Fonts/UiPanels/GameTooltip-only dependency set); the # 'P' binding (ui_script/input.rs) calls its bare ToggleSpellBook(BOOKTYPE_SPELL). SpellBookFrame.xml # The talent window (decision 0304 §4): the N-key window, the class talent grid over the # `benilla-ui::script::talent` engine seam. Loaded right after SpellBookFrame (the same # "player-state windows grouped" posture; needs Fonts/UiPanels/GameTooltip plus # ScrollTemplates.xml — its real ScrollFrame's scrollbar reuses BenillaScrollBarTemplate — # all already loaded above). The 'N' binding (ui_script/input.rs) calls its bare # ToggleTalentFrame(). TalentFrame.xml # The social window (decision 0668): the O-key friends/ignore/who window over the social # API (`benilla-ui/src/script/social.rs`) + `crate::ui_social`'s feed/drain. Needs # UiPanels (the panel manager, `CharacterFrameTabButtonTemplate`, and the StaticPopup # engine its two name-entry dialogs register into), ScrollTemplates (three faux lists), # GameTooltip (the newbie tips) and UIDropDownMenu (the who list's variable column) — # all loaded above. FriendsFrame.xml # The social window's fourth tab, in its own file because RaidFrame is a child of FriendsFrame and # a child cannot be declared before its parent — the reference splits it the same way and for the # same reason (its FrameXML.toc has RaidFrame.xml on the very next line). Decision 1549. RaidFrame.xml GossipFrame.xml MerchantFrame.xml # The mail window (decision 0544 P1/P2): the mailbox inbox, open-letter, and send tab over # the Era mail API (`benilla-ui/src/script/mail.rs`) + `crate::ui_mail`'s feed/drain. Loaded # right after MerchantFrame because it REUSES that file's global BenillaMoney_Set/_Clear # coin helpers (postage/enclosed/COD displays) — they must be defined first. MailFrame.xml # The player-to-player trade window (decision 0592 P1): the two-sided offer over the trade # API (`benilla-ui/src/script/trade.rs`) + `crate::ui_trade`'s feed/drain. Loaded after # MerchantFrame because it REUSES that file's global BenillaMoney_Set coin helpers (the two # gold displays) — they must be defined first. TradeFrame.xml # The item-text reader: letters (mail-made permanent copies) and, later, books/plaques — # the ItemTextGet* seam (`benilla-ui/src/script/item_text.rs`) over `crate::ui_item_text`'s # feed/drain. Loaded right after MailFrame (the same arc; needs only Fonts/UiPanels, both # loaded above). ItemTextFrame.xml # The trainer window (decision 0237 phase 3): the read-only class/profession trainer list. # Loaded right after MerchantFrame per the director's brief (kept adjacent even though this # v1 uses plain-text costs, not MerchantFrame's coin helpers) and before the other NPC # session windows below. TrainerFrame.xml # The bank window (decision 0604 phase 4): the vault, purchase ladder, and the 6 bank-bag # popouts, over the container feed already carrying container -1/5..10 (ui_items.rs) + # the bank Lua surface (benilla-ui/src/script/bank.rs) + crate::ui_bank's feed/drain. # Loaded AFTER MerchantFrame.xml (reuses its BenillaMoney_* coin helpers for the purchase # row + purse) and AFTER BagFrame.xml, already above (its BenillaBagSlotTemplate/ # BenillaBagWindowTemplate + the BenillaBagSlot_*/BenillaBagFrame_* function family are # reused verbatim — the 24 generic slots and the 6 bank-bag popouts are, respectively, a # container-slot grid and ordinary container windows, exactly like the bag arc's own). # Kept in the "NPC session windows grouped" cluster beside Trainer/Taxi. BankFrame.xml # The taxi-map window (decision 0484 phase 2): the flight-master session, driven by the # taxi engine seam (`benilla-ui/src/script/taxi.rs`) over `crate::ui_taxi`'s feed/drain. # Loaded right after TrainerFrame per the same "NPC session windows grouped" posture — it # needs only Fonts/UiPanels/GameTooltip (SetTooltipMoney), both already loaded above. TaxiFrame.xml # The stable-master window (decision 1676): the hunter's three-slot pet stable over the stable # API (`benilla-ui/src/script/stable.rs`) + the app's feed/drain. Kept in the "NPC session # windows grouped" cluster beside Trainer/Bank/Taxi. Two of its dependencies are resolved at # LOAD and so must sit above it: MoneyFrame (its purse and cost displays inherit # SmallMoneyFrameTemplate) and UIPanelTemplates (UIPanelButtonTemplate / UIPanelCloseButton). # A third is resolved at load too, and is the reason this cannot sit up with the other NPC # windows' dependencies: the model pane's own calls CharacterFrame.xml's shared # `BenillaPaperDollModel_OnLoad`, so that file must already have run. The rest # (ItemButtonTemplate's SetItemButtonTexture, GameTooltip, UiPanels' ShowUIPanel/HideUIPanel, # UIParent's BuildListString) are resolved when the window repaints, so their order is free. PetStable.xml # The auction house (decision 1511): the three-tab doublewide window over the auction API # (`benilla-ui/src/script/auction.rs`) + the app's feed/drain. Kept in the "NPC session # windows grouped" cluster beside Trainer/Bank/Taxi, and loaded AFTER MoneyFrame (its eight # money displays are SmallMoneyFrameTemplate, and it registers the AUCTION_DEPOSIT money type # into that file's MoneyTypeInfo), after MerchantFrame (it reuses that file's global # BenillaMoneyInput_* helpers for its four money inputs), after ScrollTemplates (four faux lists), after # UIPanelTemplates (UIPanelButtonTemplate / UIPanelCloseButton / InputBoxTemplate / # UICheckButtonTemplate), after UIDropDownMenu (the rarity capsule) and after UiPanels (the # panel manager's `doublewide` seat, `CharacterFrameTabButtonTemplate`, the PanelTemplates # tab kit and the StaticPopup engine its two confirmations register into) — all above. AuctionFrame.xml # The crafting window (decision 0437 phase 2): NOT an NPC session (opens off your own cast of # an effect-47 opener spell, TradeSkillFrame.xml's own header comment) — loaded right after # TrainerFrame per the same "player-state/profession window" grouping and because it depends # on nothing TrainerFrame doesn't already need (Fonts/UiPanels/GameTooltip/ScrollTemplates, # all loaded above). TradeSkillFrame.xml # The Enchanting window (decision 0437 phase 3): the exact twin of TradeSkillFrame above — # same "opens off your own cast, not an NPC session" shape (CraftFrame.xml's own header # comment) — loaded right after it so `BuildColoredListString` (a guarded GLOBAL # TradeSkillFrame.xml defines) already exists when CraftFrame.xml reuses it without # redefining (CraftFrame.xml's own header comment, deviation 2). CraftFrame.xml LootFrame.xml # The group-loot roll popups (decision 0591): the Need/Greed/Pass dialogs, a sibling of # LootFrame.xml (loaded right after it) over the `benilla-ui::script::loot_roll` seam # (`crate::ui_loot_roll`'s feed/drain). NOT a UIPanel — four `frameStrata="DIALOG"` toplevel # popups with their own hardcoded anchors — so it needs only Fonts (GameFontNormalSmall) + # GameTooltip (the item/PASS/NEED/GREED hovers), both already loaded above. GroupLootFrame.xml # The questgiver window (decision 0088): four sub-panels over the Era quest API. Loaded after # MerchantFrame (the BenillaMoney coin helpers live there) and GossipFrame (shared parchment # art conventions); its title/panel-button labels use the auto-centred ButtonText slot. QuestFrame.xml # The two guild-charter windows (decision 1672): the guild registrar — the window the "How do I # form a guild?" gossip row opens — and the charter itself, the sheet nine people sign. Loaded # here, right after QuestFrame, because both wear the QuestGreeting parchment and its QuestFont / # QuestTitleFont objects and read as that family; they need UiPanels (the panel manager seats both, # and PetitionFrame registers its RENAME_GUILD dialog on the shared popup engine), MoneyFrame (the # registrar's price rides MoneyFrameTemplate, resolved at LOAD — decision 1580's ordering rule) and # UIPanelTemplates (the close/action buttons), all far above. The registrar must come first: no # load-order dependency links them, but the flow does, and the pair reads in the order it is used. GuildRegistrarFrame.xml PetitionFrame.xml # The quest log window (decision 0088 arc, the quest-log slice): durable player state, not an # NPC session — loaded after MerchantFrame (the BenillaMoney coin helpers it reuses) and # alongside QuestFrame (same arc); the 'L' binding (ui_script/input.rs) calls its # ToggleQuestLog(). QuestLogFrame.xml # The timed-quest countdown window under the minimap (decision 1150): the reference's own # file split. After MinimapCluster (its anchor), UIParent (the manage pass that re-seats it, # and SecondsToTime), GameTooltip (its row hover), and QuestLogFrame — whose window a row # click opens, and whose MAX_QUESTS it shares. QuestTimerFrame.xml ChatFrame.xml # The macro window (decision 0983): the editor + its name/icon popup, driven over the # engine's OWN macro table (`benilla_ui::script::macros` — 1.12 macros have no server # side, so this is the one window whose model is not an app feed). Needs UiPanels (the # panel manager + `TabButtonTemplate`), ScrollTemplates (BOTH kits — the real one scrolls # the body box, the faux one the icon grid), MicroMenu (`UpdateMicroButtons` on # show/hide), and it must come AFTER SpellBookFrame, whose shift-click reaches # `BenillaMacroFrame_AddMacroLine`. Before GameMenuFrame, whose Macros button opens it. MacroFrame.xml # The script error log (decision 1495): the window `/errors` opens — the list B293's two # reporters asked for, which the reference's one-message-at-a-time ScriptErrors modal cannot # be. Ours entirely (1.12 has no counterpart), reading the retained log on the model rather # than any per-frame feed. Needs ScrollTemplates (BOTH kits — the faux one for the fixed row # list, the real one for the traceback pane), UIPanelTemplates (the Clear/Close buttons) and # UiPanels (ShowUIPanel/HideUIPanel + the UIPanelWindows row that seats it and gets it closed # by ESC). Before GameMenuFrame, which is deliberately last. ScriptLogFrame.xml # The GM help window + the ticket-status toast (the HelpFrame.xml transcription): the third # **center**-area UIPanelWindows row, so it opens like the game menu and the options window and # shuts every other panel on the way in. It heads the SHELL TAIL for that reason — Help, then the # options pair, then the game menu last — and it goes ahead of KeyBindingsPage.xml rather than # between it and OptionsFrame.xml, because those two are a hard must-load-before pair and nothing # should be wedged into it. Every dependency is far above: UiPanels (ShowUIPanel/HideUIPanel, the # UIPanelWindows row, and the StaticPopup engine its three ticket dialogs register into), # UIPanelTemplates (UIPanelCloseButton, UIPanelButtonTemplate2, GameMenuButtonTemplate and the # real UIPanelScrollFrameTemplate the ticket editor is built on), ScrollTemplates (the faux kit # behind the GM category list, its shared trough, and the ScrollingEdit pair), GameTooltip (the # toast wears the tooltip backdrop colours at OnLoad) and MicroMenu (whose Help button calls this # file's ToggleHelpFrame, and whose UpdateMicroButtons this file calls back on show/hide — both # resolved at call time, so that pair could sit either way round). The one seat that is a REAL # requirement rather than legibility is **after BuffFrame.xml**: the toast re-anchors # TemporaryEnchantFrame out of its own way, and that frame is declared there. HelpFrame.xml # The cinematic frame: the ESC that skips a fly-by, and the SCREENSHOT chord it hands back. It # draws NOTHING — the letterbox moved to Bevy UI nodes in `crate::cinematic` (decision 1699), # because the lane this frame paints into is dark for the whole shot. # Needs UiPanels.xml far above for ShowUIPanel/HideUIPanel and its own UIPanelWindows row; needs # nothing else, and nothing needs it — the engine reaches it purely by firing CINEMATIC_START. # Seated late because it is an outermost, screen-owning layer, like the two windows below it. CinematicFrame.xml # The Keybindings page MODULE (decision 1008, superseding 0997's standalone window): # the templates + script of the Options window's Keybindings category, over the # engine's binding table (benilla_ui::script::keybind + crate::bindings — the 1.12 # GetBinding/SetBinding Lua API). Needs UiPanels (popup engine) and GameTooltip (the # character-specific checkbox's hover); MUST load before OptionsFrame.xml, whose # Keybindings body inherits these templates and calls this script at OnLoad. KeyBindingsPage.xml # The options window (the 0985 provenance split: 0950's era structure, 0978's # 1.12-native art, 0981/0984's 1.14 chrome + working era search, 0989's directed # cuts — bare fully-live sliders, no corner X; 0992's dropdown rows + the Nameplates # page): the era-shaped OptionsFrame the game menu's Options button opens. Needs # Fonts' objects, UiPanels' panel manager, and UIDropDownMenu's capsule template # (all far above); sits right before GameMenuFrame so the menu — which reaches it by # name at click time — stays the last, outermost layer. OptionsFrame.xml # The game menu (decision 0674): the frame ESC opens, plus the CAMP/QUIT dialogs and their # event driver. LAST on purpose — it is the outermost layer of the shell, it depends on # everything it touches being loaded (UiPanels' popup engine + panel manager, MicroMenu's # UpdateMicroButtons, BagFrame's Disable_BagButtons), and nothing depends on it: the ESC # chain and the micro button both reach it by name at call time. GameMenuFrame.xml