Skip to content
forked from shagu/pfUI

A User Interface Replacement for World of Warcraft: Vanilla & TBC

License

Notifications You must be signed in to change notification settings

me0wg4ming/pfUI

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

3,419 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

pfUI - Turtle WoW Edition

Version Turtle WoW SuperWoW Nampower UnitXP

A pfUI fork specifically optimized for Turtle WoW which requires SuperWoW and Nampower with optional UnitXP_SP3 DLL integration.

This version includes significant performance improvements, DLL-enhanced features, and TBC spell indicators that work with Turtle WoW's expanded spell library.

Looking for TBC support? Visit the original pfUI by Shagu: https://github.com/shagu/pfUI


๐ŸŽฏ What's New in Version 7.6.2 (February 6, 2026)

๐Ÿš€ Pure GetUnitField Debuff System (libdebuff.lua)

Major performance rewrite: UnitDebuff() now runs entirely through Nampower's GetUnitField โ€” zero Blizzard API calls, zero tooltip scans.

Previously, every debuff icon required three expensive calls per update:

  1. UnitDebuff(unit, slot) โ€” Blizzard C-side API call
  2. scanner:SetUnitDebuff(unit, slot) โ€” Tooltip object creation + GameTooltip parse
  3. scanner:Line(1) โ€” String extraction from tooltip

All three are now replaced by pure Lua table lookups into cached GetUnitField data:

Data Old (Blizzard API) New (GetUnitField)
Spell Name Tooltip scan SpellInfo(spellId)
Texture UnitDebuff() ret.1 GetSpellIconTexture(GetSpellRecField(spellId, "spellIconID"))
Stacks UnitDebuff() ret.2 GetUnitField(guid, "auraApplications")[slot]
DebuffType UnitDebuff() ret.3 GetSpellRecField(spellId, "dispel") โ†’ dispelTypeMap
Duration/Timeleft ownDebuffs tracking unchanged
Caster slotOwnership tracking unchanged

Performance impact: With 5 debuffs on target = 15 expensive calls eliminated per update cycle. With 10 visible nameplates ร— 3 debuffs = 90 calls eliminated per refresh. Estimated 3-5x faster per UnitDebuff call.

DebuffType now works in Nampower path: Previously dtype was only available from Blizzard's UnitDebuff(). Now resolved from SpellRec DBC via GetSpellRecField(spellId, "dispel"), meaning debuff frame border colors (Magic=blue, Curse=purple, Poison=green, Disease=brown) now work correctly for all units including nameplates.

๐ŸŽจ Item-Cast Icon & Name Support (libdebuff.lua + castbar.lua)

Castbar now shows the correct item icon and item name for item-triggered casts!

Previously, using items with cast times (Gnomish Death Ray, Net-o-Matic, Noggenfogger Elixir etc.) showed the generic spell icon and spell name on the castbar. Now:

  • โœ… SPELL_START_SELF/OTHER arg1 (itemId) is now parsed and used
  • โœ… SPELL_GO_SELF/OTHER arg1 (itemId) is now parsed
  • โœ… Item icon resolved via GetItemStatsField(itemId, "displayInfoID") โ†’ GetItemIconTexture()
  • โœ… Item name resolved via GetItemStatsField(itemId, "displayName")
  • โœ… pfUI.libdebuff_item_icons โ€” Persistent item icon/name cache that survives SPELL_GO clearing cast data
  • โœ… castbar.lua โ€” Reads item icon + name from persistent cache with fallback to spell data

Note: Item icon/name detection only works for your own casts (WoW 1.12.1 protocol limitation โ€” server sends itemId=0 to other clients).

๐Ÿ”ง Icon Path Fix (libdebuff.lua)

Fixed missing icons from Nampower texture functions.

GetSpellIconTexture() and GetItemIconTexture() return short texture names (e.g. INV_Gizmo_08) without the Interface\Icons\ prefix required by SetTexture(). Both GetSpellIcon() and the item icon lookup now auto-prefix the full path when needed.

โšก Memory & GC Optimizations (libdebuff.lua)

  • โœ… Carnage frame recycling โ€” Persistent carnageCheckFrame reused instead of CreateFrame() per Ferocious Bite (eliminates frame leak in combat)
  • โœ… Recycled cleanup buffers โ€” _cleanupBuf1/_cleanupBuf2 reused instead of table.insert + new table per CleanupExpiredTimers call
  • โœ… SelfOverwrite buffer recycling โ€” Reused buffer instead of new oldCasters table per overwrite
  • โœ… Pre-defined sort function โ€” _ownDebuffSortFunc defined once instead of anonymous closure per UnitOwnDebuff call
  • โœ… spellId stored in ownDebuffs โ€” Enables direct DBC lookups for dtype without slotMap iteration

๐Ÿ“Š Code Statistics

libdebuff.lua:

  • Blizzard API calls in Nampower path: 3 per debuff โ†’ 0
  • New GetUnitField calls: aura + auraApplications (cached 50ms)
  • New DBC lookups: GetSpellRecField(spellId, "dispel") for dtype
  • New exports: pfUI.libdebuff_item_icons

castbar.lua:

  • Item icon override via pfUI.libdebuff_item_icons (persistent cache)
  • Item name override via GetItemStatsField(itemId, "displayName")
  • Works for player + target + focus castbars

๐ŸŽฏ What's New in Version 7.6.1 (February 6, 2026)

  • Added a new menu in /pfui named "Throttling" - Players who were unsatisfied with the throttling update rate can change it now for nameplates, Toolip Cursor and Chat Tab.

๐ŸŽฏ What's New in Version 7.6.0 (February 3, 2026)

๐Ÿš€ Centralized Cast-Bar Tracking System (libdebuff.lua + nameplates.lua)

Major architectural change: Cast tracking moved from nameplates to libdebuff for single source of truth!

Previously, both nameplates.lua and libdebuff.lua independently tracked cast events, creating code duplication and maintenance overhead. Now all cast tracking is centralized in libdebuff.lua with nameplates consuming shared data.

libdebuff.lua - NEW Cast Tracking:

  • โœ… SPELL_START_SELF/OTHER โ†’ Cast-Start Tracking
  • โœ… SPELL_GO_SELF/OTHER โ†’ Cast-Completion Tracking
  • โœ… SPELL_FAILED_OTHER โ†’ Cast-Cancel Detection (movement, interrupts, OOM)
  • โœ… pfUI.libdebuff_casts โ†’ Shared cast data structure [casterGuid] = {spellID, spellName, icon, startTime, duration, endTime, event}
  • โœ… pfUI.libdebuff_GetSpellIcon() โ†’ Icon cache export function

nameplates.lua - Simplified Cast Consumption:

  • โœ… GetCastInfo(guid) โ†’ Reads pfUI.libdebuff_casts
  • โœ… pfUI.libdebuff_GetSpellIcon โ†’ Uses shared icon cache
  • โŒ UNIT_CASTEVENT โ†’ REMOVED (replaced by Nampower SPELL_* events)
  • โŒ Local cast tracking code โ†’ REMOVED (~56 lines saved)

Benefits:

  • 100% Nampower, 0% SuperWOW - No longer depends on UNIT_CASTEVENT
  • Single Source of Truth - Cast data only tracked once
  • Icon Cache 100-400x faster - First lookup via Nampower's GetSpellIconTexture, then cached
  • Easier Maintenance - Changes only in one place
  • Code Reduction - 56 lines removed from nameplates.lua

โš ๏ธ Nampower Version Requirement Update (libdebuff.lua)

Now requires Nampower 2.27.2+ (SPELL_FAILED_OTHER bug fix):

Version 2.27.1 had a bug where SPELL_FAILED_OTHER didn't fire for movement-cancelled casts. This is now fixed in 2.27.2.

User Warnings:

  • 2.27.2+: โœ… Success message + auto-enable CVars
  • 2.27.1: โš ๏ธ Yellow warning + popup (cast-bar cancel broken)
  • < 2.27.1: โŒ Red error + popup (debuff tracking disabled)
  • No Nampower: โŒ Red error + popup (addon disabled)

NEW StaticPopup Dialogs:

Popups appear center-screen on login to ensure users don't miss the version requirement!

๐ŸŒฟ libpredict HoT Tracking Integration (libpredict.lua)

Major enhancement: libdebuff integration for server-accurate HoT tracking!

Previously, libpredict relied purely on prediction (UNIT_CASTEVENT + timing calculations). Now it uses libdebuff's AURA_CAST events for server-side accurate buff/debuff data when available.

NEW Hybrid System:

GetHotDuration(unit, spell):
  1. Try libdebuff first (Nampower AURA_CAST events)
     โ†“
     if available: return server-accurate data
  
  2. Fallback to prediction (legacy system)
     โ†“
     Use hots[] table with UNIT_CASTEVENT prediction

Benefits:

  • โœ… Server-accurate durations - No prediction needed with Nampower
  • โœ… Automatic rank protection - Built into libdebuff's system
  • โœ… Multi-caster support - Multiple druids = multiple rejuvs tracked separately
  • โœ… Zero overhead - libdebuff already tracks all auras
  • โœ… Backwards compatible - Falls back to prediction without Nampower

NEW Rank Support for HoTs:

Extended Hot() function signature to include rank parameter:

function libpredict:Hot(sender, target, spell, duration, startTime, source, rank)

Rank Protection Logic:

  • Don't overwrite Rank 10 HoT with Rank 8!
  • Active higher-rank HoTs block lower-rank applications
  • Works with multiple casters simultaneously

HealComm Protocol Extended (Backwards Compatible):

  • OLD: "Reju/TargetName/15/"
  • NEW: "Reju/TargetName/15/10/" (rank added)
  • "0" = unknown rank (for non-rank-aware clients)

Example Scenario:

Druid A casts Rejuvenation Rank 10 (15s duration)
Druid B casts Rejuvenation Rank 8  (12s duration)

With rank protection:
โ†’ Rank 8 is BLOCKED while Rank 10 is active!
โ†’ No more accidental overwrites of better HoTs!

๐Ÿ“Š Code Statistics

libdebuff.lua:

  • Lines: 2743 โ†’ 2835 (+92 lines)
  • Events: 12 โ†’ 15 (+3: SPELL_START_SELF/OTHER, SPELL_FAILED_OTHER)
  • Exports: 14 โ†’ 16 (+2: pfUI.libdebuff_casts, pfUI.libdebuff_GetSpellIcon)

nameplates.lua:

  • Lines: 1826 โ†’ 1770 (-56 lines)
  • Events: 7 โ†’ 6 (-1: UNIT_CASTEVENT removed)
  • Code removed: ~74 lines (UNIT_CASTEVENT handler, local cast tracking)

libpredict.lua:

  • Lines: 935 โ†’ 1095 (+160 lines)
  • New: libdebuff integration, rank support, rank protection logic
  • Backwards compatible: Works with/without Nampower

๐ŸŽฏ What's New in Version 7.5.1 (February 02, 2026)

  • Added icon cache system - Icons are now cached in pfUI.libdebuff_icon_cache for instant lookups after first access

  • Replaced SpellInfo texture lookups with GetSpellIconTexture - Direct DBC queries via Nampower (~100-400x faster than tooltip parsing)

  • Optimized UnitDebuff() function - Now uses GetUnitField("aura") to retrieve spell IDs directly from unit data, then fetches icons via GetSpellIconTexture instead of vanilla UnitDebuff API

  • Changed fallback icons - Unknown spell icons now display QuestionMark instead of class-specific icons

  • Performance impact - Icon lookups reduced from ~5-20ms to ~0.05ms (first) / ~0.001ms (cached) per debuff, resulting in 600-2600x speedup for full debuff bars

  • Replaced in libdebuff.lua the UNIT_CASTEVENT of Superwow with Nampowers SPELL_GO and SPELL_START events (slowly trying to get away from superwow, not maintained anymore and outdated)


๐ŸŽฏ What's New in Version 7.5.0 (January 31, 2026)

๐Ÿ”ง Player Buff Bar Timer Fix (buffwatch.lua)

Fixed buff timers resetting on Player Buff/Debuff Bars when other buffs expire:

Previously, buff bar timers would reset or jump when other buffs expired because the UUID (unique identifier) included the slot number. Since slots shift when buffs expire, the same buff would get a new UUID, causing the timer bar to think it's a new buff.

The Problem:

  • Old UUID: texture + name + slot (e.g., "PowerWordFortitude_tex_PWF_3")
  • Buff in slot 3 expires โ†’ slots 4,5,6 shift down to 3,4,5
  • UUID changes from ..._4 to ..._3 โ†’ timer resets!

The Solution:

  • Player buffs now use: texture + name only (no slot)
  • Target debuffs still use: texture + name + slot (needed for multi-caster scenarios)
-- For player: no slot in uuid (slots shift when other buffs expire)
-- For target: include slot (multiple players can have same debuff)
local uuid
if frame.unit == "player" then
  uuid = data[4] .. data[3] -- texture + name only
else
  uuid = data[4] .. data[3] .. data[2] -- texture + name + slot
end

๐Ÿ›ก๏ธ Immunity Check for Debuff Timers (libdebuff.lua)

No more phantom timers for immune targets:

When a target is immune to your debuff (e.g., Rake bleed on a bleed-immune mob), the AURA_CAST event fires but DEBUFF_ADDED never comes. Previously this could create a timer with icon for a debuff that was never actually applied.

The Fix:

  • Debuff data now requires slot to be set (confirmed by DEBUFF_ADDED_OTHER event)
  • If AURA_CAST fires but DEBUFF_ADDED never comes โ†’ slot stays nil โ†’ no timer/icon shown
-- IMMUNITY CHECK: Only show if slot is set (confirmed by DEBUFF_ADDED_OTHER)
-- This prevents showing timers for spells like Rake where the bleed is immune
if data.slot and timeleft > -1 then
  -- Show the debuff
end

๐ŸŽฏ UnitDebuff() Now Returns Caster Information (libdebuff.lua)

Enhanced UnitDebuff() API - 8th return value is now caster:

local name, rank, texture, stacks, dtype, duration, timeleft, caster = libdebuff:UnitDebuff(unit, id)
-- caster = "player" (your debuff), "other" (someone else's), or nil (unknown)

Use Cases:

  • Buff bar tooltip can now find correct slot for "only own debuffs" mode
  • UI can differentiate between your debuffs and others' debuffs
  • Enables future features like "show only my debuffs" filters

๐Ÿ”„ Buff Bar Tooltip Fix for "Only Own Debuffs" Mode (buffwatch.lua)

Fixed tooltip showing wrong debuff in "only own debuffs" mode:

When using the "Show only own debuffs" option on Target Debuff Bars, hovering over a debuff could show the wrong tooltip because the displayed slot didn't match the actual game slot. Now searches through all game slots to find the correct one by matching spell name AND caster.

๐Ÿ”ง Lua 5.0 Local Variable Limit Workaround (libdebuff.lua)

Fixed addon failing to load due to Lua 5.0's 32 local variable limit:

Lua 5.0 (used by WoW 1.12) has a hard limit of 32 local variables per function scope. As libdebuff grew, it hit this limit and stopped loading entirely.

The Solution: Moved 11 tables from local scope to pfUI. namespace:

Old (local) New (pfUI. namespace)
ownDebuffs pfUI.libdebuff_own
ownSlots pfUI.libdebuff_own_slots
allSlots pfUI.libdebuff_all_slots
allAuraCasts pfUI.libdebuff_all_auras
pendingCasts pfUI.libdebuff_pending
objectsByGuid pfUI.libdebuff_objects_guid
debugStats pfUI.libdebuff_debugstats
lastCastRanks pfUI.libdebuff_lastranks
lastFailedSpells pfUI.libdebuff_lastfailed
lastUnitDebuffLog pfUI.libdebuff_lastlog
cache pfUI.libdebuff_cache

๐Ÿ›‘ Crash 132 Fix (Credits: jrc13245)

Fixed client crash (Error 132) when logging out:

WoW crashes with Error 132 when addons make API calls like UnitExists() during shutdown, especially with UnitXP DLL installed.

The Fix: Register PLAYER_LOGOUT event and immediately disable all event handling:

frame:RegisterEvent("PLAYER_LOGOUT")
frame:SetScript("OnEvent", function()
  if event == "PLAYER_LOGOUT" then
    this:UnregisterAllEvents()
    this:SetScript("OnEvent", nil)
    return
  end
  -- ... rest of event handling
end)

Applied to:

  • libdebuff.lua - All event frames
  • nameplates.lua - nameplates + nameplates.combat frames
  • nampower.lua - Spell queue indicator frame
  • superwow.lua - Secondary mana bar frames
  • actionbar.lua - Page switch frame

โšก Performance Micro-Optimizations

Various small performance improvements across the codebase:

Optimization Location Benefit
childs table reuse nameplates.lua Avoids creating new table every scan cycle
Indexed access instead of pairs() nameplates.lua Faster debuff timeout scanning
Quick exit if not in combat nameplates.lua Skips threatcolor calculation when unnecessary
Player GUID caching libdebuff.lua Avoids repeated UnitExists("player") calls
Consistent DoNothing() pattern unitframes.lua, nameplates.lua Lightweight frames when animation disabled

๐Ÿ“‹ Complete libdebuff.lua Feature Summary

For reference, here's everything the enhanced libdebuff system now provides:

Debuff Detection:

  • โœ… Checks for dodges, misses, resists, parries, immunes, reflects, and evades
  • โœ… Immunity check - no timer if debuff wasn't actually applied
  • โœ… Tracks if debuff is from YOU or from OTHERS (including their GUID)

Rank & Duration:

  • โœ… Rank protection - lower rank spells can't refresh higher rank timers
  • โœ… Shared debuff logic (uniqueDebuffs and debuffOverwritePairs)
  • โœ… Faerie Fire โ†” Faerie Fire (Feral), Demo Shout โ†” Demo Roar overwrites (with rank check!)
  • โœ… Combo point finisher duration (Rip, Rupture, Kidney Shot)
  • โœ… Talent-based duration modifiers (Booming Voice, Improved SW:P, etc.)

Tracking:

  • โœ… Multi-target debuff tracking via GUID
  • โœ… Debuff stack tracking for stackable debuffs
  • โœ… Handles dispels and removals via events

API:

  • โœ… UnitDebuff() returns: name, rank, texture, stacks, dtype, duration, timeleft, caster
  • โœ… UnitOwnDebuff() for filtering only your own debuffs
  • โœ… Cleveroids API compatibility via objectsByGuid

Debug Commands:

  • /shifttest start/stop/stats/slots - Debug debuff slot tracking
  • /memcheck - Show memory usage statistics

๐ŸŽฏ What's New in Version 7.4.3 (January 29, 2026)

โšก Massive Performance Optimization - Cooldown Frame Overhaul

Revolutionary frame creation system that eliminates unnecessary Model frames:

Previously, pfUI created expensive Model frames for every single buff/debuff cooldown timer, even when the animation was disabled. This caused significant performance overhead, especially in 40-man raids where hundreds of frames were created but never actually used.

The Problem:

  • Old system: ALWAYS created Model frames with CooldownFrameTemplate
  • When animation was disabled, frames were just hidden with SetAlpha(0)
  • The frames still existed and consumed CPU resources in the background
  • In raids: 40 players ร— 32 buffs/debuffs = 1,280 Model frames running even when animations were off!

The Solution (Nameplates.lua + Unitframes.lua):

  • New system: Creates Frame type based on config setting
  • Animation ON โ†’ Model frame with CooldownFrameTemplate (expensive but animated)
  • Animation OFF โ†’ Regular Frame with dummy functions (lightweight, no animation)
  • Dummy functions (DoNothing()) prevent crashes when CooldownFrame_SetTimer() is called

Performance Impact:

Scenario Before 7.4.3 After 7.4.3 Improvement
Player frame (animation ON) 32 Model frames 32 Model frames No change โœ…
40 raid frames (animation OFF) 1,280 Model frames 1,280 Light frames 100% lighter! ๐Ÿš€
Mixed (player ON, raid OFF) 1,312 Model frames 32 Model + 1,280 Light 98% less Model frames! ๐ŸŽฏ

Real-World Example:

Before: ALL frames = 1,312 expensive Model frames
After:  32 Model (player) + 1,280 Light (raid) = 98% reduction in overhead

Technical Implementation:

-- Nameplates.lua & Unitframes.lua
if cooldown_anim == 1 then
  -- Create expensive Model frame
  cd = CreateFrame("Model", ...)
else
  -- Create lightweight Frame
  cd = CreateFrame("Frame", ...)
  cd.AdvanceTime = DoNothing
  cd.SetSequence = DoNothing
  cd.SetSequenceTime = DoNothing
end

User Experience:

  • โœ… GUI Integration: Toggling "Show Timer Animation" now prompts for /reload
  • โœ… Per-Frame Control: Each unitframe type (player/target/raid/party) has independent settings
  • โœ… Immediate Effect: Reload applies the correct frame type based on your config
  • โœ… No Visual Change: When animation is ON, everything looks identical (just way more efficient!)

Why This Matters:

  • 40-man raids: Dramatically reduced frame update overhead
  • Low-end PCs: Smoother gameplay with animations disabled
  • Battery life: Less CPU usage = longer laptop battery
  • Future-proof: Foundation for more performance optimizations

Compatibility:

  • Works with existing timer text display (independent of animation)
  • Fully backward compatible with all existing configs
  • No changes needed to user settings (automatic on reload)

๐ŸŽฏ What's New in Version 7.4.2 (January 28, 2026)

Major Performance Improvements

  • Much faster debuff tracking - No more lag in 40-man raids
  • 10x less memory usage - Runs cleaner over long raid sessions
  • Instant cleanup - Dead mobs cleaned up immediately (was: 2-5 minutes)

Better Debuff Tracking

  • Multi-player debuffs - See debuffs from all raid members with accurate timers
  • Rank protection - Lower rank spells can't overwrite higher ranks anymore
  • 100% accurate positioning - Debuff icons always in the correct slot
  • Better combo points - Rip, Rupture, Kidney Shot show correct duration

๐ŸŽฏ What's New in Version 7.4.1 (January 27, 2026)

๐ŸŽฏ Nameplate Debuff Timer Improvements

  • โœ… New Option: Enable Debuff Timers - Toggle for debuff timer display on nameplates
    • Moved from hidden location (Appearance โ†’ Cooldown โ†’ "Display Debuff Durations") to Nameplates โ†’ Debuffs
    • All timer-related options are now grouped together for better discoverability
  • โœ… New Option: Show Timer Text - Toggle the countdown text (e.g., "12s") on debuff icons
    • Previously always shown, now configurable
  • โœ… Show Timer Animation - Existing pie-chart animation option, now properly grouped with other timer options

๐Ÿ–ผ๏ธ Unitframe Timer Config Fix (unitframes.lua)

  • โœ… Live Config Updates - "Show Timer Animation" and "Show Timer Text" now update immediately
    • Previously: Changes only applied after buffs/debuffs were refreshed
    • Now: Toggling the option instantly shows/hides the animation and text on existing buffs/debuffs

๐Ÿ”ง Slot Shifting Fix Attempt (libdebuff.lua)

  • โœ… DEBUFF_REMOVED now uses slotData.spellName - Previously used spellName from scan, which could be wrong after slot shifting
    • When debuffs shift slots (e.g., slot 3 removed, slots 4+ shift down), the scan might read a different spell
    • Now uses removedSpellName = slotData.spellName from stored slot data for consistency
  • โœ… Cleanup empty spell tables - After removing a caster from allAuraCasts, checks if no other casters remain and removes the empty spell table
  • โœ… Defensive casterGuid validation - Checks for empty string and "0x0000000000000000" before looking up timer data
  • โœ… Invalid timer detection - Warns when remaining > duration (impossible state)
  • โœ… ValidateSlotConsistency function - Debug function to verify allSlots and allAuraCasts consistency after shifting
  • โœ… Enhanced debug logging - All debug messages now include target= for easier filtering

๐ŸŽฏ What's New in Version 7.4.0 (January 26, 2026)

๐Ÿ—ก๏ธ Rogue Combo Point Fix

PLAYER_COMBO_POINTS event now works for Rogues:

The combo point tracking was previously only enabled for Druids. Rogues were completely ignored, causing abilities like Kidney Shot to always show base duration (1 sec) instead of the correct CP-scaled duration.

Technical Details:

  • Nampower sends durationMs=1000 (base duration) for Kidney Shot
  • Code checked if duration == 0 before calling GetDuration()
  • Since duration was 1 (not 0), the CP calculation was skipped
  • Fix: Always call GetDuration() for CP-based abilities, regardless of event duration

โš™๏ธ New Settings: Number & Timer Formatting

Abbreviate Numbers (Settings โ†’ General):

Option Example
Full Numbers 4250
2 Decimals 4.25k
1 Decimal 4.2k (always rounds DOWN)

Castbar Timer Decimals (Settings โ†’ General):

Option Example
1 Decimal 2.1
2 Decimals 2.14

๐ŸŽฌ Nameplate Castbar Improvements

Smooth Castbar Animation:

  • Fixed stuttering castbar caused by incorrect throttle placement
  • Scanner throttle (0.05s) now only affects nameplate detection
  • Castbar updates run at full 50 FPS for smooth animation

Countdown Timer:

  • Castbar timer now counts DOWN (3.0 โ†’ 0.0) instead of up
  • Shows remaining cast time, not elapsed time

Intelligent Throttling (unchanged):

  • Target OR casting nameplates: 0.02s (50 FPS)
  • All other nameplates: 0.1s (10 FPS)
  • Event updates bypass throttle entirely

๐Ÿงน Memory Management

Cache cleanup for hidden nameplates:

  • guidRegistry cleared when plate hides
  • CastEvents cleared when plate hides
  • debuffCache cleared when plate hides
  • threatMemory cleared when plate hides

Prevents memory leaks when mobs die or go out of range.


๐ŸŽฏ What's New in Version 7.3.0 (January 25, 2026)

โšก O(1) Performance Optimizations for Unitframes

Complete rewrite of health/mana lookups using Nampower's GetUnitField API:

The unitframes now use direct memory access via GetUnitField(guid, "health") instead of the slower UnitHealth() API calls. This provides significant performance improvements especially in raids.

Key Changes:

Component Before (7.2.0) After (7.3.0)
HealPredict Health UnitHealth() API calls GetUnitField(guid, "health") O(1)
Health Bar Colors 4x redundant API calls per update Uses cached hp_orig/hpmax_orig values
GetColor Function UnitHealth() API calls GetUnitField(guid, "health") O(1)

Fallback Support:

  • Automatic fallback to UnitHealth() when Nampower not available
  • Automatic fallback for units >180 yards (out of Nampower range)
  • Automatic fallback when GUID unavailable

๐Ÿš€ Smart Roster Updates (No More Freeze!)

GUID-based tracking eliminates screen freezes when swapping raid groups:

Previously, any raid roster change would trigger a full update of ALL 40 raid frames, causing noticeable freezes. Now, only frames where the actual player changed get updated.

How it works:

-- OLD: RAID_ROSTER_UPDATE โ†’ ALL 40 frames update_full = true โ†’ FREEZE
-- NEW: RAID_ROSTER_UPDATE โ†’ Check GUID per frame โ†’ Only changed frames update
Scenario Before (7.2.0) After (7.3.0)
Swap 2 players 40 frame updates 2 frame updates
Player joins 40 frame updates 1 frame update
Player leaves 40 frame updates 1 frame update
No changes 40 frame updates 0 frame updates

Technical Implementation:

  • pfUI.uf.guidTracker tracks GUID per frame
  • On roster change, compares old GUID vs new GUID
  • Only sets update_full = true if GUID actually changed
  • Also forces update_aura = true to refresh buffs/debuffs

๐Ÿ”ง libpredict.lua Optimizations

Eliminated redundant UnitName() calls:

  • UnitGetIncomingHeals(): Removed double UnitName() call
  • UnitHasIncomingResurrection(): Removed double UnitName() call
  • UNIT_HEALTH event handler: Reuses cached name variable

๐ŸŽฏ What's New in Version 7.2.0 (January 24, 2026)

๐Ÿฑ Druid Secondary Mana Bar Overhaul

Complete rewrite using Nampower's GetUnitField API:

The Druid Mana Bar feature (showing base mana while in shapeshift form) has been completely rewritten to use Nampower's native GetUnitField instead of the deprecated UnitMana() extended return values.

Key Changes:

Component Before (7.1.0) After (7.2.0)
Data Source UnitMana() second return value GetUnitField(guid, "power1")
Player Support โœ… Druids only โœ… Druids only
Target Support โŒ Limited/broken โœ… All classes can see Druid mana in all forms
Text Settings Hardcoded format Respects Power Bar text config

grafik

New Features:

  • โœ… Target Secondary Mana: See enemy/friendly Druid's base mana while they're in Cat/Bear form
  • โœ… Respects Power Text Settings: Uses same format as your Power Bar configuration (powerdyn, power, powerperc, none, etc.)
  • โœ… Available for ALL Classes: Any class can now see Druid mana bars (controlled by "Show Druid Mana Bar" setting)

Technical Implementation:

-- OLD: Extended UnitMana (unreliable for other units)
local _, baseMana = UnitMana("target")  -- Often returns nil for non-player

-- NEW: Direct field access via Nampower
local _, guid = UnitExists("target")
local baseMana = GetUnitField(guid, "power1")      -- Base mana
local baseMaxMana = GetUnitField(guid, "maxPower1") -- Max base mana

๐Ÿงน Major Code Cleanup

superwow.lua:

  • โŒ Removed legacy pfDruidMana bar (old SuperWoW-style implementation)
  • โŒ Removed UnitMana() fallback code
  • โœ… Unified all secondary mana bars to use GetUnitField
  • โœ… Fixed text centering issue (was using SetJustifyH("RIGHT"))

nampower.lua - Massive Cleanup:

Removed significant amounts of dead/unused code:

Removed Feature Reason
Buff tracking system Data collected but never displayed
HoT Detection (AURA_CAST events) OnHotApplied callback never implemented
Swing Timer (GetSwingTimers()) Never called anywhere in codebase
UNIT_DIED buff/debuff cleanup Now handled by libdebuff

Result: Cleaner, more maintainable code with reduced memory footprint.


๐ŸŽฏ What's New in Version 7.1.0 (January 24, 2026)

โšก Cooldown Timer Animation Support

Nameplate Debuff Animations:

  • โœ… Added "Show Timer Animation" option for nameplate debuffs
  • โœ… Uses proper Model frame with CooldownFrameTemplate for Vanilla client
  • โœ… Pie/swipe animation now works on nameplate debuff icons
  • โœ… Configurable via GUI: Nameplates โ†’ Show Timer Animation

Target Frame Debuff Animations:

  • โœ… Timer animations now properly visible on target/player frame debuffs
  • โœ… Fixed CD frame scaling and positioning for correct display
  • โœ… SetScale(size/32), SetAllPoints(), SetFrameLevel(14) for proper rendering

cooldown.lua Fix:

  • โœ… Added elseif pfCooldownStyleAnimation == 1 then SetAlpha(1) to make animations visible
  • โœ… Previously animations were created but never shown (alpha stayed 0)

๐Ÿงน Memory Leak Fixes

libdebuff.lua:

  • โœ… lastCastRanks table now cleaned up (entries older than 3 seconds removed)
  • โœ… lastFailedSpells table now cleaned up (entries older than 2 seconds removed)
  • โœ… Previously these tables grew indefinitely over long play sessions

unitframes.lua:

  • โœ… Cache cleanup now uses in-place = nil instead of creating new table every 30 seconds
  • โœ… Reduces garbage collector pressure

nameplates.lua:

  • โœ… Reusable debuffSeen table instead of creating local seen = {} on every DEBUFF_UPDATE event
  • โœ… Significant reduction in table allocations during combat

๐ŸŽฏ What's New in Version 7.0.0 (January 21, 2026)

๐Ÿ”ฅ Complete libdebuff.lua Rewrite (464 โ†’ 1594 lines)

Event-Driven Architecture:

Replaced tooltip scanning with a pure event-based system using Nampower/SuperWoW:

OLD (Master):

-- Every UI update:
for slot = 1, 16 do
  scanner:SetUnitDebuff("target", slot)  -- Tooltip scan
  local name = scanner:Line(1)
end

NEW (Experiment):

-- Events fire when changes happen:
RegisterEvent("AURA_CAST_ON_SELF")     -- You cast a debuff
RegisterEvent("DEBUFF_ADDED_OTHER")    -- Debuff lands in slot
RegisterEvent("DEBUFF_REMOVED_OTHER")  -- Debuff removed

-- UI reads from pre-computed tables:
local data = ownDebuffs[guid][spell]  -- Direct lookup

๐Ÿฑ Combo Point Finisher Support

Dynamic Duration Calculation:

Ability Formula Durations (1-5 CP)
Rip 8s + CP ร— 2s 10s / 12s / 14s / 16s / 18s
Rupture 10s + CP ร— 2s 12s / 14s / 16s / 18s / 20s
Kidney Shot 2s + CP ร— 1s 3s / 4s / 5s / 6s / 7s

Before: All Rips showed 18s (wrong for 1-4 CP) After: Shows actual duration based on combo points used


๐ŸŽญ Carnage Talent Detection

Ferocious Bite Refresh Mechanics:

  • Tracks Carnage talent (Rank 2) which makes Ferocious Bite refresh Rip & Rake
  • Only refreshes when Ferocious Bite HITS (not on miss/dodge/parry)
  • Preserves original duration (doesn't reset to new CP count)
  • Uses DidSpellFail() API for miss detection

๐Ÿ”„ Additional Features

  • Debuff Overwrite Pairs: Faerie Fire โ†” Faerie Fire (Feral), Demoralizing Shout โ†” Demoralizing Roar
  • Slot Shifting Algorithm: Accurate icon placement when debuffs expire
  • Multi-Caster Tracking: Multiple players' debuffs tracked separately
  • Rank Protection: Lower rank can't overwrite higher rank timer
  • Unique Debuff System: Hunter's Mark, Scorpid Sting, etc. handled correctly

๐Ÿ“Š Performance Comparison

The Core Difference: Data Access Architecture

Master uses Blizzard API + Tooltip Scanning:

-- Every UnitDebuff call requires tooltip scan
function libdebuff:UnitDebuff(unit, id)
  local texture, stacks, dtype = UnitDebuff(unit, id)
  if texture then
    scanner:SetUnitDebuff(unit, id)  -- Tooltip scan to get spell name
    effect = scanner:Line(1)
  end
  -- Duration comes from hardcoded lookup tables
end

-- UnitOwnDebuff iterates all 16 slots
function libdebuff:UnitOwnDebuff(unit, id)
  for i = 1, 16 do
    local effect = libdebuff:UnitDebuff(unit, i)  -- 16 tooltip scans!
    if caster == "player" then ...
  end
end

Experiment uses Nampower Events + GetUnitField:

-- Single call returns ALL 48 aura slots (32 buffs + 16 debuffs)
local auras = GetUnitField(guid, "aura")  -- Returns array[48] of spell IDs
local stacks = GetUnitField(guid, "auraApplications")  -- Returns array[48] of stack counts

-- Events fire with full data including duration
-- AURA_CAST_ON_OTHER: spellId, casterGuid, targetGuid, effect, effectAuraName, 
--                     effectAmplitude, effectMiscValue, durationMs, auraCapStatus
-- BUFF_REMOVED_OTHER: guid, slot, spellId, stackCount, auraLevel

-- UnitOwnDebuff is just a table lookup
function libdebuff:UnitOwnDebuff(unit, id)
  local _, guid = UnitExists(unit)
  local data = ownDebuffs[guid][spellName]  -- Pre-computed by events
  return data.duration, data.timeleft, ...
end

Nampower Features Used (Experiment Only)

Feature Purpose Data Provided
GetUnitField(guid, "aura") Single call returns all 48 aura spell IDs array[48] of spell IDs
GetUnitField(guid, "auraApplications") Stack counts for all auras array[48] of stack counts
GetUnitField(guid, "power1") Base mana for shapeshifted Druids Mana value (7.2.0)
GetUnitField(guid, "maxPower1") Max base mana Max mana value (7.2.0)
AURA_CAST_ON_OTHER Instant debuff cast detection spellId, casterGuid, targetGuid, durationMs
AURA_CAST_ON_SELF Instant self-buff detection Same as above
BUFF_REMOVED_OTHER Instant aura removal detection guid, slot, spellId, stackCount
DEBUFF_ADDED_OTHER Debuff slot assignment guid, slot, spellId, stacks
DEBUFF_REMOVED_OTHER Debuff removal with slot info guid, slot, spellId

Master uses none of these - it relies on:

  • UnitDebuff() API (no caster info, no duration)
  • Tooltip scanning via GameTooltip:SetUnitDebuff() to get spell names
  • Chat message parsing (CHAT_MSG_SPELL_PERIODIC_*) for duration detection
  • Hardcoded duration lookup tables

Performance Comparison

Operation Master Experiment Improvement
Initial target scan 16 tooltip scans 1 GetUnitField call (48 slots) 16x fewer calls
Get YOUR debuffs Loop 16 slots + tooltip each Direct table lookup ~50-100x faster
Debuff duration Hardcoded tables / chat parsing Event provides durationMs Accurate to ms
Detect debuff removal Polling / timeout BUFF_REMOVED_OTHER event Instant
Detect new debuff Chat message delay AURA_CAST_ON_OTHER event Instant
Caster identification Not available Event provides casterGuid New capability
Druid mana (other units) Not available GetUnitField(guid, "power1") New in 7.2.0
Memory usage ~50KB ~200KB 4x more (negligible)

Memory Management (7.1.0+ Fixes)

Table Before 7.1.0 After 7.1.0
lastCastRanks Grew indefinitely Cleaned every 30s (>3s old)
lastFailedSpells Grew indefinitely Cleaned every 30s (>2s old)
debuffSeen (nameplates) New table per DEBUFF_UPDATE Reused single table
cleanedCache (unitframes) New table every 30s In-place cleanup

๐Ÿ“‹ File Changes Summary

Version 7.5.0

File Location Changes
buffwatch.lua modules/ Player buff bar timer fix (UUID without slot), tooltip fix for "only own debuffs" mode
libdebuff.lua libs/ Immunity check, UnitDebuff() 8th return value caster, Lua 5.0 table limit workaround (11 tables to pfUI. namespace), Crash 132 fix, Player GUID caching
unitframes.lua api/ Consistent DoNothing() pattern for lightweight cooldown frames
nameplates.lua modules/ Consistent DoNothing() pattern, childs table reuse, indexed debuff timeout scan, quick exit optimization, Crash 132 fix
nampower.lua modules/ Crash 132 fix
superwow.lua modules/ Crash 132 fix
actionbar.lua modules/ Crash 132 fix

Version 7.4.3 (January 29, 2026)

File Location Changes
libdebuff.lua libs/ Rogue PLAYER_COMBO_POINTS fix, always use GetDuration() for CP-abilities
api.lua api/ Abbreviate() now supports 3 modes (off/2dec/1dec), 1dec always floors
config.lua api/ Added castbardecimals option
gui.lua modules/ Abbreviate Numbers dropdown, Castbar Timer Decimals dropdown
nameplates.lua modules/ Smooth castbar (throttle fix), countdown timer, cache cleanup
castbar.lua modules/ FormatCastbarTime() helper, respects castbardecimals config

Version 7.2.0

File Location Changes
superwow.lua modules/ Removed legacy pfDruidMana, added Target/ToT secondary mana bars, GetUnitField for all mana queries, respect Power Bar text settings
nampower.lua modules/ Major cleanup: removed dead buff tracking, HoT detection, swing timer code

Version 7.1.0

File Location Changes
libdebuff.lua libs/ Memory leak fixes for lastCastRanks, lastFailedSpells
unitframes.lua api/ In-place cache cleanup, CD frame scaling/positioning
nameplates.lua modules/ Reusable debuffSeen table, Model+CooldownFrameTemplate
cooldown.lua modules/ SetAlpha(1) for pfCooldownStyleAnimation == 1
config.lua api/ Added nameplates.debuffanim option
gui.lua modules/ Added "Show Timer Animation" checkbox for nameplates

๐Ÿ“‹ Installation

Requirements

REQUIRED:

  • SuperWoW DLL
  • Nampower DLL

Optional but Recommended:

  • UnitXP_SP3 DLL (for accurate XP tracking)

Steps

  1. Install SuperWoW + Nampower
  2. Download pfUI Experiment build
  3. Extract to Interface/AddOns/pfUI
  4. /reload
  5. Check for errors in console

Verification

Type /run print(GetNampowerVersion()) - should show version number.

If nil, Nampower is not installed correctly!


๐Ÿ› Known Issues

Untested Scenarios

  • โŒ 40-man raids with 5+ druids (slot shifting stress test)
  • โŒ Rapid target swapping with Ferocious Bite spam
  • โš ๏ธ Multi-caster tracking in AQ40/Naxx

Edge Cases

  1. DEBUFF_ADDED race condition: Sometimes fires before AURA_CAST_ON_SELF processes
  2. Slot shifting bugs: Complex logic for removing/adding debuffs
  3. Combo point detection: Relies on PLAYER_COMBO_POINTS event timing

๐Ÿ“œ Changelog

7.5.0 (January 31, 2026)

Added:

  • โœ… UnitDebuff() 8th return value: caster ("player"/"other"/nil)
  • โœ… Immunity check - no timer/icon shown if debuff wasn't actually applied
  • โœ… Buff bar tooltip correctly identifies debuff slot in "only own debuffs" mode
  • โœ… /shifttest and /memcheck debug commands for libdebuff troubleshooting

Fixed:

  • ๐Ÿ”ง Player Buff Bar timer reset bug (UUID no longer includes slot for player buffs)
  • ๐Ÿ”ง Lua 5.0 local variable limit (moved 11 tables to pfUI. namespace)
  • ๐Ÿ”ง Crash 132 on logout (Credits: jrc13245) - affects libdebuff, nameplates, nampower, superwow, actionbar
  • ๐Ÿ”ง Consistent DoNothing() pattern across all cooldown frame creation

Performance:

  • โšก childs table reuse in nameplate scanner (avoids GC churn)
  • โšก Indexed access instead of pairs() for debuff timeout scanning
  • โšก Quick exit if not in combat for threatcolor calculation
  • โšก Player GUID caching in libdebuff

7.4.3 (January 29, 2026)

Added:

  • โœ… Castbar Timer Decimals setting (1 or 2 decimals)
  • โœ… Abbreviate Numbers dropdown (Full / 2 Decimals / 1 Decimal)
  • โœ… Nameplate castbar countdown (shows remaining time)
  • โœ… Cache cleanup for hidden nameplates (prevents memory leaks)

Fixed:

  • ๐Ÿ”ง Rogue combo point tracking (PLAYER_COMBO_POINTS was Druid-only)
  • ๐Ÿ”ง Kidney Shot/Rupture duration (now always uses GetDuration() for CP-abilities)
  • ๐Ÿ”ง Nameplate castbar stuttering (throttle only affects scanner, not updates)

Changed:

  • ๐Ÿ”ง Abbreviate Numbers: 1 Decimal mode always rounds DOWN (4180 โ†’ 4.1k)
  • ๐Ÿ”ง Nameplate castbar: counts down instead of up

7.2.0 (January 24, 2026)

Added:

  • โœ… Target Secondary Mana Bar (see Druid mana while in shapeshift form)
  • โœ… Target-of-Target Secondary Mana Bar
  • โœ… Secondary Mana Bars now respect Power Bar text settings

Changed:

  • ๐Ÿ”ง Secondary Mana Bars now use GetUnitField(guid, "power1") instead of UnitMana()
  • ๐Ÿ”ง "Show Druid Mana Bar" setting now available for ALL classes (not just Druids)

Removed:

  • โŒ Legacy pfDruidMana bar (replaced by pfPlayerSecondaryMana)
  • โŒ UnitMana() extended return value fallback
  • โŒ Dead code in nampower.lua: buff tracking, HoT detection, swing timer

7.1.0 (January 24, 2026)

Added:

  • โœ… Nameplate debuff timer animation support (pie/swipe effect)
  • โœ… Target frame debuff animation improvements
  • โœ… GUI option: Nameplates โ†’ Show Timer Animation

Fixed:

  • ๐Ÿ”ง Memory leak: lastCastRanks now cleaned up (>3s old entries)
  • ๐Ÿ”ง Memory leak: lastFailedSpells now cleaned up (>2s old entries)
  • ๐Ÿ”ง Memory churn: Reusable debuffSeen table in nameplates
  • ๐Ÿ”ง Memory churn: In-place cache cleanup in unitframes
  • ๐Ÿ”ง cooldown.lua: Animation now visible when pfCooldownStyleAnimation == 1

7.0.0 (January 21, 2026)

Added:

  • โœ… Event-driven debuff tracking (AURA_CAST, DEBUFF_ADDED, etc.)
  • โœ… Combo point finisher support (Rip, Rupture, Kidney Shot)
  • โœ… Carnage talent detection (Ferocious Bite refresh)
  • โœ… Debuff overwrite pairs (Faerie Fire โ†” Faerie Fire Feral)
  • โœ… Slot shifting algorithm (accurate icon placement)
  • โœ… Multi-caster tracking (multiple Moonfires)
  • โœ… Rank protection (Rank 1 can't overwrite Rank 10)
  • โœ… Unique debuff system (Hunter's Mark, Scorpid Sting)
  • โœ… Nampower GetUnitField() initial scan
  • โœ… Combat indicator fix (works on player frame now)

Changed:

  • ๐Ÿ”ง libdebuff.lua completely rewritten (464 โ†’ 1594 lines)
  • ๐Ÿ”ง UnitOwnDebuff() uses table lookup instead of tooltip scan

What's New in Version 6.2.6 (January 27, 2026)

๐ŸŽฏ Nameplate Debuff Timer Improvements

  • โœ… New Option: Enable Debuff Timers - Toggle for debuff timer display on nameplates
    • Moved from hidden location (Appearance โ†’ Cooldown โ†’ "Display Debuff Durations") to Nameplates โ†’ Debuffs
    • All timer-related options are now grouped together for better discoverability
  • โœ… New Option: Show Timer Text - Toggle the countdown text (e.g., "12s") on debuff icons
    • Previously always shown, now configurable
  • โœ… Show Timer Animation - Existing pie-chart animation option, now properly grouped with other timer options

๐Ÿ–ผ๏ธ Unitframe Timer Config Fix (unitframes.lua)

  • โœ… Live Config Updates - "Show Timer Animation" and "Show Timer Text" now update immediately
    • Previously: Changes only applied after buffs/debuffs were refreshed
    • Now: Toggling the option instantly shows/hides the animation and text on existing buffs/debuffs

๐Ÿฑ Combo Point Ability Fixes (libdebuff.lua)

  • โœ… Rogue & Druid Combo Point Tracking - Fixed duration calculation for combo point abilities
    • Rupture, Kidney Shot, and Rip now correctly calculate duration based on combo points spent
    • Added PLAYER_COMBO_POINTS event tracking for both Rogues AND Druids
    • Stores combo points before they're consumed, ensuring accurate duration calculation
    • Fixes issue where abilities showed incorrect duration when combo points were already spent at cast time

What's New in Version 6.2.5 (January 21, 2026)

๐ŸŽฏ Bug report fixes and feature requests.

  • Fixed aggro indicator on "Player" frame not working properly.
  • Fixed aggro and combat glow on player frames.
  • Changed the Aggro indicator timer from 0.1 to 0.2 times per second (5 times per second is enough)
  • Fixed the 40yard range check not working properly for Shamans and Druids in bear/cat form.
  • Added 2 new buttons to the Nameplate menu: "Disable Hostile Nameplates in Friendly Zones" and "Disable Friendly Nameplates in Friendly Zones"
  • changed version to 6.2.5 to push an update for everyone
  • Feel free to check out https://github.com/me0wg4ming/pfUI/tree/enhanced_release - this is an experiment version with proper tracking for debuffs on current target (use on own risk)


What's New in Version 6.2.3 (January 11, 2026)

๐ŸŽฏ Unit and Raidframes fix (unitframes.lua)

  • Fixed lag spikes in raids, raid frames should be now butter smooth and cause no lags
  • Fixed a bug not updating hp/mana and buffs/debuffs properly.
  • Removed a scan system that scanned always all 40 raid frames 10 times per second (worked out a better solution to track those)
  • debuff tracking on enemys (for your own abilitys/spells) should be working properly too now

What's New in Version 6.2.2 (January 10, 2026)

๐ŸŽฏ Failed Spell Detection (libdebuff.lua)

  • โœ… Resist/Miss/Dodge/Parry Detection - Spells that fail to land no longer create or update timers
    • Detects: Miss, Resist, Dodge, Parry, Evade, Deflect, Reflect, Block, Absorb, Immune
    • Timer is either blocked before creation or reverted if fail event arrives late
  • โœ… Public API: libdebuff:DidSpellFail(spell) - Other modules can check if a spell recently failed
    • Returns true if spell failed within the last 1 second
    • Used by turtle-wow.lua for refresh mechanics

๐Ÿฑ Druid/Warlock Refresh Fixes (turtle-wow.lua)

  • โœ… Ferocious Bite Refresh Fix - Rip/Rake timers only refresh when Ferocious Bite actually hits
    • Previously: Timer refreshed even on dodge/parry/miss
    • Now: Uses DidSpellFail() to verify hit before refreshing
  • โœ… Conflagrate Refresh Fix - Immolate duration only reduced when Conflagrate actually hits
  • โœ… Caster Inheritance - Refresh mechanics preserve existing caster info when not explicitly provided

โšก SuperWoW Compatibility (superwow.lua)

  • โœ… Removed UNIT_CASTEVENT for DoT Timers - SuperWoW's instant event fires before resist/miss detection
    • DoT timers now use standard hook-based fallback (compatible with resist detection)
    • HoT timers (Rejuvenation, Renew, etc.) still use SuperWoW for instant detection (buffs can't be resisted)

What's New in Version 6.2.1 (January 10, 2026)

๐ŸŽฏ Debuff Timer Protection System (libdebuff.lua)

  • โœ… Spell Rank Tracking - Tracks spell rank for all your DoTs/debuffs
    • Uses lastCastRanks table to preserve rank information across multiple event sources
    • Fixes race condition where SuperWoW UNIT_CASTEVENT fired before QueueFunction processed pending data
  • โœ… Lower Rank Protection - Lower rank spells cannot overwrite higher rank timers
    • Example: If Moonfire Rank 10 is active, casting Rank 5 will be blocked
  • โœ… Other Player Protection - Other players' casts cannot overwrite your debuff timers
    • Your DoTs are tracked separately from other players' DoTs
    • Multiple players can have their own Moonfire/Corruption on the same target
  • โœ… Shared Debuff Whitelist - Debuffs that are shared by all players update correctly:
    • Warrior: Sunder Armor, Demoralizing Shout, Thunder Clap
    • Rogue: Expose Armor
    • Druid: Faerie Fire, Faerie Fire (Feral)
    • Hunter: Hunter's Mark
    • Warlock: Curse of Weakness/Recklessness/Elements/Shadow/Tongues/Exhaustion
    • Priest: Shadow Weaving
    • Mage: Winter's Chill
    • Paladin: All Judgements

What's New in Version 6.2.0 (January 10, 2026)

๐Ÿ”ฎ HoT Timer System (libpredict.lua)

  • โœ… Regrowth Duration Fix - Corrected duration from 21 to 20 seconds (matching actual Turtle WoW spell duration)
  • โœ… GetTime() Synchronization - All timing calls now use pfUI.uf.now or GetTime() for consistent timing across all UI elements
  • โœ… Instant-HoT Detection Fix - Fixed Rejuvenation/Renew not being detected when cast quickly after Regrowth
    • Problem: spell_queue was overwritten before processing
    • Solution: Instant HoTs now processed immediately at cast hooks with current_cast tracking
  • โœ… SuperWoW UNIT_CASTEVENT Support - Precise Instant-HoT detection using UNIT_CASTEVENT
    • Only fires on successful casts (not attempts), eliminating false triggers from GCD/range failures
    • Graceful fallback to hook-based detection for players without SuperWoW
  • โœ… HealComm Compatibility - Full compatibility with standalone HealComm addon users
    • 0.3s delay compensation for Regrowth messages
    • Duplicate detection (0.5s window) prevents double timers
  • โœ… PARTY Channel Support - HoT messages now sent to PARTY channel for 5-man dungeons

๐ŸŽฏ Nameplate Improvements (nameplates.lua)

  • โœ… Target Castbar Zoom Fix - Fixed current target castbar not showing when zoom factor is enabled
    • Multi-method target detection: alpha check, istarget flag, and zoomed state
    • Proper GUID lookup for target castbar info (was incorrectly using string "target")
  • โœ… Flicker/Vibration Fix - Eliminated nameplate flicker near zoom boundaries
    • Alpha check changed from == 1 to >= 0.99 (floating-point fix)
    • Zoom tolerance changed from >= w to > w + 0.5 (prevents oscillation)
  • โœ… libdebuff Nil-Checks - Added safety checks to prevent errors when libdebuff data is unavailable

โšก Spell Queue (nampower.lua)

  • โœ… Error Handling - Added pcall wrapper for GetSpellNameAndRankForId to prevent error spam when spell ID not found

๐Ÿฑ Druid Improvements

  • โœ… Rip Duration (libdebuff.lua) - Now dynamically calculated based on combo points (10/12/14/16/18 seconds for 1-5 CP)
  • โœ… Ferocious Bite Refresh (turtle-wow.lua) - Now refreshes both Rip AND Rake (previously only Rip), preserving existing duration

โšก Energy Tick (energytick.lua)

  • โœ… Talent/Buff Energy Filter - Ignores energy gains from talents/buffs (e.g., Ancient Brutality and Tiger's Fury) to prevent tick timer reset from non-natural energy gains

What's New in Version 6.1.1 (January 8, 2026)

๐Ÿ› Bugfixes

  • โœ… Chat Level Display Fix - Fixed targeting high-level players overwriting known level with -1. Now shows "??" for unknown levels instead of -1
  • โœ… Nameplate Level Fix - Nameplates now use stored level from database after reload instead of showing "??"
  • โœ… Nameplate Level Color - Level color now correctly uses difficulty color when loaded from database

โš™๏ธ Config Changes

  • โœ… Chat Player Levels - Now disabled by default (was enabled)

What's New in Version 6.1.0 (January 8, 2026)

๐Ÿ› Bugfixes

  • โœ… 40-Yard Range Check Fix - Fixed range check not working for raid/party frames due to throttle variable conflict (this.tick vs this.throttleTick)
  • โœ… Aggro Indicator Fix - Fixed aggro indicator not displaying properly on raid/party frames (same throttle issue)
  • โœ… Aggro Detection Cache - Improved aggro cache to only cache positive results, allowing instant detection when aggro changes while maintaining performance
  • โœ… Raid Frames with Group Display - Fixed HP/Mana not updating when "Use Raid Frames to display group members" was enabled without being in a raid
  • โœ… SuperWoW nil-check - Added nil-check for SpellInfo in superwow.lua to prevent errors when SuperWoW is not installed
  • โœ… Missing Event Registration - Added missing events for raid/party frames: PARTY_MEMBER_ENABLE, PARTY_MEMBER_DISABLE, PLAYER_UPDATE_RESTING

๐ŸŽจ UI Improvements

  • โœ… Share Button Warning - Shows message when Share module is disabled instead of doing nothing
  • โœ… Hoverbind Button Warning - Shows message when Hoverbind module is disabled instead of doing nothing

What's New in Version 6.0.0 (January 5, 2026)

๐Ÿš€ Major Performance Improvements

  • โœ… Central Raid/Party Event Handler - Replaced per-frame event registration with a centralized system using O(1) unitmap lookups instead of O(n) iteration. Reduces event processing from ~5,760 calls/sec to ~400 calls/sec in 40-man raids (97.5% improvement)
  • โœ… Raid HP/Mana Update Fix - Fixed race condition where unitmap wasn't rebuilt after frame IDs were reassigned, causing HP/Mana bars to not update when players swap positions
  • โœ… OnUpdate Throttling - Added configurable throttles to reduce CPU usage:
    • Nameplates: 0.1s throttle (target updates remain instant)
    • Tooltip cursor following: 0.1s throttle
    • Chat tab mouseover: 0.1s throttle
    • Panel alignment: 0.2s throttle
    • Autohide hover check: 0.05s throttle
    • Libpredict cleanup: 0.1s throttle

๐Ÿ”ง Castbar & Pushback System

  • โœ… Pushback Fix - Fixed spell pushback calculation: now correctly adds delay to casttime instead of start time, matching actual WoW behavior
  • โœ… Player GUID Caching - Caches player GUID on PLAYER_ENTERING_WORLD for efficient self-cast detection
  • โœ… Hybrid Detection System - Uses libcast.db for player casts (handles SPELLCAST_DELAYED events) and SuperWoW's UNIT_CASTEVENT for NPC/other player casts
  • โœ… 2-Decimal Precision - Castbar timer now displays with 2 decimal places (e.g., "1.45 / 2.50") for more precise timing

๐Ÿฑ Druid Stealth Detection

  • โœ… Event-Based Detection - Replaced polling-based stealth detection with event-driven system using UNIT_CASTEVENT and PLAYER_AURAS_CHANGED
  • โœ… Instant Cat Form Detection - Detects Cat Form via UNIT_CASTEVENT (spell ID 768) for immediate actionbar page switch
  • โœ… Smart Buff Scanning - Only scans buffs when actually needed (entering Cat Form), eliminates 31-buff scan every frame
  • โœ… Cached Variables - Caches stealth state to prevent redundant checks

๐ŸŽฏ Nameplate Improvements

  • โœ… Friendly Player Classification - Fixed friendly players being classified as FRIENDLY_NPC, now correctly uses FRIENDLY_PLAYER for proper nameplate coloring and behavior
  • โœ… Performance Throttle - 0.1s update throttle for non-target nameplates while keeping target nameplate updates instant

๐Ÿ†• New Modules

Modules by jrc13245

  • โœ… nampower.lua - Nampower DLL integration module:

    • Spell Queue Indicator (shows queued spell icon near castbar)
    • GCD Indicator
    • Reactive Spell Indicator
    • Enhanced buff tracking
    • Requires Nampower DLL
  • โœ… unitxp.lua - UnitXP_SP3 DLL integration module:

    • Line of Sight Indicator on target frame
    • Behind Indicator on target frame
    • OS Notifications for combat events
    • Distance-based features
    • Requires UnitXP_SP3 DLL
  • โœ… bgscore.lua - Battleground Score frame positioning:

    • Movable BG score frame
    • Position saving across sessions

๐Ÿ› ๏ธ DLL Detection & API Helpers

  • โœ… HasSuperWoW() - Detects SuperWoW DLL presence
  • โœ… HasUnitXP() - Detects UnitXP_SP3 DLL presence
  • โœ… HasNampower() - Detects Nampower DLL presence
  • โœ… GetUnitDistance(unit1, unit2) - Returns distance using best available method (UnitXP or SuperWoW)
  • โœ… UnitInLineOfSight(unit1, unit2) - Line of sight check via UnitXP
  • โœ… UnitIsBehind(unit1, unit2) - Behind check via UnitXP

๐Ÿ“ New Slash Commands

  • โœ… /pfdll - Shows DLL status for SuperWoW, Nampower, and UnitXP with detailed diagnostics
  • โœ… /pfbehind - Test command for Behind/LOS detection on current target

๐ŸŽฎ SuperWoW API Wrappers

  • โœ… TrackUnit API - Track group members on minimap (configurable)
  • โœ… Raid Marker Targeting - Target units by raid marker ("mark1" to "mark8")
  • โœ… GetUnitOwner - Get owner of pets/totems using "owner" suffix
  • โœ… Enhanced SpellInfo - Wrapper returning structured spell data
  • โœ… Clickthrough API - Toggle clicking through corpses
  • โœ… Autoloot API - Control autoloot setting
  • โœ… GetPlayerBuffSpellId - Get spell ID from buff index
  • โœ… LogToCombatLog - Add custom entries to combat log
  • โœ… SetLocalRaidTarget - Set raid markers only visible to self
  • โœ… GetItemCharges - Get item charges (SuperWoW returns as negative)
  • โœ… GetUnitWeaponEnchants - Get weapon enchant info on any unit

๐Ÿ’ฌ Chat Enhancements

  • โœ… Player Level Display - Shows player level next to names in chat (color-coded by difficulty)
  • โœ… Tab Mouseover Throttle - 0.1s throttle for chat tab hover effects

โš™๏ธ New Configuration Options

All new features are configurable via /pfui:

Unit Frames โ†’ SuperWoW Settings:

  • Track Group on Minimap

Unit Frames โ†’ Nampower Settings:

  • Show Spell Queue Indicator
  • Spell Queue Icon Size
  • Show Reactive Spell Indicator
  • Reactive Indicator Size
  • Enhanced Buff Tracking

Unit Frames โ†’ UnitXP Settings:

  • Show Line of Sight Indicator
  • Show Behind Indicator
  • Enable OS Notifications

Chat โ†’ Text:

  • Enable Player Levels

๐Ÿ› Bugfixes

  • โœ… superwow_active Variable - Fixed inconsistent SuperWoW detection across modules (nameplates, castbar, librange, unitframes)
  • โœ… Unitmap Race Condition - Fixed HP/Mana not updating when raid members swap positions
  • โœ… Friendly Nameplate Color - Fixed friendly players using NPC color instead of player color

๐Ÿข Turtle WoW TBC Spell Indicators

Turtle WoW includes TBC spells in the Vanilla client. This version includes all TBC buff indicators:

  • โœ… Commanding Shout indicator
  • โœ… Misdirection indicator
  • โœ… Earth Shield indicator
  • โœ… Prayer of Mending indicator

Version: 6.2.0
Release Date: January 10, 2026
Compatibility: Turtle WoW 1.18.0
Optional DLLs: SuperWoW, Nampower, UnitXP_SP3 (enhanced features when available)


Installation

  1. Download Latest Version
  2. Unpack the Zip file
  3. Rename the folder "pfUI-master" to "pfUI"
  4. Copy "pfUI" into Wow-Directory\Interface\AddOns
  5. Restart Wow

Optional DLL Enhancements

pfUI 6.0.0 includes optional integrations with client-side DLLs for enhanced functionality. These DLLs are fully supported on Turtle WoW:

SuperWoW

Repository: https://github.com/balakethelock/SuperWoW

Provides:

  • Enhanced castbar detection via UNIT_CASTEVENT
  • UnitPosition for distance calculations
  • SetMouseoverUnit for improved targeting
  • SpellInfo for spell data queries

Nampower

Repository: https://gitea.com/avitasia/nampower

Provides:

  • Spell queue indicator
  • GCD indicator
  • Reactive spell detection
  • Enhanced cast information

UnitXP_SP3

Repository: https://codeberg.org/konaka/UnitXP_SP3

Provides:

  • Line of Sight detection
  • Behind detection
  • Accurate distance calculations
  • OS notifications

Use /pfdll in-game to check which DLLs are detected.

Commands

/pfui         Open the configuration GUI
/pfdll        Show DLL detection status (SuperWoW, Nampower, UnitXP)
/pfbehind     Test Behind/LOS detection on current target
/clickthrough Toggle clickthrough mode (or /ct)
/share        Open the configuration import/export dialog
/gm           Open the ticket Dialog
/rl           Reload the whole UI
/farm         Toggles the Farm-Mode
/pfcast       Same as /cast but for mouseover units
/focus        Creates a Focus-Frame for the current target
/castfocus    Same as /cast but for focus frame
/clearfocus   Clears the Focus-Frame
/swapfocus    Toggle Focus and Target-Frame
/pftest       Toggle pfUI Unitframe Test Mode
/abp          Addon Button Panel

Languages

pfUI supports and contains language specific code for the following gameclients.

  • English (enUS)
  • Korean (koKR)
  • French (frFR)
  • German (deDE)
  • Chinese (zhCN)
  • Spanish (esES)
  • Russian (ruRU)

Recommended Addons

Plugins

FAQ

What does "pfUI" stand for?
The term "pfui!" is german and simply stands for "pooh!", because I'm not a big fan of creating configuration UI's, especially not via the Wow-API (you might have noticed that in ShaguUI).

How can I donate?
You can donate via GitHub or Ko-fi

How do I report a Bug?
Please provide as much information as possible in the Bugtracker. If there is an error message, provide the full content of it. Just telling that "there is an error" won't help any of us. Please consider adding additional information such as: since when did you got the error, does it still happen using a clean configuration, what other addons are loaded and which version you're running. When playing with a non-english client, the language might be relevant too. If possible, explain how people can reproduce the issue.

How can I contribute? Report errors and issues in the Bugtracker. Please make sure to have the latest version installed and check for conflicting addons beforehand.

I have bad performance, what can I do?
Version 6.0.0 includes significant performance optimizations. If you still experience issues:

  1. Disable "Frame Shadows" in Settings โ†’ Appearance โ†’ Enable Frame Shadows
  2. Check /pfdll to see which DLLs are active (some features require DLLs)
  3. Disable all AddOns but pfUI and enable one-by-one to identify conflicts
  4. Report issues via the Bugtracker

Where is the happiness indicator for pets?
The pet happiness is shown as the color of your pet's frame. Depending on your skin, this can either be the text or the background color of your pet's healthbar:

  • Green = Happy
  • Yellow = Content
  • Red = Unhappy

Since version 4.0.7 there is also an additional icon that can be enabled from the pet unit frame options.

Can I use Clique with pfUI?
This addon already includes support for clickcasting. If you still want to make use of clique, all pfUI's unitframes are already compatible to Clique-TBC. For Vanilla, a pfUI compatible version can be found Here. If you want to keep your current version of Clique, you'll have to apply this Patch.

Where is the Experience Bar?
The experience bar shows up on mouseover and whenever you gain experience, next to left chatframe by default. There's also an option to make it stay visible all the time.

How do I show the Damage- and Threatmeter Dock?
If you enabled the "dock"-feature for your external (third-party) meters such as DPSMate or KTM, then you'll be able to toggle between them and the Right Chat by clicking on the ">" symbol on the bottom-right panel.

Why is my chat always resetting to only 3 lines of text?
This happens if "Simple Chat" is enabled in blizzards interface settings (Advanced Options). Paste the following command into your chat to disable that option: /run SIMPLE_CHAT="0"; pfUI.chat.SetupPositions(); ReloadUI()

How can I enable mouseover cast?
On Vanilla, create a macro with "/pfcast SPELLNAME". If you also want to see the cooldown, You might want to add "/run if nil then CastSpellByName("SPELLNAME") end" on top of the macro.

Everything from scratch?! Are you insane?
Most probably, yes.


๐Ÿค Credits & Acknowledgments

  • Shagu - Original pfUI creator (https://github.com/shagu/pfUI)
  • me0wg4ming - pfUI fork maintainer and Turtle WoW enhancements
  • jrc13245 - Nampower, UnitXP, and BGScore module integration (https://github.com/jrc13245/)
  • SuperWoW Team - SuperWoW framework development
  • avitasia - Nampower DLL development
  • konaka - UnitXP_SP3 DLL development
  • Turtle WoW Team - For the amazing Vanilla+ experience
  • Community - Bug reports, feature suggestions, and testing

๐Ÿ“„ License

Same as original pfUI - free to use and modify.


Version: 7.6.2 Release Date: February 6, 2026
Compatibility: Turtle WoW 1.18.0
Status: Stable

About

A User Interface Replacement for World of Warcraft: Vanilla & TBC

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Lua 100.0%