Repository navigation
Releases: lxhwes/LegacyNext
Release list
v0.1.0-beta2
Changelog
All notable changes to LegacyNext are recorded here. The format follows
Keep a Changelog, and the version numbers follow
Semantic Versioning as described under Versioning below.
LegacyNext targets the World of Warcraft: Forever beta, interface 16001. Each release names the
client build it was verified against.
Unreleased
0.1.0-beta2 - 2026-10-02
Built against client build 1.60.1 (70170). Nothing new in this release has been seen in game
yet, and each entry says so.
Added
- The window can be resized from its bottom-right corner, and keeps its size for each
character. Not yet seen in game. - Click a challenge row to open Blizzard's Legacy panel on that challenge, or shift-click it to
link the challenge in chat. Not yet seen in game. - A minimap button. Left-click opens the window, right-click opens the settings, and dragging
moves it round the minimap's edge. Its tooltip shows the reward track, this character's
unspent points and the three challenges closest to done./lgn minimapshows or hides it.
Hovering LegacyNext in the minimap's addon dropdown shows the same tooltip.
Not yet seen in game. - A settings page under Options > AddOns > LegacyNext, with toggles to show and to lock the
minimap button./lgn configopens it. Not yet seen in game.
Changed
- The roster keys each character by its GUID, so a name change between builds no longer splits
one character into two rows. A character saved underName-Realmmoves to its GUID the next
time it logs in./lgn roster forgettakes aName-Realmor a stored key. Not yet run in
game.
0.1.0-beta1 - 2026-10-02
Verified against client build 1.60.1 (70170).
Added
- The window remembers its tab, category filter and position for each character.
- Blizzard's top tabs for Next Up and Roster, so the selected one stands out.
- Achievement icons on Next Up and tradeskill rows, and the next reward's icon in the header.
- Roster names in class colours, with the current character tinted.
- Tagged releases: a pushed
v*tag is linted, tested and packaged into a GitHub release, and
the tag becomes## Version. A copy straight from the repo reports its version asdev. - Roster tab (v1): the window has a second tab listing every saved character with Legacy points
spent per tree and points unspent, then each tradeskill challenge a saved character has the
profession for, closest character first. Next Up's tooltip on a tradeskill row names the saved
characters with that profession./lgn uidump rosterprints the tab as text. - Roster groundwork (v1): each character's class, level, professions and Legacy tree spend is
saved at login and after a level-up, skill or talent change. The game does not return
professions or tree spend at logout, so a logout snapshot keeps the stored ones./lgn roster
lists every saved character and, for each tradeskill challenge, which of them is closest.
/lgn roster forget <Name-Realm>removes a deleted character. /lgnand/legacynextopen the Next Up window: incomplete Legacy challenges ranked by
closeness to completion. Each row shows the name, category, points awarded and criteria
remaining./lgn helplists the commands.- Category filter over the game's own Legacy categories.
- Reward track header: current Legacy points, points to the next reward, and that reward's name.
- Challenge ranking (
Model/) in three tiers, each under its own divider: in progress (sorted
by closeness), not started (the game's category order), and no progress shown. Closeness
reads criterion quantities wheneverneed > 1, so a 0/42000 reputation criterion is not
scored as one step from done. Zero-point challenges are excluded. Challenges with no
measurable criteria sit in the last tier rather than at 0%. - Other classes' challenges are hidden for the current character, with a line saying how many.
They are matched by structure against the character's class name, and nothing is hidden if
that fails to match. - Reward-track summary (
Model/): current level, next threshold and reward name from the
sparse renown level list. - Guarded client read layer (
Api/). Every call is feature-detected,pcalled and checked with
issecretvalue, and returns plain tables ornilplus a reason. Covers challenges, the
reward track, tree spend and character state. A struct with one uncopyable field is kept
and the field named, rather than dropped whole. /lgn probe: one line per client API reportingok,nil,missing,error,secretor
skipped./lgn dump [section] [page]: a copyable Lua literal of everythingApi/returns, shown in a
window you can select from. Sections:all,summary,challenges,categories,rewards,
trees,character,probe./lgn uidump [category]: the window's contents as text, for checking what would render
without a screenshot.- Addon icon in the AddOns list (
Media/icon.tga, original art; seedocs/icon-design.md). - Escape closes the window. It refreshes on open, on
ACHIEVEMENT_EARNEDwithin a second and
onCRITERIA_UPDATEat most every five seconds while open, and defers any rebuild,
including the first on open, until combat ends. A read that throws shows as the window's
error state instead of a Lua error. - A key binding to open and close the window, under Key Bindings > AddOns.
- LegacyNext sits under Achievements in the AddOns list.
Versioning
SemVer 0.x.y while Forever is in beta; 1.0.0 is the release that targets Forever's launch
build on 2026-11-04. The client build is not encoded in the version string. One addon version
is expected to outlive several beta builds, so each release entry names the build it was
verified against instead. LegacyNext.toc carries ## Version: v0.1.0-beta2, which
the packager replaces with the git tag at build time, so the tag is the version. Beta builds
are tagged -betaN and upload to CurseForge as beta releases. The first upload was
v0.1.0-beta1.
v0.1.0-beta1
LegacyNext
v0.1.0-beta1 (2026-10-02)
Full Changelog Previous Releases
- chore(toc): add the CurseForge project ID
- docs(status): add the resizable window to the release backlog
- docs(claude): split the project ID fact out of the retail API bullet
- docs: close D10, U2, U5, U6 and U7, and record C2 in part
- test(model): rank Geo's captured Alchemy progress, closing C3
- Merge pull request #6 from lxhwes/feat/addon-compartment
feat(ui): open the window from the minimap addon compartment - chore(merge): bring the window polish into the addon compartment branch
Docs only: the queue keeps U5, U7 and U6, and status lists all three as not
blocking under the polish-pass section. 263 tests, none pending. - Merge pull request #8 from lxhwes/feat/toc-category-keybinding
Add a toggle key binding and an AddOns-list category - Merge pull request #9 from lxhwes/feat/ui-tab-state
Polish the window: top tabs, icons, class colours, remembered state - docs(ui): note the key binding citations hold at the 70170 pin
- chore(merge): bring the 70170 re-pin into the window polish branch
The queue keeps main's 70170 D10 row and heading plus this branch's U6. The
polish citations hold at 9a789c0: none of the cited files changed. - chore(merge): bring the updated addon compartment branch into this one
No conflicts. Picks up main's 70170 re-pin through PR #6. - chore(merge): bring the 70170 re-pin into the addon compartment branch
- PINS.md lists six directories outside the checkout: this branch's
Blizzard_Minimap and main's Blizzard_ProfessionsTemplates. The 70170 diff
does not touch Blizzard_Minimap, so the compartment citations hold - status.md and the queue keep main's 70170 text plus this branch's U5
- PINS.md lists six directories outside the checkout: this branch's
- Merge pull request #7 from lxhwes/chore/pin-70170
chore(vendor): re-pin forever branch to 1.60.1.70170 - docs: record the key binding and AddOns category, queue U7
- ui-templates.md: Bindings.xml loading, the label and section globals, and
where the AddOns list reads Category - Queue U7, a status note under the minimap entry, and two CHANGELOG lines
- ui-templates.md: Bindings.xml loading, the label and section globals, and
- docs: record the polish pass and queue U6 for its look
- ui-templates.md section 7: the top tab, its helpers and class colours, with
the evidence that the tab file loads on Forever - read_globals for the tab helpers and the class colour tables
- Status and CHANGELOG entries; U6 asks for the uidump, two screenshots and a
reload and relog
- ui-templates.md section 7: the top tab, its helpers and class colours, with
- feat(model): add row and header icons and roster class tokens
- test(model): expect icons on rows and header, class token on roster
- feat(core): group in the AddOns list and add a toggle key binding
-
Category: Achievements; the AddOns list groups on that exact string
- Bindings.xml adds LEGACYNEXT_TOGGLE under Key Bindings > AddOns; it
calls LegacyNext_Toggle, a global in Core.lua, which toggles like /lgn - BINDING_NAME_LEGACYNEXT_TOGGLE labels the row. No header attribute:
at 966519c a header row draws as a blank spacer, not text - Read from source at 966519c only; needs an in-game check
-
- test(core): pin the TOC category and the toggle key binding
- The TOC carries ## Category: Achievements
- Bindings.xml holds one ADDONS binding whose BINDING_NAME_ label Core
defines, and running its Lua opens then closes the window - All three fail until the feat commit; the other 208 pass
- chore(merge): bring main into the addon compartment branch
Conflicts were in docs only. The queue and status take main's closed S1, D4,
U1, U3 and U4, plus this branch's U5 row, section and minimap entry note.
223 tests, none pending. - feat(ui): draw row icons, the reward icon and class colours
- row.icon left of Next Up and tradeskill names; their names keep one
indent when any row has an icon, and none when no row does - header.icon before header line 2
- character names in class colour from RAID_CLASS_COLORS, then
C_ClassColor, as a colour escape; a coloured current character gets a
faint gold row tint, an uncoloured one stays gold as before - icon, colour and tint are reset on every draw of a pooled row
- row.icon left of Next Up and tradeskill names; their names keep one
- test(ui): draw row icons, the reward icon and class colours
Fails until UI draws row.icon, header.icon and row.classToken from
hand-built views, tints the current character, and resets all three on
pooled rows. - feat(ui): draw the tabs with Blizzard's top tab template
- PanelTopTabButtonTemplate with PanelTemplates_SelectTab/DeselectTab,
as Forever's own FriendsFrame uses the tab family; the tab sizes from
its text and hangs off the one before - Without the template or helpers, the panel button gains a gold
underline under the selected tab - /lgn uidump reports which one was used as tabTemplate
- PanelTopTabButtonTemplate with PanelTemplates_SelectTab/DeselectTab,
- test(ui): mark the selected tab clearly
Fails until the tabs use PanelTopTabButtonTemplate with its select
helpers, falling back to the panel button with a gold underline. - feat(ui): remember tab, filter and position per character
- Store: GetUIState/PutUIState keep window state in LegacyNextCharDB.ui,
additive, with no schema field and no change to LegacyNextDB - UI: restore on first build, save on tab change, filter change and drag
stop; the position is clamped onto the screen, centred when unusable
- Store: GetUIState/PutUIState keep window state in LegacyNextCharDB.ui,
- test(ui): remember tab, filter and position per character
Fails until Store keeps window state in LegacyNextCharDB and UI restores
it on first build. Covers a stale filter id, clamping and an unusable
saved position. - docs: fix U5's button and the compartment citations
- U5 points under the calendar, where AddonCompartment.xml anchors the
button, not the clock; a failed icon is a green square or blank - Cite AddonCompartment.lua:99 for the call, not :98
- List Blizzard_Minimap in PINS.md's outside-the-checkout set
- Record the 16 px compartment draw in icon-design.md
- Name the dropdown and its all-characters catch in README.md
- Drop the S1 caveat from CLAUDE.md; status.md already holds it
- U5 points under the calendar, where AddonCompartment.xml anchors the
- test(core): clear the compartment global in the shared teardown
- chore(vendor): merge main's S1 results into the 70170 re-pin
- chore(vendor): re-pin forever branch to 1.60.1.70170
- Move the pin from 966519c to 9a789c0; no constant, signature or API doc on our surface changed
- Re-derive citations shifted by six Blizzard_LegacySystem edits and the professions refactor
- Record the excludeStagedChanges flip and the zero-point gate on ToggleLegacySystemUI
- Retarget D10 at 70170
- feat(ui): open the window from the minimap addon compartment
-
AddonCompartmentFunc names LegacyNext_OnAddonCompartmentClick, a
global in Core.lua; any click toggles the window like /lgn - Lifecycle tests read the name from the TOC and check it toggles; both
failed before the change. Test and code share one commit so no commit
has a failing suite - U5 queues the in-game check; the compartment on Forever is read from
source at 966519c only
-
- Merge pull request #5 from lxhwes/test/s1-roster-capture
Close S1 from in-game captures, and probe Forever surnames - docs: record the PR #5 review and correct three stale passages
- CLAUDE.md: the no-secrets claim excludes the unprobed name calls,
and the join paragraph no longer gives two opposite rules - ingame-commands: U2 expects what v2 already showed; D10 says the
name rows print every return - status: PR #5 review section, 221 tests
- CLAUDE.md: the no-secrets claim excludes the unprobed name calls,
- test(debug): compare U4's STATE block and footnote wording
The U4 test stopped at ROWS. It now compares through the end of STATE
except the note line, whose count of 15 needs tradeskill challenges
never captured, and checks the note's wording separately using Bong's
captured snapshot, with the count left out. - test(api): check the S1 parent map against raw client fields
The test compared Api.GetSkillLineParents with parentsLive, which Api
itself produced in game, so it was circular. It now checks each
derived field against the raw struct. Also moves the S1 provenance
comment onto the roster_geo test it describes. - fix(core): hold the session snapshot log to Store's limit
- Core kept every skill-up for the whole session; it now keeps the
login result and the latest up to Store.LOG_LIMIT, counting the rest - The renderer no longer skips lines itself, which removes the
off-by-one at LIMIT + 1 and the duplicated LOG_SHOWN - The saved log from earlier sessions shows in full, newest included
- Core kept every skill-up for the whole session; it now keeps the
- fix(api): print every return on the probe's name rows
status() printed only the first return, so D10's paste would show
neither UnitFullName's realm nor a surname UnitName or
UnitNameUnmodified put second. The three name rows now go through
statusAll; every other probe row is unchanged. - docs: record U2: unprotected frame, templates present, clipped widths
- IsProtected false,false and both ScrollBox templates verified on 70124
- A clipped string reads IsTruncated true but GetStringWidth equals its full
width, so only IsTruncated detects clipping - U2 stays open for one look: whether the clipped string ends in ...
- docs(ingame): make U2 guard each step and write...