Skip to content

Arena: don't hide late-loading teammates (incomplete-nameList fallback)#155

Open
Krathe82 wants to merge 2 commits into
DanderBot:mainfrom
Krathe82:pr/arena-late-join-frames
Open

Arena: don't hide late-loading teammates (incomplete-nameList fallback)#155
Krathe82 wants to merge 2 commits into
DanderBot:mainfrom
Krathe82:pr/arena-late-join-frames

Conversation

@Krathe82

Copy link
Copy Markdown
Contributor

Live + alpha reports: in non-rated arenas, zoning in early and having the last teammate join a bit later leaves their frame missing for the whole round (joining last yourself is always fine); often described as "first round of every arena, 1-2 players missing", and a mid-match /reload can leave the sort wrong afterwards.

Root cause: with sorting on and Self Position First/Last (the default), the arena header runs in NAMELIST mode. A teammate can exist before their name resolves (UnitName returns nil/UNKNOWNOBJECT while they load in — exactly the trickle-in pattern of non-rated queues). A nameList built in that window omits or mis-names them, so the secure header filters their frame out — and nothing repairs it: name resolution fires no GROUP_ROSTER_UPDATE, and once the gates open, combat blocks header attribute writes for the rest of the round. Joining last is fine because everyone else's names resolved long ago; solo shuffle is unaffected because FrameSort owns arena sorting when active.

Fix:

  • BuildArenaNameList now reports completeness; an unresolved member is omitted rather than added as a literal "Unknown" (which could never match their real name).
  • On an incomplete build, ApplyArenaHeaderSorting shows everyone in INDEX order instead of applying a filtering nameList — unsorted beats missing — and a capped 0.5s retry loop re-sorts once names resolve. UNIT_NAME_UPDATE nudges the retry too (gated on the incomplete flag), with the timer as primary since that event is unreliable.
  • ApplyArenaHeaderSorting's combat early-return now queues pendingSortingUpdate instead of silently dropping — an arena round's combat lasts minutes, so e.g. a post-/reload apply mid-round previously vanished, leaving the header unsorted (the "sort is screwed after reloading" half of the report).

Worst case under the fix is a few seconds of unsorted-but-complete frames during prep, then correct sorting.

@Krathe82

Copy link
Copy Markdown
Contributor Author

Follow-up commit from a deep audit of the arena population/sorting pipeline against Blizzard's SecureGroupHeaders.lua:

  • Roster-sourced nameLists: for raid-kind units (arena = raid1-5), the secure header matches nameList tokens against GetRaidRosterInfo names, not UnitName — and the roster usually knows a late-joiner's name before their player object loads. BuildArenaNameList now builds from the roster, so in the common late-join case the list is complete and matchable immediately: frames appear sorted right away, with the INDEX fallback from the first commit kept as the safety net for true roster gaps.
  • FrameSort integration: SortArenaFrames had the same late-join hole this PR fixes natively (an unloaded teammate's name was skipped or inserted as a literal "Unknown" token — frame filtered out for the whole round). It now uses roster names, falls back to INDEX on an incomplete roster, and hooks into the shared retry/nudge machinery via the new DF:SetArenaSortIncomplete. The retry is FrameSort-aware: it re-requests FrameSort's order instead of calling ApplyArenaHeaderSorting (which would just yield and clear to INDEX).
  • A UNIT_NAME_UPDATE nudge now re-arms the retry safety cap, so a player loading slower than the ~12s window still gets re-sorted.

Krathe82 added 2 commits June 13, 2026 11:24
Live + alpha reports: in non-rated arenas, when you zone in early and the
last teammate joins a bit later, their frame never appears for the whole
round (joining last yourself is always fine); often "the first round of
every arena, 1-2 players missing", and a mid-match /reload can leave the
sort wrong.

Root cause: with sorting on and Self Position FIRST/LAST (the default), the
arena header runs in NAMELIST mode. A teammate can EXIST before their name
RESOLVES (UnitName returns nil/UNKNOWNOBJECT while they load in - exactly
the trickle-in pattern of non-rated queues). The nameList built in that
window omits (or mis-names) them, so the secure header filters their frame
out - and NOTHING repairs it: name resolution fires no GROUP_ROSTER_UPDATE,
and once the gates open, combat blocks header attribute writes for the rest
of the round. Joining last is fine because everyone else's name resolved
long ago.

Fix:
- BuildArenaNameList now reports completeness; an unresolved member is
  omitted (a literal "Unknown" entry could never match their real name).
- On an INCOMPLETE build, ApplyArenaHeaderSorting shows EVERYONE in INDEX
  order instead of applying a filtering nameList (unsorted beats missing),
  and a capped 0.5s retry loop re-sorts once names resolve. UNIT_NAME_UPDATE
  nudges the retry too (gated on the incomplete flag; that event is
  unreliable, hence the timer as primary).
- ApplyArenaHeaderSorting's combat early-return now queues
  pendingSortingUpdate instead of silently dropping (an arena round's combat
  lasts minutes - e.g. a post-/reload apply mid-round previously vanished,
  leaving the header unsorted: the "sort is screwed after reloading" half of
  the report).
Follow-up hardening of the arena late-join fix, from a full audit of the
arena population/sorting pipeline against Blizzard's SecureGroupHeaders.lua:

- BuildArenaNameList now sources names from GetRaidRosterInfo instead of
  UnitName. For raid-kind units (arena = raid1-5), the secure header matches
  nameList tokens against GetRaidRosterInfo names, and the roster usually
  knows a late-joiner's name BEFORE their player object loads. Result: a
  complete, matchable nameList immediately in the common late-join case --
  frames appear sorted right away instead of unsorted INDEX order until
  names resolve. The INDEX fallback remains for true roster gaps.

- FrameSort integration: SortArenaFrames had none of the late-join
  protections -- an unloaded teammate's name was either skipped (nil) or
  inserted as a literal "Unknown" token, filtering their frame out for the
  whole round. It now resolves names via GetRaidRosterInfo, falls back to
  INDEX (show everyone) on an incomplete roster, and hooks into the shared
  incomplete-state machinery (new DF:SetArenaSortIncomplete) so the 0.5s
  retry + UNIT_NAME_UPDATE nudge cover it too. The retry is FrameSort-aware:
  it re-requests FrameSort's order rather than calling
  ApplyArenaHeaderSorting (which would just yield and clear to INDEX).

- Retry cap: a UNIT_NAME_UPDATE nudge now re-arms the ~12s safety cap, so a
  player who loads in slower than the retry window still gets re-sorted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant