moduleloadout.swf
The Module Loadout panel in Trove — Geode's Discovery Suit loadout (
$ModuleLoadout_WindowName, "DISCOVERY SUIT LOADOUT") — where a player equips and swaps active modules, passive modules, and reliquaries on their character, and views/swaps their active companion. It is opened from the character sheet and supports both PC and console navigation.
Document/main class: ModuleLoadout (extends _kiwi.Core.UIComponent)
SWF-specific classes: 9 game-logic classes (plus 5 ModuleLoadout_fla timeline symbols and ~35 asset-wrapper/skin classes)
Main class: ModuleLoadout
ModuleLoadout is the root UIComponent. The constructor calls addFrameScript(0→frame1, 11→frame12), then calls __setProp_swapCompanion_Scene1_swapBtn_0() to configure the companion swap button's translate label, and registers a FRAME_CONSTRUCTED listener to re-apply timeline component inspector properties when the frame changes.
configUI() is the main initialisation:
- Listens for
CLICKonm_acceptButtonandswapCompanion. - Listens for
CLICKonm_moduleList["closeBtn"]to close the swap module window. - Hides
m_moduleListand setscompanionIcon.data = 4(companion type default). - Registers all
ExternalInterfacecallbacks whenIggyFunctions.inIggyis true.
The draw() override (triggered by STYLES invalidation) re-positions companion stat labels, compressing leading to fit all stats above the swap companion button.
Public methods (also registered as ExternalInterface callbacks in Iggy)
setCompanionName(name:String)— shows and setscompanionNameTextField; invalidates STYLES.addCompanionStat(text:String)— appends aStatTextinstance above the companion swap button; invalidates STYLES for layout. Each line arrives already formatted by the engine (+{0} {1}in the client), e.g. "+25% Rocket Boot Acceleration".clearCompanionStats()— hides allStatTextinstances.addModule(iconImage, itemImage, tooltipTitle, tooltipDesc, rarity:int, hotkey:String, showSwap:Boolean, itemIndex:int)— adds aModuleItem(active module slot);itemIndexis the engine's slot number (0–1) and becomes the slots'data; positions it vertically atmoduleListYPosition + n * moduleListSpacing; adjusts description text alignment based on whether an icon image is present.clearModules()— hides allModuleIteminstances.addModuleListItem(moduleIndex, iconImage, abilityImage, name, desc, level, rarity:int, isUnlocked:Boolean, hotkey:String, rarityColor:uint)— adds aModuleSelectButtonto the swap-module popup list (m_moduleList), laid out in a 2-column grid.clearSelectModuleList()— hides allModuleSelectButtoninstances and resets console cursor.addPassiveModule(iconImage, name, desc, level:String, rarity:int, levelColor:uint)— adds aModulePassiveto a 2-column grid on the right side. The fourth argument is the module's level text (e.g. "Level 10") and the last its colour — the same pairaddModuleListItemputs intomoduleLevel— but this method drops both: onlymoduleNameis written, andname/descgo to the slot tooltip.clearPassiveModules()— hides allModulePassiveinstances.addReliquary(index, iconImage, name, desc, xp:Number, maxXp:Number, isLocked:Boolean, rarityIndex:int)— adds aMegaItem(reliquary slot); positioned atreliquaryListYPosition + n * reliquaryListSpacing.clearReqliquaries()— hides allMegaIteminstances.moveSelection(dx:int, dy:int)— console D-pad navigation across 4 selection modes (0=active modules, 1=passive modules, 2=reliquaries, 3=companion swap button).activateCurrentSelection()— triggers click on whichever console-selected element is active (module swap, reliquary swap, accept, companion swap, or aModuleSelectButton).
Key fields
m_acceptButton : LabelButton— "Accept" button; translate key$Accept; firesAcceptClickedvia ExternalInterface.m_moduleList : MovieClip— container for the swap-module popup; holdscloseBtnand the dynamically addedModuleSelectButtonchildren. The SWF only ever hides it (once, inconfigUI); the engine opens the list by settingm_moduleList.visible = trueafter answeringOpenSwapModule.swapCompanion : MovieClip(configured asLabelButton) — translate key$ModuleLoadout_SwapBtnCompanion; firesOnSwapCompanion.companionIcon : ArtClip— renders the companion's portrait;data = 4on init. Filled by the engine, which also writesdisplayNameanddescriptionon it.companionName : TextField— companion name label.companionRarity : TextField— companion rarity label; positioned belowcompanionNameindraw(). Its text comes from the engine; the SWF never assigns it.unequippedCompanionText : TextField— shown when no companion is equipped. The engine sets its text and visibility; itsvisibleflag is what marks "no companion".petBackground : MovieClip— visual background for the companion panel; also driven by the engine.currentIndex : int(private) — slot id of the controller-selected element: 0–1 active modules, 2–3 reliquaries, 4 companion, −1 for a passive module. Same numbering as the slots'data(ModuleItemgetsitemIndex,MegaItemgetsindex + 2,companionIconis 4).passiveModules : Array— pool ofModulePassiveinstances.moduleSelectList : Array— pool ofModuleSelectButtoninstances (in the swap popup).moduleButtons : Array— pool ofModuleIteminstances.companionStats : Array— pool ofStatTextinstances.reliquariesList : Array— pool ofMegaIteminstances.currentSelection : MovieClip— currently console-highlighted element.currentSelectedModule : int— index of the highlighted item inmoduleSelectList(−1 = none).m_selectionMode : int— 0=active modules, 1=passive modules, 2=reliquaries, 3=companion.- Layout constants:
moduleListXPosition=108.45,moduleListYPosition=72.55,moduleListSpacing=127.45,reliquaryListXPosition=110,reliquaryListYPosition=361.35,reliquaryListSpacing=125.15,passiveModuleListXPosition=596,passiveModuleListYPosition=77,passiveModuleListXSpacing=151.95,passiveModuleListYSpacing=127,NUM_PASSIVE_COLUMNS=2,companionStatXPosition=671.85,companionSkillPadding=25.6,companionRarityPadding=−4,moduleSelectListXPosition=23.75,moduleSelectListYPosition=58.45,moduleSelectListXSpacing=455.15,moduleSelectListYSpacing=184.55,passiveModuleImageSize=74.5.
Frame scripts / timeline
frame1—stop(); frame labelPC.frame12—stop(); frame labelConsole. Removesm_acceptButtonand one unnamed child; places nothing new.__setProp_handleronFRAME_CONSTRUCTED— re-appliesm_acceptButtoncomponent inspector props when the frame changes (translate key$Accept).
Runtime dependencies & integration
- IggyFunctions.inIggy — gates ExternalInterface callback registration.
- Engine-written fields — the client's string block for this screen names, besides the callbacks and outbound calls, the fields
m_moduleList,companionIcon(withdisplayName/description),companionName,companionRarity,unequippedCompanionText,petBackgroundandcurrentIndex, plus$ModuleLoadout_NoModuleTitle("Empty!") and$ModuleLoadout_NoModuleDescription("Select a module!"). The engine reaches those fields by name rather than through callbacks. - ExternalInterface.call (outgoing):
AcceptClicked,CloseSwapModule,OnSwapCompanion,OpenSwapModule(itemIndex),OnSwapReliquary(index),SelectedModule(moduleIndex). - IsConsole() — adjusts passive module tooltip style and auto-selects first item in module lists.
- HighlightUtil (
_kiwi.Util.HighlightUtil) —highlightMovieClip/unhighlightMovieClipused for console focus;ModuleSelectButton.selectHighlightused instead for select items. - Slot (
_kiwi.Controls.Slot) —setSize,setSlotSize,setRarityScale,UITooltipTitle/Description,rarity,iconImage,clickFeedbackproperties. - KiwiTextUtil.rainbowify — applied to
moduleLeveltext when rarity == 6 (stellar/radiant). - fl.core.InvalidationType.STYLES — triggers companion stat layout recalculation in
draw().
Other game-specific classes
ModuleItem— Embed symbol125; extendsUIComponent; displays one active module slot withimage(ArtClip for the module ability icon),itemImage(Slot for the item render),swapButton(LabelButton, label$ModuleLoadout_SwapBtn),moduleNameanddescriptionTextFields;onSwapClickedcallsExternalInterface.call("OpenSwapModule", itemIndex).ModulePassive— Embed symbol106; extendsUIComponent; read-only display of a passive module withitemImage(Slot),moduleName,moduleLevel,moduleDescriptionTextFields; no interaction logic. OnlymoduleNameis ever written —moduleLevelandmoduleDescriptionstay as authored.MegaItem— Embed symbol146; extendsUIComponent; reliquary slot withitemImage(Slot),swapBtn(LabelButton, label$ModuleLoadout_SwapBtn/$ModuleLoadout_UnlockBtndepending on locked state),xpBarMovieClip (fill + highlight sub-clips),reliquaryXPTextField,moduleNameTextField,lockedImage/locked/unequipped/m_emptySlotvisibility states;SetDatacomputes XP bar fill asfill.scaleX = clamp(xp/maxXp, 0, 1); callsExternalInterface.call("OnSwapReliquary", m_index).ModuleSelectButton— Embed symbol104; extendsUIComponent; shown in the swap-module popup; 4 frame labels (Default, hover, down, Locked) plus console variants (frames 1, 10, 21, 32);SetDatasetsitemRender(Slot),abilityIcon(ArtClip), name/level/description TextFields, hotkey MovieClip (console useshtmlText), and locked state;onClickfiresExternalInterface.call("SelectedModule", moduleIndex)unless locked;KiwiTextUtil.rainbowifyapplied tomoduleLevelwhen rarity == 6.StatText— Embed symbol44; trivialMovieClipwith a singletextField:TextField; used for companion stat lines.PreviewContainer— Embed symbol201; extendsArtClip; thin wrapper for companion/item preview rendering (no additional logic).Image— Embed symbol86; extendsArtClip; generic image/art display wrapper (no additional logic).ModuleCloseBtn— Embed symbol189; extends_kiwi.Controls.BaseButton; 4-state button (frames 10/20/30/40 stops) used as the close button onm_moduleList.
ModuleLoadout_fla timeline symbols (5):
equipped_18(symbol59) — 2-frame MC (frames 1, 2 stop) for equipped indicator overlay.equipedLarge_16(symbol56) — animated MC; frame 1 stops, frame 61 loops to"Pulse"label (pulse animation for equipped large slot).slotFrameLarge_15(symbol53) — 3-frame slot frame (stops at 1, 2, 3) for large slot rarity states.qualityPips_25(symbol79) — single-frame stop; quality pip indicator graphic.abilityFrame_35(symbol122) — frame 1 stop; holdshighlight:MovieClipandhotkeyText:TextFieldused by active module slots.
Asset wrappers (~35 classes): rarity_frame_*_png / rarity_frame_*_large_png / rarity_frame_*_over_png / rarity_frame_*_large_over_png (all rarity tiers: common, uncommon, rare, epic, legendary, relic, resplendent, radiant1, shadow, stellar — full and large variants with normal and hover states), slot_large, itemSlot, reliquarySlotEmpty, moduleCloseButton, btnGreen_small, btnGreenIcon_small, btnGreenIcon_medium, BtnGreen, rarity_frame_stellar_large, dummy.
Notable logic
- Object pool pattern:
ModuleItem,ModulePassive,MegaItem,ModuleSelectButton, andStatTextare all pooled —add*methods reuse existing hidden instances before creating new ones, andclear*hides them without destroying. - Console selection grid:
moveSelectionmanually encodes a grid layout — active modules (column 0, mode 0) link right to passive modules (column 1, mode 1), which link down to companion swap (mode 3); reliquaries (mode 2) sit below active modules. When the swap popup (m_moduleList) is visible, selection is redirected entirely to themoduleSelectList2-column grid. - Companion stat layout:
draw()iterates reducing line leading (0–5 px) until all stat TextFields fit above theswapCompanionbutton's y position. - Hotkey rendering: on console the
hotkey["hotkeyText"]useshtmlTextwith filters cleared; on PC it uses plaintextand the hotkey flag is visible. - MegaItem lock state: when
isLocked=truethe swap button label switches to$ModuleLoadout_UnlockBtn, the XP bar / item image hide, and a lock graphic appears.