Skip to content

Latest commit

 

History

History
953 lines (724 loc) · 39 KB

File metadata and controls

953 lines (724 loc) · 39 KB

TODO.md - SUF Enhancement Implementation Roadmap

Last Updated: 2026-03-12 Current Phase: Step 6 — Final Documentation + Release Validation Pass Status: Step 6 documentation/release validation complete; release commit/publish flow in progress ⏳


PERFORMANCE COALESCER PILOT (2026-03-10)

Status: ✅ VALIDATED (2026-03-12)

Implemented in code:

  • Added shared spell bucket in performance routing:
    • SPELL_UPDATE_COOLDOWN + SPELL_UPDATE_CHARGES -> one coalesced dispatch bucket
  • Added BAG_UPDATE debounce in performance coalescer path
  • Routed low-risk handlers to CustomTrackers update paths (without broad full-frame refresh)
  • Added lightweight debug counters with slash helpers:
    • /suf coalescer reset
    • /suf coalescer

Validation checklist (single dungeon run):

  • Before entering dungeon: run /suf coalescer reset
  • Complete one dungeon run with performance integration enabled
  • After run: run /suf coalescer
  • Confirm spell bucket shows reduced raw -> dispatched
  • Confirm bag debounce shows reduced raw -> dispatched
  • Confirm CustomTracker bars still update correctly for cooldown/charges/bag-driven changes

Observed result (2026-03-12):

  • /suf coalescer reported: SPELL_UPDATE_COOLDOWN+SPELL_UPDATE_CHARGES 6002 -> 2700 (~55.0% reduction)
  • /suf coalescer reported: BAG_UPDATE 38 -> 21 (~44.7% reduction)
  • CustomTracker bars updated correctly for cooldown, charges, and bag-driven changes during the run.

Next if validation passes:

  • Expand coalescer coverage to the next safest non-unit buckets only (incremental rollout).

DATATEXT ENHANCEMENT TRACK (XIV Comparison)

Step 5c: Extended Layout & GUI Ordering (7-slot / full-width / taller)

Status: ✅ VALIDATED (2026-03-12)

Implemented in code:

  • Added 7-slot DataText layout (outerLeft, farLeft, left, center, right, farRight, outerRight)
  • Added per-slot LDB display mode controls (AUTO, TEXT, ICON, ICON_TEXT)
  • Increased default DataText panel height to 40 (double-height baseline)
  • Expanded width control max and runtime clamp so panel can fill full screen width
  • Moved DataText dropdown controls higher in both OptionsV2 and legacy GUI sections

Step 5c Validation Checklist:

  • Switch to 7 Slots (Extended) and verify all seven entries render without overlap
  • Verify Outer Left / Outer Right source dropdowns enable only in 7-slot layout
  • Verify DataText width can be adjusted to full screen width and clamps correctly
  • Verify default/new profile DataText height starts at 40px
  • Verify LDB display mode per-slot (AUTO/TEXT/ICON/ICON_TEXT) renders as expected
  • Verify dropdown ordering in GUI matches updated top-priority control flow

Observed result (2026-03-12):

  • Full Step 5c validation passed in-game with no reported problems.

Step 5b: LDB Tooltip + Click Integration (HidingBar-style)

Status: ✅ VALIDATED (2026-03-12)

Implemented in code:

  • Enhanced LDB text rendering in DataText buttons:
    • supports icon + text/value/label fallback composition
  • Added robust LDB tooltip fallback path when broker has no OnTooltipShow:
    • supports tooltiptext, value/suffix, multiline rows
  • Added hover compatibility for broker callbacks:
    • OnEnter / OnLeave support
    • hovered-source tracking for tooltip refresh
  • Added click compatibility improvements:
    • AnyUp click registration
    • dispatch OnClick(frame, button) with fallback to OnMouseUp
  • Added live LibDataBroker attribute callback handling:
    • LibDataBroker_AttributeChanged now triggers datatext refresh
    • active tooltip refreshes while hovered on relevant key changes

Step 5b Validation Checklist:

  • Test with an LDB launcher addon (icon/label only) and verify click opens expected panel
  • Test with an LDB data source addon (text updates) and verify DataText updates without waiting for ticker cycle
  • Verify tooltip fallback renders when broker has no OnTooltipShow
  • Verify broker-provided tooltip still works when OnTooltipShow exists
  • Verify broker OnEnter/OnLeave paths do not break tooltip lifecycle
  • Verify middle/right click dispatch for LDB sources registered for those buttons

Observed result (2026-03-12):

  • Full Step 5b validation passed in-game; LDB tooltip and click behavior showed and worked correctly.

Next after Step 5b validation:

  • Fold any addon-specific click edge cases into a tiny compatibility shim (only if needed).

Step 3: High-Value Provider Upgrades

Status: ✅ VALIDATED (2026-03-12)

Implemented in code:

  • Upgraded builtin Currencies datatext provider with cap-aware formatting and weekly progress tooltip rows.
  • Added builtin Reputation datatext provider with support for:
    • standard standings,
    • friendship standings,
    • major faction renown,
    • paragon reward-pending state.
  • Upgraded reputation databar text/tooltip to use the same normalized watched-faction logic.
  • Added event-driven refresh wiring for faction/currency/renown updates:
    • UPDATE_FACTION
    • CURRENCY_DISPLAY_UPDATE
    • MAJOR_FACTION_RENOWN_LEVEL_CHANGED
    • MAJOR_FACTION_UNLOCKED

Step 3 Validation Checklist:

  • Select Currencies in a DataText slot and verify cap + weekly rows in tooltip
  • Select Reputation in a DataText slot and verify normal standing/progress display
  • Verify friendship faction watched display (rank text + progress handling)
  • Verify major faction watched display (renown styling/progress)
  • Verify paragon watched display and pending reward indicator (! + tooltip line)
  • Verify reputation databar tooltip matches datatext standing/progress state
  • Verify left-click actions (TokenFrame for currencies, ReputationFrame for reputation)
  • Verify event-driven updates after rep/currency changes without requiring UI reload

Observed result (2026-03-12):

  • Full Step 3 validation passed in-game; the upgraded provider and databar behavior showed and worked correctly.

Step 5: Panel Layout Expansion (optional)

Status: ✅ VALIDATED (2026-03-12)

Implemented in code:

  • Added configurable datatext slot layout (3 classic / 5 expanded) with profile key datatext.panel.slotCount.
  • Expanded slot model to support farLeft and farRight alongside left/center/right.
  • Refactored DataText panel runtime layout to dynamically size/position buttons per active slot count.
  • Added configuration controls in both OptionsV2 and legacy OptionsWindow for layout + far slot source assignment.

Step 5 Validation Checklist:

  • Switch to 5 Slots (Expanded) and verify five datatext fields render with no overlap at default width
  • Verify farLeft and farRight source dropdowns become enabled only in 5-slot layout
  • Verify switching back to 3 Slots (Classic) hides far slots and preserves left/center/right content
  • Verify drag/edit mode still works for the panel in both layouts
  • Verify tooltip/click behavior still works for all visible slots (builtin/custom/LDB)
  • Verify System and LDB:* slot assignments persist and render correctly after /reload and fresh login (no reselect required)

Observed result (2026-03-12):

  • Full Step 5 validation passed in-game; the panel layout expansion and related databar/datatext behavior showed and worked correctly.

Next after Step 3 + Step 5 validation:

  • Step 6: Final documentation + release validation pass

Step 6: Final Documentation + Release Validation Pass

Status: 🟡 IN PROGRESS (2026-03-12)

Completed at kickoff:

  • Refresh CHANGELOG.md for 1.33.1 with validated DataText and coalescer work
  • Refresh README.md recent updates, commands, and feature summary for the current validated feature set

Remaining Step 6 checklist:

  • Do a final release-metadata consistency pass (SimpleUnitFrames.toc, changelog version, README release references)
  • Draft the final release summary / publish notes for the validated DataText and coalescer work
  • Decide whether coalescer expansion is release-blocking or deferred to the next work cycle
  • Confirm no additional documentation updates are needed before packaging/release prep

Step 6 result (2026-03-12):

  • SimpleUnitFrames.toc (1.33.1.31226), CHANGELOG.md, and README.md are aligned on 1.33.1 release metadata.
  • Final publish notes drafted in RELEASE_NOTES_v1.33.1.md.
  • Validated low-risk coalescer work is included in this release scope; broader next-bucket expansion is deferred to follow-up work.

SHAMAN TOTEMS INTEGRATION (2026-03-05)

Status: ✅ VALIDATED (2026-03-12)

Objective: Display Shaman totem information (slot 1-4) above player auras via oUF Totems element

What Was Implemented:

  1. Totems Widget Constructor (CreateTotems function):

    • Creates 4 totem button frames (36px × 36px each, 4px spacing)
    • Each button has Icon texture and Cooldown CooldownFrame
    • Follows oUF element contract per Libraries/oUF/elements/totems.lua
  2. Player Frame Instantiation (Shaman-gated):

    • Added CreateTotems call in player Style (line ~8991-9000)
    • Guards with UnitClassBase check to ensure Shamans only
  3. Dynamic Anchor Chain (ApplySize layout):

    • Primary anchor: Above Auras (if visible) — respects multi-row aura layout
    • Fallback 1: Above ClassPowerAnchor (if visible) — for when auras disabled
    • Fallback 2: Above AdditionalPower (if visible) — secondary fallback
    • Fallback 3: Above main frame (if nothing else visible)
    • Prevents totem disappearance under any configuration
  4. Event Integration (Dirty event routing):

    • PLAYER_TOTEM_UPDATE event coalesced with power events
    • IsFrameEventRelevant updated to recognize Totems
    • UpdateFrameFromDirtyEvents routes updates to Totems element
  5. Spec-Change Reliability (OnClassResourceContextChanged):

    • Added Totems.ForceUpdate hook alongside ClassPower/AdditionalPower
    • Ensures clean state on spec/form transitions

Files Modified:

  • SimpleUnitFrames.lua (5 locations):
    • Line ~7654-7682: CreateTotems function (28 lines)
    • Line ~8991-9000: Player Style instantiation (9 lines)
    • Line ~7376-7421: ApplySize anchoring logic (46 lines)
    • Line ~3282: IsFrameEventRelevant Totems check (1 line modified)
    • Line ~3382: UpdateFrameFromDirtyEvents SafeUpdateElement (1 line added)
    • Line ~10037-10039: OnClassResourceContextChanged ForceUpdate (3 lines added)

In-Game Testing Checklist:

  • Cast behavior: Cast a totem and verify it appears above auras with icon/cooldown
  • Expiration: Totem expires after duration ends; frame hides cleanly
  • Replacement: Replace active totem (e.g., swap fire totem); new one renders correctly
  • Multi-row auras: With 12+ auras causing 2-row layout, totems stay above full stack
  • Auras disabled: Hide player auras; verify totems anchor to ClassPowerAnchor (or fallback) and remain visible
  • Spec switch: Swap specs (e.g., Enhancement ↔ Restoration); totems update cleanly without stale state
  • Form changes: Shapeshift forms (e.g., Bear/Cat for Druid mains) don't break totem layout
  • Combat context: Cast totems in combat; verify event handling works without combat lockdown issues

Observed result (2026-03-12):

  • Shaman Totems integration worked in-game with no reported problems or errors.

Implementation Quality Metrics:

  • Code Reuse: Follows existing class-resource patterns (CreateClassPower, CreateAuras)
  • Maintainability: Zero custom event handling; relies on oUF's built-in PLAYER_TOTEM_UPDATE
  • Performance: Minimal overhead; event-driven with dirty coalescing (included in power event batch)
  • Compatibility: Works with existing aura/class-power/additional-power layout system

Known Limitations & Future Enhancements:

  • Totem Size: Currently hard-coded to 36px × 36px (no UI customization yet)
  • Totem Dismiss: Right-click functionality not implemented (future enhancement)
  • Keybindings: No default keybindings for totem casting (rely on Blizzard defaults)
  • Multi-class: Implementation Shaman-specific (other classes don't benefit; patch as needed if added)

Next Steps:

  1. ✅ Code implementation complete
  2. ✅ In-game testing complete
  3. ✅ No bug-fix cycle required from current validation
  4. ✅ WORK_SUMMARY.md updated with final validated status
  5. ⏳ Consider optional enhancements (configurable size, positioning, right-click dismiss)

Low-effort, high-confidence enhancements. Start here.

Scope update: Task 1.1 removed. Focus is Midnight API 12.0.x only.


Task 1.2: Expand Safe Value Helpers (45 min)

Objective: Add 4 missing safe value wrappers (SafeCompare, SafeArithmetic, SafeToNumber, SafeToString)

Status: ✅ COMPLETE (2026-03-03)

What to Do:

  1. Open SimpleUnitFrames.lua safe value section (lines ~765-835)
  2. Add functions:
    SafeCompare(a, b)              -- Compare values without arithmetic
    SafeArithmetic(val, op, fall)  -- Safe arithmetic (+, -, *, /, %)
    SafeToNumber(val, fall)        -- Convert to number with pcall
    SafeToString(val, fall)        -- Convert to string with pcall
  3. Add to addon helper exports (_core)
  4. Document pattern (comment block at top)

Files to Modify:

  • SimpleUnitFrames.lua (safe helpers section, ~30 new lines)

Validation:

  • Editor diagnostics check passed (no syntax/errors in modified files)
  • /reload and verify no errors (in-game verification pending)
  • Check each function in debug console (/run print(SafeCompare(...))) (in-game verification pending)

Implementation Notes:

  • Confirmed helper functions exist and are exported: SafeCompare, SafeArithmetic, SafeToNumber, SafeToString
  • Refined SafeArithmetic to support proper operand math with backward compatibility for legacy 3-arg usage
  • Unified wrappers so SafeNumber uses SafeToNumber and SafeText uses SafeToString

Time Estimate: 45 min
Difficulty: Easy
Risk: 🟢 LOW


Task 1.3: SafeReload System (1 hour)

Objective: Prevent "addon action forbidden" when reloading during combat Status: ✅ COMPLETE (2026-03-03)

What to Do:

  1. Create Core/SafeReload.lua with:
    function addon:SafeReload()
        if InCombatLockdown() then
            addon:QueueOrRun(function()
                ReloadUI()
                -- Show confirmation popup
            end, {
                key = "SafeReload",
                type = "UI_RELOAD",
                priority = "NORMAL"
            })
        else
            ReloadUI()
        end
    end
  2. Register in SimpleUnitFrames.lua
  3. Call from OptionsWindow.lua reload buttons
  4. Add to SimpleUnitFrames.toc load order

Files to Create:

  • Core/SafeReload.lua (60-80 lines)

Files to Modify:

  • SimpleUnitFrames.lua (register SafeReload method)
  • Modules/UI/OptionsWindow.lua (call SafeReload on reload buttons)
  • SimpleUnitFrames.toc (add Core/SafeReload.lua)

Validation:

  • /reload in safe zone (should reload immediately)
  • Try reload during combat scenario (should queue for after combat)
  • Verify no "addon action forbidden" errors

Implementation Notes:

  • Core/SafeReload.lua already existed with full implementation
  • Updated PromptReloadAfterImport() to use SafeReload
  • Updated OptionsV2/Layout.lua reload button to prefer SafeReload
  • All ReloadUI() calls now route through SafeReload when available

Time Estimate: 1 hour
Difficulty: Easy-Medium
Risk: 🟢 LOW (only called from option buttons)


Task 1.4: Profile Import Validation (1 hour)

Objective: Prevent crashes from malformed profile import strings

Status: ✅ COMPLETE (2026-03-03)

What to Do:

  1. Create Modules/UI/ProfileValidator.lua with ValidateImportTree function
  2. Check for:
    • Correct data types (no functions, threads, userdata)
    • Depth limits (max 20 levels deep)
    • Node count limits (max 50k nodes)
  3. Integrate into core import validation path (ValidateImportedProfileData) so all import handlers are protected
  4. Show user-friendly error messages on failure

Files to Create:

  • Modules/UI/ProfileValidator.lua (80-120 lines)

Files to Modify:

  • SimpleUnitFrames.lua (call ValidateImportTree before payload unwrap/deep copy)
  • SimpleUnitFrames.toc

Validation:

  • Editor diagnostics check passed (no syntax/errors in modified files)
  • /reload and test normal profile import (should work)
  • Try importing a corrupted profile string (should show error)
  • Verify error message is clear to user

Implementation Notes:

  • Added iterative addon:ValidateImportTree() helper in Modules/UI/ProfileValidator.lua
  • Enforces unsupported type rejection (function, thread, userdata) in keys and values
  • Enforces limits: max depth 20, max table nodes 50000
  • Detects cycles/repeated table references and blocks unsafe payloads
  • Wired into ValidateImportedProfileData() before UnwrapImportedPayload() so legacy + OptionsV2 imports are both protected

Time Estimate: 1 hour
Difficulty: Medium
Risk: 🟢 LOW (only adds validation, doesn't change success path)


Phase 1 Summary:

  • Total Time: 3-3.5 hours
  • Total Risk: LOW across all items
  • Outcome: Cleaner codebase, better error handling, future-proof APIs
  • Next: Move to Phase 2 after validation

PHASE 2: UI/Visual Improvements (8-10 hours total)

Medium-effort, high-value enhancements. Better user experience.

Task 2.1: Accent Color Theme System (2-3 hours)

Objective: Single accent color picker → all UI colors automatically update

Status: ✅ COMPLETE (2026-03-03)

What Was Implemented:

  1. ✅ Created color derivation functions in Theme.lua:
    • LerpColor(r1,g1,b1,r2,g2,b2,t) - Linear interpolation between colors
    • DarkenColor(r,g,b,factor) - Reduce brightness by factor (0-1)
    • LightenColor(r,g,b,factor) - Increase brightness toward white
    • GenerateAccentVariants(r,g,b) - Create base/soft/dark/light RGBA variants
  2. ✅ Built accent color cache system:
    • addon:UpdateAccentColor(r,g,b) - Updates cache and propagates to all UI colors
    • addon:GetAccentColor() - Returns current accent RGB from cache
    • addon.accentColorCache - Stores all color variants
  3. ✅ Added accent color picker to Options (Global/Theme section):
    • Color picker widget in Registry.lua
    • Saves to db.profile.media.accentColor
    • Real-time UI refresh on color change via ScheduleUpdateAll()
  4. ✅ Integrated into reload flow:
    • Accent color default in profile (SimpleUnitFrames.lua line 67)
    • Color restoration in OnInitialize() (SimpleUnitFrames.lua line ~9940)
    • Automatic restoration on /reload

Files Modified:

  • Modules/UI/Theme.lua (added 100+ lines of color math at lines 665-790)
  • Modules/UI/OptionsV2/Registry.lua (added color picker widget at line 3730+)
  • SimpleUnitFrames.lua (added default at line 67, restoration at line ~9940)

Validation:

  • Syntax validation passed (all 3 files: no errors)
  • In-game test: Open options → Global/Theme tab → change accent color (Working ✅)
  • In-game test: Verify all UI elements update (buttons, controls, text, backgrounds) (All elements update correctly ✅)
  • In-game test: /reload and verify color persists (Color persists across reload ✅)
  • Performance test: Rapidly changing accent color with no FPS drops or stutters (Smooth 60 FPS ✅)

Implementation Notes:

  • Color derivation uses HSL-inspired math: darken/lighten adjust brilliance while preserving hue
  • Soft color (reduced saturation variant) helps with UI contrast balance
  • All THEME references update dynamically through cache layer
  • Profile migration automatic for existing users (defaults applied on first load)
  • Process is event-driven (no polling overhead)

Time Estimate: 2-3 hours (completed)
Difficulty: Medium
Risk: 🟢 LOW (all changes validated, no regression risk)


Task 2.2: Search Navigation Enhancement (1-2 hours)

Objective: Search results now navigate to correct tab + scroll to section + pulse highlight

Status: ✅ COMPLETE (2026-03-04)

What Was Implemented:

  1. Scroll to Section — Auto-scrolls page to bring matched section into view
    • Calculates section TOP anchor position relative to scroll content
    • Uses SetVerticalScroll() to position section 50px from top
    • Handles multi-anchor frames correctly (iterates all GetPoint() anchors)
  2. Pulsing Text Highlight — Matched control label pulses continuously
    • Changes FontString color to accent color
    • Uses C_Timer.NewTicker(0.5s) for continuous pulse effect
    • Alternates between accent color and original color
    • Pulse continues until search box cleared (backspace or ESC)
  3. False Positive Filtering — Eliminates duplicate page-level matches
    • Search index contains both page-level (sectionKey=nil) and section-level entries
    • Filters out page-level matches when section-level matches exist for same page
    • Prevents "Failed condition check" false positives
  4. Cleanup on Clear — All pulse timers canceled when search cleared
    • OnTextChanged handler detects empty search box
    • OnEscapePressed handler cancels all active timers
    • Restores all FontStrings to original colors

Files Modified:

  • Modules/UI/OptionsV2/Layout.lua (scroll calculation + pulse system at lines ~425-495)
  • Modules/UI/OptionsV2/Renderer.lua (section frame storage at lines ~607-610)
  • Modules/UI/OptionsV2/Search.lua (false positive filtering at lines ~156-175)

Technical Details:

  • WoW API Discovery: ScrollToChild() doesn't exist → used SetVerticalScroll(pixels) with manual calculation
  • Frame Hierarchy: GetChildren() returns child frames; GetRegions() returns FontStrings/textures
  • Anchor System: Iterates all GetPoint() anchors to find TOP anchor relative to pageContent
  • Pulse Storage: addon._searchHighlightedRegions array tracks all pulsing FontStrings for cleanup

Validation:

  • Syntax validation passed (all 3 files: no errors)
  • In-game test: Search for "health" → jumps to correct section (Working ✅)
  • In-game test: Page scrolls to section position (Scrolling correctly ✅)
  • In-game test: Matched label pulses continuously (Pulsing perfectly ✅)
  • In-game test: Clear search (backspace) → pulse stops and color restores (Cleanup working ✅)
  • In-game test: Press ESC to clear → pulse stops and color restores (ESC handler working ✅)
  • In-game test: No false positives (page-level matches filtered ✅)

Implementation Notes:

  • Deferred callback (0.1s) ensures page render completes before scroll/highlight
  • Debug logging removed after validation (production-ready code)
  • Pulse timer cleanup prevents memory leaks and orphaned timers
  • Color restoration uses stored __searchOriginalColor RGBA values
  • Search result filtering happens at query time (not render time)

Time Estimate: 1-2 hours (completed)
Difficulty: Medium
Risk: 🟢 LOW (all edge cases handled, cleanup robust)


Task 2.3: Modular Builders Refactor (4-5 hours)

Objective: Break OptionsV2/Renderer.lua BuildGUIPanel into smaller, testable functions

Status: 🔴 NOT STARTED

Implementation Strategy:

  1. Scroll to Section — Use pageScroll:ScrollToChild() to scroll section into view
  2. Visual Highlight — Tint section background briefly to show user where match is
  3. Control-Level Matching — Track which specific control matched (if applicable)

Files to Modify:

Step-by-Step Implementation:

Step 2.2.1: Enhance search index to track control-level info

  • Modify Search.lua so each search result includes closest parent section frame
  • Track control index within section for precision matching

Step 2.2.2: Add section frame storage in Renderer

  • When rendering sections, store frame reference on page content
  • Store as addon._optionsV2SectionFrames[pageKey][sectionKey] = sectionFrame

Step 2.2.3: Implement scroll-to-result function

  • Create addon:ScrollOptionsV2SearchResult(pageKey, sectionKey)
  • Use pageScroll:ScrollTochild(sectionFrame) if available
  • Add tint animation (highlight section for 1 second)

Step 2.2.4: Integrate into RunSearch

  • After SetPage(), call scroll function with match data
  • Verify no conflicts with existing navigation

Validation:

  • Search for setting (e.g., "health color")
  • Click result → should navigate to correct tab and scroll to section
  • Section should highlight briefly to show where match is
  • Verify existing search still works (no regressions)

Time Estimate: 1-2 hours
Difficulty: Medium
Risk: 🟢 LOW (enhancement to existing search, non-breaking)


Task 2.3: Modular Options Page Builders (3-4 hours)

Objective: Break up OptionsV2 page specs into separate builder files (code quality)

Status: ✅ COMPLETE (2026-03-04)

What to Do:

  1. Extract each OptionsV2 page into separate builder file under Modules/UI/OptionsV2/Builders/
  2. Register builders in central registry (addon._optionsV2Builders)
  3. Route GetOptionsV2PageSpec() through builder delegation first
  4. Remove inline legacy blocks from Registry once all builders are stable

Files Created:

  • Modules/UI/OptionsV2/Builders/ (new directory)
  • Modules/UI/OptionsV2/Builders/*.lua (one per page)

Files Modified:

  • Modules/UI/OptionsV2/Registry.lua (builder delegation + all legacy branches removed)
  • SimpleUnitFrames.toc (load builder files before Registry)

Completed Work:

  • CreditsBuilder.lua extracted
  • TagsBuilder.lua extracted
  • PerformanceBuilder.lua extracted
  • ImportExportBuilder.lua added (placeholder page, previously unimplemented)
  • UnitsBuilder.lua added (routes player/target/tot/focus/pet/party/raid/boss)
  • GlobalBuilder.lua fully extracted (standalone global page spec + helpers)
  • CustomTrackersBuilder.lua fully extracted (1159 lines: 6 sections, state management, all helpers)
  • Registry.lua builder delegation added with skipBuilderLookup fallback flag
  • Removed all inline legacy page branches from Registry.lua (performance, tags, credits, units, global, customtrackers)
  • SimpleUnitFrames.toc updated with builder load order

Implementation Notes:

  • CustomTrackersBuilder.lua contains complete standalone implementation (1159 lines):
    • BuildMediaOptions helper (LSM font/texture integration)
    • BuildCustomTrackersPageSpec() function with all sections (manage, layout, position, visibility, cooldown, entries)
    • State management closures (ctState.selectedBarID, GetBars, GetSelectedBar, SetBarField, etc.)
    • Dynamic entry button row generation (inline - / U / D controls)
    • All 6 section control arrays preserved from original inline implementation
  • Registry.lua now only contains builder delegation and defaults fallback (all inline page specs removed)

Validation:

  • Syntax validation passed (CustomTrackersBuilder.lua and Registry.lua: no errors)
  • In-game: all 14 pages render correctly
  • In-game: all settings apply and persist
  • In-game: Custom Trackers page fully functional (bar CRUD, entry management, all 6 tabs)
  • In-game: search navigation still works across extracted pages
  • In-game: no visual regressions / lua errors on /reload

Time Estimate: 3-4 hours (completed)
Difficulty: Hard (large refactor)
Risk: 🟢 LOW (validated, non-breaking)


Task 2.4: Sidebar Tab UI Architecture (6-8 hours) [OPTIONAL - Next Phase]

Objective: Adopt vertical sidebar tabs like QUI (visual overhaul)

Status: 🔴 DEFER to Phase 3
Reason: Largest change, requires careful UX testing


Phase 2 Summary:

  • Total Time: 6-9 hours (or 12-13 with Task 2.4)
  • Total Risk: LOW to MEDIUM
  • Outcome: Better UX, client-friendly colors, easier code maintenance
  • Blockers: None (all items independent)
  • Next: Phase 3 visual polish after validation

PHASE 3: Visual Polish (5-6 hours total)

High-impact visual improvements.

Task 3.1: Pixel-Perfect Scaling System (4-5 hours)

Objective: Unit frames render cleanly at all UI scales (75%, 100%, 125%)

Status: ✅ COMPLETE (2026-03-04)

  1. Study QUI's implementation (scaling.lua, lines 1-100)
  2. Create Core/PixelPerfect.lua with:
    • GetPixelSize(frame) → physical pixel size
    • Pixels(n, frame) → round to nearest pixel
    • PixelRound(value, frame) → utility
  3. Cache screen dimensions on UI_SCALE_CHANGED
  4. Update all frame sizing in Units/ directory
  5. Update Theme.lua border creation
  6. Update Movers.lua position tracking

Files to Create:

  • Core/PixelPerfect.lua (80-120 lines)

Files to Modify:

  • Units/Player.lua, Units/Target.lua, Units/Pet.lua, Units/Focus.lua, Units/Tot.lua (sizing)
  • Modules/UI/Theme.lua (border creation)
  • Modules/System/Movers.lua (position tracking)
  • SimpleUnitFrames.lua (cache screen dimensions)
  • SimpleUnitFrames.toc

Validation:

  • Screenshot unit frames at 75% UI scale (borders clean)
  • Screenshot at 100% UI scale (borders consistent)
  • Screenshot at 125% UI scale (no seams/gaps)
  • Test window drag/resize (pixel-perfect positions preserved)

Time Estimate: 4-5 hours
Difficulty: Hard (touches many files, many edge cases)
Risk: 🟡 MEDIUM (visual regressions possible)

Value: 🟢🟢 HIGH (most visible improvement)


Phase 3 Summary:

  • Total Time: 4-5 hours
  • Total Risk: MEDIUM (visual testing critical)
  • Outcome: Professional appearance at all UI scales
  • Visual Impact: HIGH (users immediately notice improvement)
  • Next: Phase 4 or community feedback

Task 3.1: Pixel-Perfect Scaling System (4-5 hours)

Objective: Unit frames render cleanly at all UI scales (75%, 100%, 125%)

Status: ✅ COMPLETE (2026-03-04)

What Was Implemented:

  1. ✅ Created Core/PixelPerfect.lua (342 lines)
    • Core pixel math: GetPixelSize(), Pixels(), PixelRound/Floor/Ceil()
    • Frame-aware sizing: SetPixelPerfectSize/Width/Height()
    • Pixel-aligned positioning: SetPixelPerfectPoint(), SetSnappedPoint(), SnapFramePosition()
    • Backdrop creation: SetPixelPerfectBackdrop() for exact N-pixel borders
    • Texture snapping: ApplyPixelSnapping() using WoW 12.0+ APIs (SetSnapToPixelGrid, SetTexelSnappingBias)
    • Smart scale utilities: GetSmartDefaultScale() (0.53 for 4K, 0.64 for 1440p, 1.0 for 1080p)
    • Event system: UI_SCALE_CHANGED handler with cached screen dimensions
  2. ✅ Applied pixel-perfect sizing to frame creation via addon:ApplySize()
  3. ✅ Applied texture snapping to 9 StatusBar types (Castbar, ClassPower, Health/Power prediction bars)
  4. ✅ Integrated into Theme.lua backdrop creation
  5. ✅ Fixed initialization order (PixelPerfect now initializes after database setup)
  6. ✅ Added nil guards for early calls before frame spawning

Files Created:

  • Core/PixelPerfect.lua (342 lines)

Files Modified:

  • SimpleUnitFrames.lua (InitializePixelPerfect() call, SnapFrameToPixelGrid() helper, ApplySize() update, frame creation snapping)
  • Modules/UI/Theme.lua (EnsureBackdrop() pixel-perfect integration)
  • SimpleUnitFrames.toc (load order)

Validation:

  • Static syntax/error validation passed (all 3 files: no errors)
  • Fixed 2 critical initialization errors (ipairs nil guard, db nil guard)
  • In-game validation: /reload successful, no Lua errors
  • In-game visual test: Borders clean at 75% UI scale ✅
  • In-game visual test: Borders clean at 100% UI scale ✅
  • In-game visual test: Borders clean at 125% UI scale ✅
  • In-game test: Window drag/resize preserves pixel alignment ✅
  • Performance test: No FPS impact from pixel calculations ✅

Implementation Notes:

  • Studied QUI's scaling.lua (487 lines) as reference implementation
  • Pixel-perfect formula: pixelSize = 768 / (physicalScreenHeight * effectiveScale)
  • Frame-aware calculation accounts for parent chain scaling via GetEffectiveScale()
  • Event-driven system: UI_SCALE_CHANGED triggers screen dimension cache update + ScheduleUpdateAll()
  • Smart defaults auto-detect display resolution for optimal UI scale (prevents blur)
  • All StatusBar textures snapped for crisp rendering without sub-pixel artifacts

Time Estimate: 4-5 hours (completed)
Difficulty: Hard
Risk: 🟢 LOW (all edge cases handled, in-game validation complete)

Value: 🟢🟢 HIGH (professional frame rendering at all UI scales)


Phase 3 Summary:

  • Total Time: 4-5 hours
  • Total Risk: LOW (comprehensive validation completed)
  • Outcome: Professional appearance at all UI scales (75%, 100%, 125%)
  • Visual Impact: HIGH (users immediately notice clean borders and crisp textures)
  • Status: ✅ COMPLETE

RELEASE READINESS

All Phases Complete: Phase 1, Phase 2, Phase 3 ✅

Work Completed Summary:

  • Phase 1 (Quick Wins): 3 tasks complete (Safe Helpers, SafeReload, Profile Validation)
  • Phase 2 (UI Improvements): 3 tasks complete (Accent Colors, Search Navigation, Modular Builders)
  • Phase 3 (Visual Polish): 1 task complete (Pixel-Perfect Scaling)
  • LibCustomGlow Integration (2026-03-06): Expanded glow style options for castbar non-interruptible, raid debuffs, and target selection (PIXEL/AUTOCAST/BUTTON/BORDER styles with UI controls in both OptionsV2 and legacy OptionsWindow)

Recommended Next Steps:

  1. Option A: Prepare v1.30.0 release (all core phases complete)
    • Update CHANGELOG.md
    • Tag release: git tag v1.30.0
    • Publish release notes
  2. Option B: Continue with Phase 4 (Infrastructure features)
    • Task 4.1: Profile Migration Helpers (3-4 hrs)
    • Task 4.2: Sidebar Tab UI Overhaul (6-8 hrs)
  3. Option C: Community feedback & top-up features
    • Gather user feedback from Phase 1-3 work
    • Polish based on gameplay testing

PHASE 4: Infrastructure & Advanced Features (20+ hours - DEFER)

Large features that deserve dedicated sessions.

Task 4.1: Backwards Compatibility Profile Migrations (3-4 hours)

Status: 🟡 OPTIONAL
Objective: Users' profiles continue working across addon updates

Why Later:

  • Needed only when schema changes happen
  • Can add retroactively (no rush)

Task 4.2: Sidebar Tab UI Overhaul (6-8 hours)

Status: 🟡 OPTIONAL
Objective: Vertical sidebar tabs like QUI (QUI reference: options/framework.lua, options/options.lua)

Why Later:

  • Largest change (total UI redesign)
  • Requires extensive UX testing
  • Can be done after core features solid

Task 4.3 - 4.5: High-Risk Features (20+ hours - DEFER)

  • Task 4.3: Modular Cooldown System (8-12 hours) - 🔴 LOW PRIORITY
  • Task 4.4: Advanced Aura Filtering (10-15 hours) - 🔴 LOW PRIORITY
  • Task 4.5: Frame Preview Mode (6-8 hours) - 🟡 MEDIUM PRIORITY for Phase 5 polish

Status: All DEFER unless user demand justifies effort


RECOMMENDED WEEKLY SCHEDULE

Week 1: Phase 1 Quick Wins (3-4 hours)

Monday:  Task 1.1 (API Version Compat - 30 min)
Tuesday: Task 1.2 (Safe Helpers - 45 min) + Task 1.3 (SafeReload - 1 hour)
Wednesday: Task 1.4 (Profile Validation - 1 hour)
Thursday: Validation & Testing
Friday: Code Review & Commit

Time Total: 3-4 hours
Risk: 🟢 LOW across all tasks


Week 2-3: Phase 2 UI Improvements (6-9 hours)

Pick Your Path:

Path A: UI Quality Focus (6-7 hours)

Week 2 Mon-Wed: Task 2.1 (Accent Colors - 2-3 hours)
Week 2 Thu-Fri: Task 2.2 (Search Nav - 1-2 hours)
Week 3 Mon-Tue: Task 2.3 (Modular Builders - 3-4 hours)

Path B: Defer Builders (2-3 hours)

Week 2: Task 2.1 + Task 2.2 only
(Save Task 2.3 for Phase 4)

Week 4: Phase 3 Visual Polish (5-6 hours)

Mon-Fri: Task 3.1 (Pixel-Perfect Scaling - 4-5 hours)
+ Testing (extensive screenshots at different UI scales)

Visual Impact: 🟢 HIGH (users immediately notice)


IMPLEMENTATION CHECKLIST (Per Task)

Before Starting:

  • Read relevant QUI reference code (links in RESEARCH.md)
  • Create git feature branch (e.g., feature/api-compat)
  • Estimate time (add 20% buffer)
  • List all affected files

During Implementation:

  • Follow existing code style (no reformatting)
  • Add comments for non-obvious logic
  • Test /reload frequently
  • Verify no new Lua errors in debug console

After Completion:

  • /reload addon and verify no errors
  • Test in safe zone (no combat)
  • Test in dungeons/raids (if applicable)
  • Run /SUFperf (verify no frame time spike)
  • Take screenshots (visual verification)
  • Update WORK_SUMMARY.md
  • Create commit with clear message
  • Merge to main branch

SUCCESS METRICS

Phase 1 (After Completion):

  • ✅ API version caching working
  • ✅ Safe helpers added and used (no breaking changes)
  • ✅ SafeReload prevents combat lock errors
  • ✅ Profile validation prevents import crashes
  • ✅ No performance regression

Phase 2 (After Completion):

  • ✅ Accent color system functional (single picker → all UI colors update)
  • ✅ Search navigation works (click result → correct tab + scroll section)
  • ✅ Modular builders reduce code complexity
  • ✅ No visual regressions to options UI

Phase 3 (After Completion):

  • ✅ Frames render cleanly at 75%, 100%, 125% UI scales
  • ✅ No blurry borders/lines
  • ✅ Window drag/resize preserves pixel-perfect positions
  • ✅ No performance regression (frame time budget consistent)

KNOWN RISKS & MITIGATION

Risk Mitigation
Accent color system breaks existing theme Keep existing Theme.lua functions as fallback
Pixel-perfect math incorrect at edge cases Screenshot-test extensively at all UI scales
Search nav scrolls to wrong section Hard-code section registry entries first
Profile validation too strict Start with lenient checks, tighten gradually

GIT WORKFLOW

# Start feature
git checkout -b feature/NAME-FROM-TASK
git commit -m "Task X.Y: Description"

# After testing
git commit -m "Task X.Y: Fix issues from testing"

# Before merge
git diff main -- [affected files]  # Review changes

# Merge to main
git checkout main
git merge feature/NAME-FROM-TASK --no-ff

# Tag release if completing phase
git tag -a v1.24.0 -m "Phase 1 Quick Wins Complete"

REFERENCE LINKS

RESEARCH.md: Full analysis with effort/value/risk assessments
QUI Code: See RESEARCH.md Section F for file paths
SUF Code: SimpleUnitFrames.lua (main), Modules/UI/ (options), Units/ (frames)


NOTES

  • Phase 1 is Self-Contained: All 4 tasks independent, can do in any order
  • Phase 2 Builds on Phase 1: But not required (can skip Phase 1)
  • Phase 3 Depends on Phase 2: Especially Task 2.3 (modular builders help with sizing)
  • Phase 4 Deferred: Only tackle if users specifically request features or addon has time

Ready to start? Begin with Task 1.1: API Version Compatibility (30 min) ← Recommended first task