v1.1.3
What's new
MilestoneKeys Changelog
[Unreleased]
[1.1.3] - 2026-08-11
Changed
- TOC
## Interfacebumped120005→120100for patch 12.1.0 (Midnight, The Curse of Ula'tek). Addon no longer flags as out-of-date. - TOC
## Authorfixed from the scaffold placeholder "You" to "icey2488".
Fixed
- Release changelog now shows these curated notes instead of a raw commit dump.
.pkgmetagained amanual-changelogdirective pointing atCHANGELOG.md, andCHANGELOG.mdwas dropped from theignorelist so the curated file also ships inside the release zip. Every release through v1.1.2 shipped a packager-generated commit log.
Notes
No dungeon data changes were needed for the Season 2 keystone pool. MilestoneKeys hardcodes no instance IDs, map IDs, or season lists. The pool is resolved at runtime in three places, all of which pick up new dungeons automatically:
UI.luaBuildDungeonList()—C_ChallengeMode.GetMapTable(), rebuilt each time the options panel opens.Core.luaGetCurrentDungeonContext()— same call, matchingGetInstanceInfo()againstGetMapUIInfo().Predict.luaGetMDTDungeonIdx()— resolveschallengeMapID→ MDTdungeonIdxby lookup; MDT owns route and forces data.
Season 2 pool for reference: Altar of Fangs, Murder Row, Den of Nalorakk, The Blinding Vale, Voidscar Arena (Midnight); King's Rest, Temple of Sethraliss (BfA); Ruby Life Pools (Dragonflight).
Known issues
- Per-dungeon milestone profiles are keyed by
challengeMapIDin SavedVariables. Profiles for dungeons that rotate out of the pool persist but disappear from the "Editing profile for" dropdown, so they can no longer be edited or cleared. Accumulates one season's worth of orphans per rotation. Core.luain-instance detection comparesGetInstanceInfo()toGetMapUIInfo()by exact string. Needs an in-game check against the new 12.1 instances (Altar of Fangs in particular) to confirm the two names still match.
[1.1.2] - 2026-05-17
Added
- Options panel opacity slider (Appearance group): fades the backdrop only, leaving all widgets fully opaque. Saved to
db.profile.options.panelOpacity. - Reset Window button in Settings: wipes saved position and size, reopens the panel at defaults.
- Options panel position and dimensions now persist across sessions via
AceGUI Frame:SetStatusTable(). - Location-aware dungeon auto-selection: options panel auto-selects the current dungeon when opened during or between runs, with a coloured indicator label.
- MDT predictive pull alerts now production-ready: warns in chat when the next MDT pull will cross a milestone threshold. Verified working in live M+ keys. Enabled via the Behavior group toggle.
Changed
- Settings section reorganized into four labeled subsections: Alerts, HUD, Appearance, Behavior.
- Alert sound selection consolidated from three radio checkboxes into a single dropdown with a Play preview button.
- All three opacity sliders (HUD, Alert Frame, Options Panel) now reach fully opaque at 1.0. Root cause was the AceGUI default backdrop texture (
UI-DialogBox-Background) having semi-transparent pixels baked in; fix replaces it withInterface\\Buttons\\WHITE8x8. - Default options panel size increased to 820×620 so milestone row buttons sit side-by-side without wrapping.
Fixed
- Forces criteria detection for TWW/Midnight:
isWeightedProgress = trueis now the sole detection signal; the pre-TWWflags & 0x80check no longer works (all flags are 0 in current API). - Decimal percentage precision: computed from raw kill counts via
(%d+)parse ofquantityString, divided bytotalQuantity. Previous approach using[%d%.]+parsed"237%"as237.0and fired all milestones simultaneously. - Options panel backdrop no longer leaks transparency at slider 1.0 (bgFile swap fix).
- Sound preview buttons play the correct sound per button (Lua closure capture fix).
[1.1.1] - 2026-05-17
Added
- Options panel default width increased to 820 × 620 (was 540 × 520) so milestone row buttons (All / None) sit side by side without wrapping.
- Options panel position and dimensions now persist across sessions via
AceGUI Frame:SetStatusTable()backed bydb.profile.uiState. - Off-screen safety: saved position is cleared if the frame would land entirely outside the current screen resolution (e.g. after switching from an ultrawide to a laptop).
- Minimum resize guard: the panel cannot be shrunk below 700 × 450 (
SetResizeBoundswithSetMinResizefallback). - "Reset window" button at the bottom of the Settings section: wipes saved position/size and reopens the panel at defaults.
- Options panel opacity slider (0.30–1.00) in Settings: fades the backdrop only, leaving all text and interactive widgets fully opaque. Saved to
db.profile.options.panelOpacity. Useful for stream overlays and accessibility. - Settings reorganized into labeled InlineGroup subsections: Alerts (sound, chat, frame, forces display), HUD (toggle, lock, opacity, preview), Appearance (alert frame opacity, panel opacity), Behavior (per-dungeon, party sync, predictive alerts, minimap).
- Alert sound selection consolidated from three radio checkboxes to a single dropdown + Play button. Selection stored the same way (
db.profile.alertSound); existing saved values carry forward. - All three opacity sliders (HUD, alert frame, options panel) now use
SetBackdropColor(0,0,0,alpha)on a pure-black backdrop. Slider at 1.0 is now visually fully opaque with no game world visible through any frame. - Options panel opacity slider now achieves true full opacity at 1.0: the AceGUI Frame's default backdrop texture (
UI-DialogBox-Background) has semi-transparent pixels baked in thatSetBackdropColorcannot override; the fix replaces it once withInterface\\Buttons\\WHITE8x8(a solid tile) and drives all opacity viaSetBackdropColor(0,0,0,alpha)— the same approach used by the HUD and Alert frames. Seedocs/API-NOTES.md §2for details.
[1.1.0] - 2026-05-17
Fixed
- Forces tracking now works correctly in The War Within (TWW) / Midnight. All milestone alerts (sound, chat, HUD frame) fire at the right thresholds. Confirmed in-game: Algeth'ar Academy +14, milestones at 20/40/60/80/100% all triggered at correct thresholds; HUD percentage matched Blizzard UI.
- Forces percentage is now computed with decimal precision using raw kill counts from
info.quantityString, rather than the low-precision integerinfo.quantity. - Fixed a regression introduced in v1.0.11 where
(quantity / totalQuantity) * 100produced wildly wrong results (e.g. 4.57% when Blizzard showed 21.52%) becausequantityis an integer percent, not a raw kill count, whenisWeightedProgress = true. - Nominal display mode (
237/585 forces) now uses the correct raw kill count rather than the integer percent field.
Documentation
- Permanent API reference for the TWW forces scenario criteria slot added to
docs/API-NOTES.md §1, preventing future regressions.
[dev-fix-3] - 2026-05-17
Fixed
Forces percentage now computed correctly for The War Within (TWW) / Midnight. See
docs/API-NOTES.md §1for the full field layout and regression history.Previous bug:
dev-fix-2matched the decimal regex[%d%.]+againstquantityString, which parsed e.g."237%"as237.0, then used that directly aspct— firing all milestones simultaneously. Fix: extract only the leading digit sequence(%d+)and divide bytotalQuantity.qtypassed toMK_FormatForcesis nowrawKillsso nominal mode renders e.g.237/585 forces.pctis clamped to[0, 100]after computation.Non-
isWeightedProgressslots now cause an earlyreturninEvaluateForces.Diagnostics kept for one more verification run — remove
[MK Step],[MK Eval],[MK Detect]logging in follow-up commit after confirmation.
[dev-fix-2] - 2026-05-16
Fixed
EvaluateForcesnow readsinfo.quantitydirectly as the forces percentage wheninfo.isWeightedProgress == true, instead of computing(quantity / totalQuantity) * 100. WhenisWeightedProgress=true, Blizzard stores the forces % as an integer inquantity(e.g. 21 for 21.52%);totalQuantityholds the total enemy forces count and is not a denominator. Dividing produced wildly wrong results (e.g. 4.57% when Blizzard showed 21.52%). This restores the intent of the v1.0.9 fix — the v1.0.11 reversion to the division formula was based on a misread of the diagnostic data. Future maintainers: do NOT revert this to a division formula for theisWeightedProgresspath.- If
info.quantityStringcontains a decimal string (e.g."21.52") that differs from the integerquantity, that parsed value is used aspctfor sub-percent precision. IfquantityStringis nil or matches the integer, the integerquantityis used. - Guard is now
if not info then return endonly;totalQuantity == 0is no longer an early-exit for theisWeightedProgresspath (wheretotalQuantityis informational, not a divisor). [MK Step]forces-slot diagnostic line now printsquantityStringand shows computed pct with 4 decimal places, so the next screenshot can confirm precision matches Blizzard UI. Diagnostics kept for one more verification cycle — remove in follow-up commit.
[dev-fix-1] - 2026-05-16
Fixed
EvaluateForcesnil guard now also checksnot info.totalQuantitybefore testing== 0, preventing a potential nil arithmetic error if the API returns an info table with nototalQuantityfield.[MK Step]diagnostic: per-slot loop now marks which slot isFORCES_IDXwith a← FORCES_IDXsuffix so the forces row is immediately visible in output. Final forces-slot print now issues a freshGetCriteriaInfo(idx)call (rather than reusing theinfolocal from the top of the function) and prints the computedpctalongside qty/totalQty, confirming the re-fetched values are consistent with what milestone evaluation uses. Diagnostics not yet removed — keeping until next in-game test confirms pct matches Blizzard UI.
[dev-diag-4] - 2026-05-16
Debug
- Added
[MK Detect]prints insideDetectForcesIndex: logs the returned index on success, or nil with the reason (numCriteria=0 vs no isWeightedProgress slot found). Fires every time detection runs so call-site timing is visible. - Added
[MK Step]block inside the existing 3s-throttled log inEvaluateForces(before[MK Eval]): dumpscurrentStep,stepName, andnumCriteriafromC_Scenario.GetStepInfo(), then enumerates every criteria slot in the current step (desc, qty/totalQty, isWeightedProgress, criteriaType), then prints which slotFORCES_IDXis cached at and what qty/totalQty it's reading. Intended to diagnose multi-step scenario bug (Pit of Saron) where forces criteria lives in a different step than the one detected at run start. Not for release.
[dev-feat-location] - 2026-05-15
Added
MK:GetCurrentDungeonContext()in Core.lua: returns the challenge map ID for the player's current context, checking active M+ key first, then party-instance map ID (translated viaC_ChallengeMode.GetMapUIInfo). Returns a reason code ("active_key"or"in_instance") alongside the ID. API calls are wrapped inpcallfor forward-compatibility.- Dungeon dropdown in the options panel now auto-selects the current dungeon when the panel is opened, if
sessionManualDungeonOverrideis false. Shows a coloured indicator label to the right of the dropdown (📍 Current keyin green or📍 Current dungeonin gold). MK.sessionManualDungeonOverrideflag: set totruewhen the player manually changes the dropdown (clears the indicator); reset tofalseinInitRunso the next key re-enables auto-detection.
[dev-diag-3] - 2026-05-15
Debug
- Added throttled (once per 3 s) diagnostic in
EvaluateForcesthat logs: which milestone table is being iterated and from which DB path (global vs dungeon-specific), then for every milestone slot: index, label, threshold value and type,State.triggered[i]status, current pct, pct type, and whether the threshold comparison passes. Intended to diagnose why an 89% milestone failed to trigger at 93% forces. Not for release — remove before merging to main.
[1.0.11] - 2026-05-15
Fixed
DetectForcesIndexrewritten for TWW/Midnight: detection now usesisWeightedProgress == trueas the sole signal for the forces criteria slot. The oldflags & 0x80bit-check no longer works — all criteria flags are 0 in the current API, causing boss-kill slots (criteriaType=165) to be selected instead. Confirmed via in-game diagnostic dump that the forces slot is uniquely identified byisWeightedProgress=truewith realquantity/totalQuantitycounts.EvaluateForcesnow always computespct = (quantity / totalQuantity) * 100. The previous branch that setpct = info.quantitydirectly whenisWeightedProgresswas true has been removed — the diagnostic showedquantityholds a raw enemy count (e.g. 66), not a percentage.- All diagnostic logging (
[MK Debug]prints,lastDumpthrottle variable) removed. Code is back to clean production state.
[dev-diag-2] - 2026-05-15
Debug
- Expanded diagnostic in
EvaluateForcesto enumerate every scenario criteria slot on eachSCENARIO_CRITERIA_UPDATE, not just the slotDetectForcesIndexselected. Each line shows slot index, description, quantity/totalQuantity, flags, criteriaType, and isWeightedProgress. Output is throttled to once per 5 seconds to avoid chat spam. The selected slot index is printed last so incorrect detection is immediately visible. Not for release — remove before merging to main.
[dev-diag-1] - 2026-05-13
Debug
- Added diagnostic
printstatements toDetectForcesIndexandEvaluateForcesin Core.lua to capture the exact field names and values Blizzard returns for the forces scenario criteria. EachSCENARIO_CRITERIA_UPDATEevent now dumps the fullinfotable and computedpctto the chat frame so the correct percentage field can be identified. Not for release — remove before merging to main.
[1.0.10] - 2026-05-08
Fixed
C_Scenario.GetCriteriaInfoandC_Scenario.GetStepInfoare now called through safe local wrappers (GetCriteriaInfo,GetStepInfo) that tryC_ScenarioInfofirst (TWW), fall back toC_Scenario, and return nil/defaults rather than erroring if neither exists. Eliminates the "attempt to call a nil value" Lua error on line 141 that prevented forces tracking from functioning.
[1.0.9] - 2026-05-07
Fixed
- "Level Up" alert sound now uses FileDataID 569593 (
Sound/Spells/LevelUp.ogg, SoundKit 888) — the actual WoW level-up fanfare — instead of 543587 (BigWigs "Beware" chime). Play button and live alerts now both play the correct sound for each label. - Forces tracking now works in The War Within: when
isWeightedProgress = true,quantityis already the forces percentage (Blizzard hides raw counts).DetectForcesIndexnow recognisesisWeightedProgressas the forces criteria, andEvaluateForcesusesquantitydirectly instead of dividing bytotalQuantity(which TWW sets to 0). Milestones were silently never triggering before this fix. - "Chat" and "Frame" checkboxes in the milestone list widened (65 px and 70 px respectively) to prevent label truncation.
[1.0.8] - 2026-05-07
Fixed
- Sound playback completely reworked: replaced
PlaySound(soundKitID)withPlaySoundFile(fileDataID)for both alert triggers and sound preview Play buttons. SoundKit IDs are unreliable in The War Within; raw FileDataIDs withPlaySoundFilework correctly. - SOUNDS table now uses verified WoW FileDataIDs (567397 alarm, 569200 gong, 543587 level-up) instead of BigWigs OGG paths or SOUNDKIT constants. No external addon dependency.
- Removed all
[MK Debug]print statements from the sound preview Play buttons.
[1.0.7] - 2026-05-07
Added
- HUD frame: "Preview HUD" toggle button in Settings — shows/hides the HUD outside an active key so it can be repositioned freely.
- HUD frame: "Lock HUD position" checkbox in Settings — saves lock state to
db.profile.hudLocked; when locked the frame is click-through (EnableMouse false). hudLocked = falseadded to DB_DEFAULTS.
Fixed
PlaySoundchannel changed from"Master"to"SFX"in both alert triggers (Alerts.lua) and sound preview Play buttons (UI.lua)."Master"was routing through an audio path that produced no audible output on some systems.
[1.0.6] - 2026-05-07
Added
- Persistent in-run HUD frame (HUD.lua): lists all enabled milestones; triggered rows flash then dim with a strikethrough line. Draggable; position saved to
db.profile.hudFramePos. - "Show milestone HUD during keys" checkbox in Settings.
- "HUD Frame Opacity" slider in Settings (0.1–1.0, default 0.8), calls
MK_HUD_SetAlphalive. hudFramePos,hudFrameAlpha, andoptions.showHUDadded to DB_DEFAULTS in Core.lua.MK_HUD_OnMilestoneTriggered(i)wired intoEvaluateForces;MK_HUD_OnRunStart/Endwired intoInitRun,CHALLENGE_MODE_COMPLETED, andCHALLENGE_MODE_RESET.
Debug
- Added temporary debug prints to sound preview Play buttons (key, sound ID, before/after PlaySound) for in-game tracing.
[1.0.5] - 2026-05-07
Added
- Forces display consolidated into a single dropdown: Percentage (85%), Percentage (84.9%), Percentage (84.94%), Nominal (382/450). Replaces the separate "decimal places" dropdown and "Nominal forces" checkbox.
MK_FormatForces(pct, quantity, total)in Core.lua is now the single source of truth for forces formatting, applied in alerts, frame subtitle, and minimap tooltip.
Fixed
- Sound preview Play buttons now capture their key per-iteration via
local k = snd.keyto avoid potential Lua closure scoping issues in the loop. - "None" button on milestone rows widened to 70 px (was 56 px) so the full label renders without truncation.
- Minimap tooltip Forces line now respects the selected Forces display mode (was hardcoded to 1 decimal).
[1.0.4] - 2026-05-07
Added
- Column headers ("On", "Forces %", "Label", "Alerts") above the milestone list, styled in gold with GameFontNormalSmall.
Fixed
- Truncated "P..." Play buttons in Alert Sound section widened to 60 px so "Play" renders fully.
- Truncated "..." All/None buttons on milestone rows widened (All → 50 px, None → 56 px).
- Play button OnClick now has an explicit fallback sound ID in case MK_GetSoundID returns nil.
/mk testand "Test Alert" button now usealertType = "sound_chat_frame"so the on-screen alert frame fires during tests (wassound_chat, which suppressed the frame).- Nominal forces mode now renders correctly during
/mk test: when quantity/total are unavailable, derives stand-in values from the current % (e.g. "42/100 forces") instead of silently falling back to percentage format.
[1.0.3] - 2026-05-07
Added
- Milestone rows now have independent Sound / Chat / Frame checkboxes instead of a single dropdown, with All and None buttons for quick selection.
- Forces display options: configurable decimal places (0, 1, or 2) and a "Nominal forces" mode (e.g. 382/450 instead of 84.9%).
- Hover tooltips on all Settings options for extra context.
Fixed
- "Calculate & Add" (MDT route import) now immediately updates the Milestones list without requiring the panel to be closed and reopened.
- Sound preview "Play" buttons now render correctly (replaced unrenderable UTF-8 glyph).
[1.0.2] - 2026-05-07
Fixed
- Milestone rows: alert type dropdown replaced with Sound/Chat/Frame checkboxes.
- Alert type now stored as a substring-based string, backward-compatible with existing saved data.
[1.0.1] - 2026-05-07
Fixed
- MDT route import now correctly reads saved routes.
- Routes are stored in
MDT.db.global.presets(notprofile.routes). - Pull data accessed from
preset.value.pullswith the correct flat[enemyIdx] = {cloneIdx, ...}structure. - Active preset resolved via
MDT.db.global.currentPreset.
- Routes are stored in
- MDT Route Import dropdown now shows "Select a dungeon profile above to load MDT routes" when the global profile is active, instead of silently showing no routes.
[1.0.0] - 2026-05-06
Added
- Core enemy forces tracking with milestone alerts (sound, chat, on-screen frame).
- Per-dungeon milestone profiles.
- Minimap button (LibDBIcon).
- Party sync — broadcasts milestone hits to party chat via
MKSYNV1prefix. - MDT route integration — calculate forces % at any pull and add it as a milestone.
- MDT predictive alerts — warns in chat when the next pull will cross a milestone threshold.
/mkto open config,/mk testto fire a test alert.
This mod has no additional files