Version: 0.7.0-alpha
This project has been heavily vibe-coded.
My personal coding experience is limited, and I am doing what I can to build, test, and improve it as I go.
This addon is still in a very early stage of development. It is not really intended yet as a polished daily-use addon, and it still needs more logic work, design refinement, testing, and general cleanup before it can be considered stable.
If that is not your thing, please abstain from low-value or useless comments.
Blood Elf Restore is a World of Warcraft addon for Midnight-era Quel'Thalas that suppresses selected new Blood Elf NPC voice lines and injects original TBC-era Blood Elf voice sets during NPC interaction events.
It also includes a scoped Midnight Quel'Thalas music layer that mutes tracked supported-zone music FileDataIDs and injects old TBC regional music on Master while temporarily forcing native Sound_MusicVolume=0 in supported zones.
- Mutes tracked Midnight Blood Elf NPC voice FileDataIDs listed in
SoundData.lua - Plays original TBC voice lines for supported Blood Elf NPCs
- Supports greet playback on left-click target selection
- Supports greet playback on gossip open
- Supports bye playback on gossip close
- Supports bye playback when you click away from a recently greeted target
- Supports pissed playback after repeated clicks on the same NPC
- Mutes tracked supported-zone music FileDataIDs listed in
SoundData.lua - Injects region-aware TBC intro/day/night music while you remain in supported Midnight Quel'Thalas music areas
- Uses shuffle-with-cooldown logic so the same TBC music track is strongly discouraged from repeating too soon
- Can record music routing traces into SavedVariables for later analysis
- Captures all debug output to a 2000-line ring-buffer log in SavedVariables, viewable in-game via
/belr dumplog - Optionally routes all debug output to a dedicated chat tab via DebugChatFrame (install separately if desired)
- Exposes an in-game settings and test UI via
/belr
- Addon loads correctly as
bloodElfRestore - Midnight Blood Elf voice muting can be enabled, disabled, and re-applied
- Left-click greet playback works on recognized nearby targets
- Hidden-race target-select fallback now works only for positive Blood Elf name/profile hints, so generic humanoids no longer get guessed into TBC VO
- Right-click gossip greet playback works
- Gossip close bye playback works
- Target-loss bye playback works after a short post-greet delay and is skipped if the disengage happens too late to sound believable
- Male and female TBC voice selection works with the current default reversed
UnitSexmapping - GUID-based and name-based manual overrides work
- Role-based voice pools work for
noble,standard, andmilitary - Test playback buttons cover male and female voice sets for all three roles
- Rapid retargeting overlap is reduced by stop-handle logic, playback throttling, and target-loss bye delay/max-age rules
- Far-distance left-click targeting uses fake distance falloff buckets instead of always playing
- If WoW sound output is disabled (including the usual sound-effects toggle such as
Ctrl+S), the addon does not inject replacement voices - Verbose logging now includes the NPC name in key trigger lines to make troubleshooting easier
- Voice replacement is now scoped to supported Quel'Thalas areas, with native-only exclusions such as
Harandar - Music replacement is now scoped to Midnight Quel'Thalas map lineage instead of broad zone text alone
- Music logic currently recognizes:
Silvermoon CityEversong WoodsSanctum of Light- selected supported subzones such as
The Bazaar,Sunstrider Isle,Tranquillien,Sanctum of the Moon, andWayfarer's Rest
- Native-only guards keep unsupported or intentionally excluded areas on Blizzard music:
Harandar- unrelated Midnight zones outside Quel'Thalas scope
- non-Midnight world zones
- Region routing now distinguishes:
silvermoonsilvermoon_interioreversongsunstridereversong_southdeatholmeamani
Ruins of Deatholmenow routes to the dedicateddeatholmepool again, including a token fallback for small subzone naming shifts- Amani-style troll subzones now route to dedicated troll music logic:
- explicit overrides for
Amani Pass,Zeb'Nowa, andZeb'tela Ruins - name-pattern fallback for subzones containing
amaniorzeb'
- explicit overrides for
- Midnight music muting is now applied only while you are actually in a supported music region; it is no longer globally applied on login
- Supported interiors can now mute both Midnight
mus_120_*music and Blizzard generic tavern / inn zonemusic to prevent overlap in supported interior subzones - Silvermoon City interiors detected via
IsIndoors()or explicit subzone overrides such asWayfarer's Restnow route to a dedicatedsilvermoon_interiorpool with calm scenic music instead of the outdoor day/night cycle - The generated Midnight catalog is loaded at runtime and currently provides the main music mute coverage, with Harandar families intentionally excluded
- Replacement music now uses
Masterwhile supported replacement ownership temporarily forces nativeSound_MusicVolume=0, which is the current reliable fix for Silvermoon load-screen overlap - Moving between supported music regions now forces an immediate TBC music handoff instead of waiting for the old injected region track to finish naturally
- Temporary CVar backups for music volume, ambience, and dialog are restored on area exit,
/reload, and logout - Ctrl+M and global sound-toggle changes now trigger immediate music re-evaluation (
CVAR_UPDATE) without waiting for periodic ticks - Non-NPC gossip objects with protected or nonstandard GUID values now fail closed instead of crashing the addon while it tries to inspect or log them
- The settings UI is now split into separate
VoiceandMusictabs - Music-tab action buttons now anchor below the live status block so longer status text does not overlap the controls
- Music can optionally play an intro cue on entry into supported zones, then rotate through day or night pools
- Intro cooldown (default 10 minutes) is persisted in SavedVariables across
/reload, logout, and game restarts, so the intro only replays after the cooldown expires - Intro cooldown policy is now user-editable in
Config.luaby region, zone, subzone, area (zone||subzone), pool, and exact FileDataID - Music trace recording can be enabled, walked through the city, and saved via
/reloador logout for later tuning /belr statusnow reports music region, scope source, override source, catalog counts, and supplemental mute counts
- True 3D positional audio is not possible with this addon approach
- Per-yard volume falloff is not possible for injected
PlaySoundFile()playback - Fake distance falloff is behavioral only: sounds play less often at range, but not quieter
- Some Midnight NPCs still require manual overrides because Blizzard hides or misreports metadata
- Some NPCs still need explicit built-in profile exceptions (for example vendor-only or excluded non-Blood Elf false positives)
- Hidden-race target-select fallback before gossip is intentionally conservative: it only accepts supported-area NPCs with positive Blood Elf name/profile hints
- Mute coverage depends on the generated Midnight catalog plus the manual and supplemental FileDataIDs listed in
SoundData.lua - If Blizzard adds or swaps new Blood Elf VO assets, more mute IDs may be needed
- Music replacement is an addon-side approximation, not a true engine-level override of Blizzard's internal zone music resolver
- The addon cannot reliably read the exact native Midnight music FileDataID currently playing
- Music transitions are smoother than a hard stop, but they are still limited by what
PlaySoundFile()andStopSound()allow on the addon side - Music muting now depends on a generated Midnight catalog plus manually maintained supplemental IDs in
SoundData.lua; anonymousmus_1200_*IDs or non-listfile SoundKit playback can still require manual follow-up - Supported-zone continuity for interiors and enclave slices depends on the scope tokens, native-only tokens, and subzone overrides in
Config.lua
The addon is built around two layers:
-
Suppression It calls
MuteSoundFile()for known Midnight Blood Elf voice FileDataIDs. -
Replacement It listens for target and gossip events, classifies the target as a Blood Elf NPC, resolves a role and voice sex, then plays a matching TBC FileDataID.
Because WoW does not let the addon attach those injected sounds to the NPC in 3D space, the addon uses approximation logic:
- fake distance falloff by distance buckets
- short playback throttling
- target-loss bye delay plus a short maximum believable disengage window
- brief dialog-channel suppression around injected playback
The music system uses a similar approximation model:
- Build a tracked supported-zone mute set from generated Midnight
mus_120_*families, manual non-catalogmus_1200_*seeds, and supplemental Blizzard zonemusic families used inside supported interiors. - Resolve whether the current area is actually inside Midnight Quel'Thalas using zone text, subzone text, and parent map lineage.
- Keep native-only exclusions such as
Harandaron Blizzard music even if the parent zone would otherwise qualify. - Watch zone, subzone, resting, and day/night changes.
- Choose an intro/day/night TBC music track.
- Avoid immediate repeats with a per-track cooldown.
- Stop, fade, and re-evaluate the injected music when the context changes, including immediate supported-region handoff when the active injected track no longer matches the player's current region.
- Restore any temporary audio-setting backups when the addon leaves music control or the client reloads.
The current music layer also:
- uses region-specific pools for broader Eversong, Sunstrider Isle, southern Eversong remastered areas, a dedicated Deatholme pocket, Amani routing, and a Silvermoon interior pool
- detects Silvermoon City interiors via
IsIndoors()and routes them to calm scenic music instead of the outdoor day/night cycle - loads a generated Midnight music catalog from wowdev/wow-listfile release
202603061837 - excludes Harandar music families from addon muting so Harandar stays native
- supplements the Midnight catalog with Blizzard generic tavern / inn / rest-area zonemusic for supported interiors
- avoids replaying intro cues too often with a separate intro cooldown
- persists intro cooldown history across
/reloadand logout-safe SavedVariables flushes - reads intro cooldown rules from
Config.luainstead of one hardcoded runtime constant - lets known tracks finish naturally instead of cutting them off with the old coarse timer
- keeps
/belr music stopidle until a real resume trigger occurs - temporarily forces native
Sound_MusicVolume=0only while supported replacement music is active, then restores the previous value on exit,/reload, and logout
Clone or download this repository into your WoW addons directory so the folder is named bloodElfRestore:
World of Warcraft\_retail_\Interface\AddOns\bloodElfRestore\
The folder name must match the TOC filename exactly or WoW will not load the addon.
bloodElfRestore/
├── bloodElfRestore.toc Addon metadata and load order
├── Config.lua User-editable policy layer
├── Midnight_ID_catalog.lua Generated Midnight music catalog (runtime)
├── SoundData.lua Mute IDs, TBC voice/music pools
├── Debug.lua DebugChatFrame integration + log capture
├── BElfRestore.lua Main logic, UI, event handling
├── LICENSE MIT License
├── README.md This file
├── CHANGELOG.md Version history
├── DEV_NOTES.md Developer handoff notes
├── Midnight_ID_Index.md Human-readable Midnight music index
├── TBC_ID_INDEX.md Human-readable TBC zone-music index
├── TBC_ID_CATALOG.lua TBC zone-music ID catalog (reference)
├── assets/
│ └── tbc_art.jpg Optional UI background art
└── tools/
├── generate_midnight_catalog.ps1
└── generate_tbc_catalog.ps1
Files are loaded by WoW in the order specified in bloodElfRestore.toc:
Config.lua → Midnight_ID_catalog.lua → SoundData.lua → Debug.lua → BElfRestore.lua
Config.luaUser-editable policy layer for safe voice behavior, voice classification/scope rules, built-in name/ID overrides, music routing/scope/timing, intro cooldown rules, trace limits, and UI art/layout tuning.Debug.luaDebugChatFrame integration layer. Provides globalc()andcp()logging shortcuts, a 2000-line ring-buffer log capture in SavedVariables, a copyable dump frame (/belr dumplog), and pre-init buffering for startup lines. Requires the optional DebugChatFrame addon for the dedicated chat tab; falls back toprint()if not installed. Log capture to SavedVariables works either way.BElfRestore.luaMain logic, UI, event handling, classification, overrides, playback rules.SoundData.luaNew Midnight mute IDs plus TBC male/female voice pools, manual Midnight music seed IDs, supplemental supported-zone music mute IDs, and TBC music pools.Midnight_ID_catalog.luaMachine-readable Midnightmus_120_*music catalog generated from wowdev/wow-listfile and loaded at runtime beforeSoundData.lua.Midnight_ID_Index.mdHuman-readable Midnight music family index generated from wowdev/wow-listfile, with notes about runtime exclusions and supplemental mutes.TBC_ID_CATALOG.luaData-first TBC zone-music ID catalog (Quel'Thalas focus + Outland + key TBC instances) for future config authoring.TBC_ID_INDEX.mdHuman-readable summary/counts and full Quel'Thalas ID listing generated from wow-listfile.assets/tbc_art.jpgOptional UI background art used by the settings panel.bloodElfRestore.tocAddon metadata and load order.DEV_NOTES.mdOngoing developer handoff notes.
Catalog regeneration:
tools/generate_midnight_catalog.ps1 -ListfilePath <path-to-community-listfile.csv> -ReleaseTag <tag>tools/generate_tbc_catalog.ps1 -ListfilePath <path-to-community-listfile-withcapitals.csv> -ReleaseTag <tag>
/belrOpen the UI.- Legacy alias:
/belvrruns the same command set for backward compatibility.
General addon power:
/belr onTurns the addon on./belr offTurns the addon off and stops its replacement behavior./belr statusPrints the addon's current settings, loaded counts, intro cooldown summary, and current music zone / subzone / region context in chat.
Voice muting and voice debug:
/belr mute onTurns on muting for the tracked new Midnight Blood Elf voice lines./belr mute offRestores the tracked new Midnight Blood Elf voice lines./belr verboseToggles detailed voice debug messages in chat./belr verbose onForces detailed voice debug messages on./belr verbose offForces detailed voice debug messages off.
Voice detection and behavior:
/belr fallback onAllows the addon to use its backup humanoid check when Blizzard hides NPC race data./belr fallback offDisables that backup humanoid check./belr target onPlays a greet when you left-click and target a supported NPC./belr target offDisables left-click target greet playback./belr invertToggles the male/female voice swap used when Blizzard reports NPC sex backwards./belr invert onForces the male/female voice swap on./belr invert offForces the male/female voice swap off./belr suppressToggles temporary native dialog suppression during injected voice playback./belr suppress onForces native dialog suppression on./belr suppress offForces native dialog suppression off.
Manual voice fixes for the NPC you are targeting:
/belr force maleForces the current target to use male voice playback./belr force femaleForces the current target to use female voice playback./belr force clearClears the exact-target gender override./belr role militaryForces the current target into the military voice pool./belr role nobleForces the current target into the noble voice pool./belr role standardForces the current target into the standard voice pool./belr role clearClears the exact-target role override.
Manual voice fixes for every NPC with the same visible name:
/belr force-name maleForces all NPCs with the current target's name to use male voice playback./belr force-name femaleForces all NPCs with the current target's name to use female voice playback./belr force-name clearClears the name-wide gender override./belr role-name militaryForces all NPCs with the current target's name into the military voice pool./belr role-name nobleForces all NPCs with the current target's name into the noble voice pool./belr role-name standardForces all NPCs with the current target's name into the standard voice pool./belr role-name clearClears the name-wide role override.
Music controls:
/belr music onTurns the music replacement system on./belr music offTurns the music replacement system off./belr music mute onMutes the tracked supported-zone music IDs used by the music replacement layer./belr music mute offRestores the tracked supported-zone music IDs./belr music verboseToggles detailed music routing messages in chat./belr music verbose onForces detailed music routing messages on./belr music verbose offForces detailed music routing messages off./belr music intro onMakes the addon play the intro music cue when entering the supported music region./belr music intro offDisables that intro-on-entry cue./belr music nowForces the addon to re-check your current area and refresh music logic immediately./belr music stopStops the currently injected addon music and clears the music state.
Debug log:
/belr dumplogOpens a copyable window with the full debug log buffer. UseCtrl+AthenCtrl+Cto copy the contents./belr log clearClears the debug log buffer.
Music trace recording:
/belr music trace onStarts recording music routing and playback lines into SavedVariables for later review./belr music trace offStops recording the music trace./belr music trace clearClears the saved music trace buffer./belr music note <text>Adds a manual trace marker line with your note plus current zone/subzone/region context.
Music test playback:
/belr test music introPlays the configured intro music track for testing./belr test music dayPlays one of the configured daytime music tracks for testing./belr test music nightPlays one of the configured nighttime music tracks for testing.
Voice test playback:
/belr test male greetPlays a random male greet line./belr test male byePlays a random male bye line./belr test male pissedPlays a random male pissed line./belr test female greetPlays a random female greet line./belr test female byePlays a random female bye line./belr test female pissedPlays a random female pissed line.
- Hovering a checkbox shows a plain-English explanation of what it does.
- Enable addon logic
- Mute new Midnight Blood Elf voice files
- Verbose chat debug
- Fallback humanoid classifier
- Left-click greet toggle
- Invert NPC sex mapping toggle
- Suppress native dialog during injected playback toggle
- Enable replacement music logic
- Mute tracked supported-zone music files
- Verbose music debug
- Record music trace to SavedVariables
- Play intro cue on fresh entry
- Music status block with region and ID counts
- Test buttons for intro/day/night music
- Re-apply music mutes
- Clear music trace
- Restore Midnight music
- Force music refresh
- Test playback buttons for male/female
noble,standard, andmilitary - Re-apply mutes
- Restore Midnight VO
Re-apply Mutes also re-enables the mute option if it was previously turned off.
The addon includes a structured debug logging system. All voice, music, and event activity is captured to a ring buffer in SavedVariables and can optionally be routed to a dedicated in-game chat tab.
All c() debug output is captured to BElfVRDB.debugLog in SavedVariables (2000-line ring buffer). This persists across /reload and logout.
/belr dumplogopens a scrollable, copyable window in-game. UseCtrl+AthenCtrl+Cto copy the full log./belr log clearwipes the buffer.- The raw log is also available on disk after logout at:
WTF/Account/<ACCOUNT>/SavedVariables/bloodElfRestore.lua
For a live-scrolling debug chat tab, install the DebugChatFrame addon separately. When installed, all debug output is routed to a dedicated BElfVR tab in the chat pane in addition to the SavedVariables ring buffer.
DebugChatFrame is entirely optional. If it is not installed, the addon falls back to print() for any output and the ring-buffer capture still works normally.
- Addon lifecycle:
ADDON_LOADED,PLAYER_LOGIN,PLAYER_ENTERING_WORLD,PLAYER_LOGOUT - Zone changes:
ZONE_CHANGED_NEW_AREA,ZONE_CHANGED,ZONE_CHANGED_INDOORS - Target events:
PLAYER_TARGET_CHANGEDwith NPC name - Gossip events:
GOSSIP_SHOW,GOSSIP_CLOSED - Sound CVar changes:
Sound_EnableMusic,Sound_MusicVolume,Sound_EnableDialog - Voice decisions: NPC classification, gender/role resolution, playback or skip reasons
- Music decisions: track selection, intro cooldown checks, context changes, region handoffs
New bugs and regressions should be tracked in the repo issue tracker rather than maintained here as a running checklist.
Sound_EnableDialogis briefly toggled during injected playback. This is intentional as a workaround, but it is a global client setting and not a per-NPC audio control.UnitSexappears inverted for current Midnight Blood Elf NPCs, so the addon treats it as reversed by default.- Role classification still uses name heuristics for many NPCs.
- The role-pool slicing logic depends on the exact list order in
SoundData.lua. - Music replacement currently uses
Masterwhile nativeSound_MusicVolumeis forced to0in supported areas, so WoW's music slider does not directly control the injected track during replacement playback. - The generated Midnight catalog covers
mus_120_*families, but manual follow-up may still be needed for anonymousmus_1200_*IDs or non-listfile SoundKit playback. - The music trace recorder does not create a standalone text file. It writes into SavedVariables, which WoW flushes to disk on
/reloador logout. - Large trace captures should be done in a single pass and then cleared; the recorder keeps a capped ring buffer, not an infinite log.
Config.luais a live code file, not a UI form. Keep its text keys lowercase and change one rule at a time.
This project is released under the MIT License. See LICENSE for the full text.
- Move additional tightly-coupled data-layout knobs into
Config.luaonly where doing so does not make the runtime easier to break. - Expand mute coverage for additional Midnight Blood Elf VO assets.
- Add more exact built-in overrides for known problematic NPCs.
- Add optional UI controls for tuning fake distance falloff probabilities.
- Add a richer role model if more granular voice pools are needed.
- Expand the Midnight Quel'Thalas scope and subzone allow-lists based on trace recordings.
- Capture additional anonymous
mus_1200_*or non-listfile native music leaks if Blizzard introduces them. - Replace placeholder TOC metadata such as author information with final release metadata.
This addon benefits more from free exploratory testing than from a rigid scripted pass.
- Use it normally across supported and unsupported areas, including reloads, relogs, flight paths, fast movement, and abrupt target swaps.
- Try destructive or awkward interaction patterns on purpose: rapid left-click retargeting, repeated gossip open and close, moving out of range mid-line, and toggling settings while audio is active.
- If something sounds wrong, file it in the repo issue tracker with the NPC name, zone or subzone, what you expected, what actually happened, and any useful
/belr verboseor/belr music traceoutput. - Use the in-game debug commands when needed, but as investigation tools, not as a required checklist for every tester.