Addon Architecture
Initialization and load order
SpectrumFederation.toc is the authoritative load order. Libraries and foundational modules load first, followed by Loot Helper models, the sync protocol, settings, UI pages, Loot Helper windows, modules/Init.lua, and finally SpectrumFederation.lua.
There are two initialization paths:
modules/Init.luainitializes settings storage/application, Mouse Tracer, and the standalone settings UI.SpectrumFederation.luahandlesPLAYER_LOGIN, initializes diagnostics and Loot Helper persistence, enables sync, and registers feature slash commands.
Modules share the table passed by WoW as the addon's second vararg:
Major subsystems
| Area | Responsibility |
|---|---|
modules/core.lua |
Shared class metadata and time/version helpers. |
modules/NameUtil.lua |
Realm-aware player normalization and comparison. |
modules/MessageHelpers.lua |
Consistent user-facing chat messages. |
modules/debug.lua |
Persistent, bounded diagnostic logging. |
modules/SlashCommands.lua |
/sf dispatch and feature command registry. |
modules/Settings/ |
Defaults, migrations, path-based storage, per-character storage, and runtime application. |
modules/MouseTracer/ |
Optional per-character cursor trail: cached settings, fixed-pool rendering, and account-wide copy snapshots. |
modules/UI/Settings/ |
Page/category registry, navigation model, standalone window, controls, dialogs, and page definitions. |
modules/LootHelper/ |
Profile, member, and log domain models plus serialization, the current communication adapter, and runtime-only local impersonation. |
modules/LootHelperSync/ |
Session state, validation, requests, convergence, heartbeat, routing, bulk handlers, and public API. |
modules/UI/LootHelper/ |
Roster/equipment presentation and controller logic. |
modules/RaidCheck.lua |
Inspection cache, equipment evaluation, whispers, snapshots, and point awards. |
modules/VersionCheck.lua |
Raid/party addon-version query, roster snapshot, and /sf version window. |
Persistent data
The TOC declares:
SpectrumFederationDB— account-wide settings, profiles, logs, equipment snapshots, and resumable sync-session identity.SpectrumFederationDebugDB— debug enabled state and up to 500 diagnostic entries.SpectrumFederationCharDB— character-specific settings storage.
WoW serializes plain tables, not metatables. Loot Helper database initialization restores LootProfile, Member, and LootLog metatables after SavedVariables load.
Settings schema migrations normalize older database shapes before defaults are merged. Domain models also contain compatibility normalization for profile snapshots and older saved fields.
Event and update flow
Profile mutations create immutable LootLog entries. Member point and equipment state is rebuilt from these entries, and Loot Helper events refresh the visible roster.
flowchart LR
UI[Admin action] --> Model[Profile or Member method]
Model --> Log[Append LootLog]
Log --> Replay[Rebuild derived member state]
Log --> Sync[Broadcast or later synchronize]
Replay --> Events[Loot Helper data event]
Events --> View[Roster and log views refresh]
Settings follow a separate path:
flowchart LR
Control[Settings control] --> Store[SettingsStore]
Store --> Saved[SavedVariables]
Store --> Callback[Registered callbacks]
Callback --> Apply[SettingsApply / feature controller]
Permissions
LootProfile:IsCurrentUserAdmin() and IsCurrentUserOwner() are canonical membership queries. Named-sender, protocol, and sync authorization also stay canonical and can never be granted by Preview as Non-Admin.
Local user-facing capability (Settings controls, roster/equipment actions, member and profile mutators, local loot-log creation, Raid Check start/consequences, and user-triggered session start/end) uses SF.LootHelperImpersonation effective local admin/owner. That overlay is a runtime-only one-way downgrade bound to the active profile. It is not persisted, does not change SavedVariables or sync payloads, and is cleared by profile switch/clear/delete/reset, canonical admin loss, and /reload.
Authorization is enforced by specific guarded domain methods, log insertion, and sync validation, but Store adapters and low-level LootProfile mutators are not uniformly guarded. Callers must check authorization before invoking an unguarded write path; disabled UI controls alone are not a security boundary. Sync verifies group membership, sender identity, and profile authorization before accepting network changes.
The profile creator is the initial owner and admin. Ownership and admin membership use normalized Name-Realm identifiers. Use NameUtil for comparisons because connected-realm and short-name forms can differ.
Combat and asynchronous APIs
Settings application can debounce and defer work until PLAYER_REGEN_ENABLED.
Raid inspection and item information are asynchronous and throttled. RaidCheck.lua queues inspect requests, caches current and profile-backed snapshots, tracks pending/stale states, and notifies UI listeners through a snapshot version.
Sync scheduling similarly centralizes jitter, retry, timeout, and timer behavior instead of making handlers block.
Public extension points
The codebase exposes internal addon APIs on SF, including:
SF:RegisterSlashCommand(...);SF.SettingsStoreandSF.SettingsApply;SF.SettingsUI:RegisterPage(...);SF.LootHelperEvents;SF.LootHelperSyncpublic session and safe-mode methods;SF.Debugand message helpers.
These are internal project APIs, not stable third-party compatibility guarantees. Prefer feature-level methods over writing SavedVariables directly.
Child addons
SpectrumFederation_CursedSurgeTracker and SpectrumFederation_RCLootCouncilIntegration are sibling addon folders packaged in the same release zip. Each declares ## Dependencies: SpectrumFederation, ## Group: SpectrumFederation, and ## X-SpectrumFederation-Parent: SpectrumFederation so WoW nests them under the parent in the AddOns list and the parent Settings UI can discover them. The RC child also sets ## X-SpectrumFederation-Settings-Host: lootHelper so it registers under Loot Helper instead of creating an Optional sidebar row. See RC Loot Council Integration.
The parent does not load child Lua/XML and does not depend on the child. Discovery uses TOC metadata only. Optional children may read _G.SpectrumFederation for Debug, slash registration, and SF:Now(). The assignment is made in modules/Init.lua so the parent remains fully usable when no child is present.