Skip to content

Getting Started

APHONIC edited this page Sep 15, 2026 · 2 revisions

Getting Started

Installation

Drop the LibAPH folder into your ESO AddOns directory, same as any other library. In your own addon's manifest, declare it as either a required or an optional dependency:

## DependsOn: LibAPH>=260915001
## OptionalDependsOn: LibAPH

Accessing the library

LibAPH.CreateStatusWindow(...)
LibAPH.GetPlatformString()

Library organization

File Covers
LibAPH.lua namespace + LibAPH.VERSION (loaded first)
Window.lua CreateStatusWindow, CreateRowList, CreateScrollListWindow, CreateCopyTextBox, CreateKeybindLabelButton, AddButtonHoverEffects, SetWindowActive, AddFragmentToScenes, RemoveFragmentFromScenes
Gamepad.lua CreateGamepadMover
Platform.lua GetPlatformString, GetPlatformServiceName
PlayerState.lua busy-state checks and movement/teleport trackers
Messaging.lua ShowDialogChained, SafeCSA, CreateChatLogger, SendRawChatLine
Cleanup.lua RunDoubleGCPass
ModuleManager.lua module manager functions
Wizard.lua ScheduleWizardIfNeeded, AutoUnloadWizardModule
Localization.lua Localize, LoadLocalization, BuildLanguagePickerControls
Format.lua diagnostic formatters
MenuState.lua PersistSubmenuOpenState and friends
MenuRefresh.lua CreateMenuLabelRefresher
LibraryVersionCheck.lua, LibraryManager.lua, KnownLibraries.lua, KnownAddonDependencies.lua, AutoEnableRequiredDeps.lua, AddonManagerTooltip.lua, AddonManagerCheckbox.lua dependency/library management
ErrorCapture.lua HookErrorCapture
SelfVersion.lua CheckSelfVersion

Your first window

local win, text_lbl = LibAPH.CreateStatusWindow({
    name = "MyAddonWindow",
    movable = not MyAddon.settings.is_ui_locked,
    isGamepad = is_pad,
    onMoveStop = function(left, top)
        MyAddon.settings.ui_x = left
        MyAddon.settings.ui_y = top
    end,
})

MyAddon.ui_window = win
MyAddon.update_ui_anchor()

Your first row list

MyAddon.rowlist = LibAPH.CreateRowList(MyAddon.window, { orientation = "vertical", padding = 6, spacing = 2 })

-- every refresh:
local texts = {}
for i, data in ipairs(sorted_list) do
    texts[i] = string.format("%s  %.1fs  (%s)", data.name, data.remaining, data.source)
end
if #texts > 0 then
    MyAddon.rowlist:SetRows(texts)
else
    MyAddon.rowlist:Clear()
end

Your first gamepad mover

MyAddon.ui_mover = LibAPH.CreateGamepadMover(win)
MyAddon.ui_mover:RegisterCallback(MyAddon.name .. "_UI", 2, function(new_pos)
    if type(new_pos.left) == "number" then MyAddon.settings.ui_x = new_pos.left end
    if type(new_pos.top) == "number" then MyAddon.settings.ui_y = new_pos.top end
end)
-- later, from a "move with stick" button:
MyAddon.ui_mover:ToggleGamepadMove(true)

Your first localized string

function MyAddon.L(key, ...)
    local id = _G["SI_MYADDON_" .. key]
    local str = id and GetString(id) or key
    if select("#", ...) > 0 then return string.format(str, ...) end
    return str
end

-- in init(), after MyAddon.settings exists:
LibAPH.LoadLocalization("SI_MYADDON_", MyAddon.Lang, "en")

Finding the right tool

Task Use
Build a moveable status window LibAPH.CreateStatusWindow
Show a variable-length list of rows without clipping LibAPH.CreateRowList
Show a long, scrollable, checkable list in its own window LibAPH.CreateScrollListWindow
Give a player a searchable, scrollable copy box for an error report LibAPH.CreateCopyTextBox
Build a keybind button (auto-updating key icon) for your own window LibAPH.CreateKeybindLabelButton
Let a gamepad player drag a window LibAPH.CreateGamepadMover
Know what platform/storefront the player is on LibAPH.GetPlatformString / GetPlatformServiceName
Delay an action until the player is free LibAPH.CheckBusyReason
Know if the player is currently moving or just teleported LibAPH.CreateMovementTracker / CreateTeleportTracker
Open a dialog from inside another dialog's callback LibAPH.ShowDialogChained
Show a center-screen banner LibAPH.SafeCSA
Print a reliable chat message (works around gamepad-mode CHAT_SYSTEM:AddMessage flakiness) LibAPH.CreateChatLogger
Run a double-pass GC sweep with a before/after diff LibAPH.RunDoubleGCPass
Let a player unload an optional feature file to save memory LibAPH.ToggleModuleDisabled + ApplyModuleDisableOverrides
Make an unloaded module toggle live instead of needing /reloadui LibAPH.RegisterModuleLifecycle + SyncModuleLifecycle
Run a first-run setup wizard once, then unload its module LibAPH.ScheduleWizardIfNeeded + AutoUnloadWizardModule
Translate your addon's text LibAPH.Localize (simple) or LibAPH.LoadLocalization (native ESO string-ID system)
Build a LAM2 language-picker control LibAPH.BuildLanguagePickerControls
Show a dependency's version status in a diagnostics panel LibAPH.FormatLibraryVersion / FormatVersionHistory
Include the player's settings in a bug report LibAPH.FormatSettingsSnapshot
Reset a player's settings to defaults LibAPH.ResetToDefaults
Strip color codes before putting text in a copy box LibAPH.StripColors
Remember whether a LAM2 submenu was left open LibAPH.PersistSubmenuOpenState
Re-apply a LAM2 control's function-based label on demand LibAPH.CreateMenuLabelRefresher
Make your addon's optional dependencies visible to /libcheck LibAPH.RegisterAddonDependencies
Capture your addon's own errors for a bug report LibAPH.HookErrorCapture
Know if your addon's own version just changed LibAPH.CheckSelfVersion

Home

Clone this wiki locally