acdream/docs/research/2026-06-26-character-window-retail-reference.md
Erik e264d8392f docs(CT): CT1 fix round — sealed RowHighlightSprite verdict, verified resize mechanism, strengthened pins
Applies the Opus dual-lens review corrections to CT1's DAT ground-truth
research (docs/research/2026-08-24-campaign-ct-dat-ground-truth.md):

- Window constraints (BLOCKER): replaced the "likely a hardcoded
  ResizeTo/SetMinSize" guess with the verified mechanism —
  UIElement::ResizeTo clamps only via element attributes 0x3C-0x3F,
  nothing writes them at runtime, and retail resizes the SHARED
  gmPanelUI host (LayoutDesc 0x2100006E, slot 0x1000018E) rather than
  0x2100002E's own content root. Flags the unresolved 300x600-vs-300x362
  size tension for CT3/CT6 and marks the host elements NOT PROBED by
  CT1.
- RowHighlightSprite upgraded from a flagged hedge to a SEALED VERDICT:
  the stat row's selected-state media is 0x06000F93
  (gmAttributeUI::UpdateSelection -> InfoRegion::SetState on template
  0x10000248), not 0x06001397 (which is legitimately the spellbook
  row's separate selected-overlay mechanism). Falsifies the matching
  comment in CharacterStatController.cs and dated-corrects the older
  2026-06-26 doc at the spot that originated the wrong sprite id.
- Replaced the "18px gutter + 7px = 25px" derived story with the bare
  authored rectangles (the numbers don't compose cleanly: 300-281=19,
  and the 282px row overlaps the 281px scrollbar band by 1px) — CT5
  must implement the authored numbers directly, never a derived
  listWidth-18 formula.
- Plan doc: corrected the UpdateButtons ghost rule (no selection ->
  Ghosted, not "ghosts when selected == current") and added the
  AddTitleToList row-write contract for CT3.
- Pins: CharacterPanelLiveDatTests now honors ACDREAM_DAT_DIR first
  (matching InstalledDatFactAttribute and its sibling live-DAT test
  classes), hoists five vacuous bare-foreach assertions to counted
  .ToList() pins, and adds the stat ListBox + scrollbar rect pins that
  CT5/CT6 depend on.
- Doc hygiene: marked several probe-session observations (header
  geometry "identical" claim, 0x06004CC2 characterization, the
  master-map/category-map dump) as unpinned inference vs. committed
  fact, corrected the 0x1000052D "throwaway container" mislabel, and
  stated the header table's parent-relative coordinate frame.
- Recorded the CT5 gold this round found: InfoRegion::InfoRegion's
  icon-DID lookup (a third GetDIDByEnum consumer, category
  0x10000002) and gmSkillUI::RebuildSkillList's section-header order
  confirmation, plus the RowHeight=22-vs-authored-20 divergence for
  attribute rows.

Verified: ACDREAM_RUN_INSTALLED_DAT_TESTS=1 CharacterPanelLiveDatTests
filter 9/9 green; hermetic App suite filter (CI's Lane exclusion list)
6111/6111 green. No production code changed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 21:58:27 +02:00

4.1 KiB

Character window (Attributes tab) — retail reference + polish targets

Transcribed from two user-provided retail screenshots (2026-06-26): the not-selected state and the Strength-selected state. The PNGs live in the user's chat; this doc is the durable target spec for the remaining polish on acdream's CharacterStatController (LayoutDesc 0x2100002E). "✗" = acdream gap.

State 1 — nothing selected

  • Tabs: Attributes (active, gold label), Skills, Titles.
  • Name: "Horan" — WHITE (✗ acdream renders the name gold).
  • Heritage line: "Female Aluvian Adventurer" — white.
  • PK line: "Non-Player Killer" — white.
  • Level area (right): small caption "Character Level" (two lines: "Character" / "Level"), then the number "240" as LARGE GOLD SPRITE DIGITS — a number-sprite font, not plain text (✗ acdream draws "126" as plain gold text, and the caption truncates to "Character Le").
  • "Total Experience (XP):" caption + value "100,000,017,999" (✗ caption missing in acdream).
  • "XP for next level:" caption + value "99,738,801" with the red fill bar behind it (✗ caption + value missing — the value element is consumed by the UiMeter at import).
  • Attribute list — 9 rows, each = icon + name + right-aligned value:
    • Row text is LARGER (roughly the icon height ~24px) and rows are TIGHTER (less vertical gap) than acdream's current small-text / wide-spacing.
    • Order: Strength 200, Endurance 10, Coordination 10, Quickness 200, Focus 10, Self 10, Health 5/5, Stamina 10/10, Mana 10/10.
  • Footer: "Select an Attribute to Improve" (title) / "Skill Credits Available: 96" / "Unassigned Experience: 87,757,321,741". (acdream now matches — confirm the title says Attribute, not skill.)

State 2 — Strength selected

  • Same header.

  • Selected row (Strength): highlighted with a DARKER background + bars above/below — retail's selected-row sprite 0x06001397 (Button state 6). (✗ acdream uses a translucent GOLD tint — replace with the dark-bar sprite.)

    CORRECTION 2026-08-24 (Campaign CT, CT1 fix round). The sprite id above is WRONG for this element. Campaign CT's live-DAT probe (docs/research/2026-08-24-campaign-ct-dat-ground-truth.md, §2 "SEALED VERDICT") found the attribute/skill row's actual Highlight media is 0x06000F93, drawn via gmAttributeUI::UpdateSelection @0x0049DEE0's SetState(6)InfoRegion::SetState @0x004F0EE0 on the row template 0x10000248 itself. 0x06001397 is real, but it belongs to a DIFFERENT mechanism: the spellbook row's separate selected-overlay child element (0x10000342 under prototype 0x10000343, via UIElement_UIItem::SetSelectedState @0x004E1240). This note's "Button state 6" framing was accidentally right about the STATE number but wrong about which sprite that state resolves to on this element. CT5 is the owning slice for the fix.

  • Footer flips to:

    • Title: "Strength: 200"WHITE text (✗ acdream uses the body/gold color).
    • "Experience To Raise:" + "Infinity!" (Strength is maxed → cost is infinite; ✗ acdream shows a numeric/"maxed" placeholder — show "Infinity!" when the attribute is at max).
    • "Unassigned Experience:" + "87,757,321,741".
  • Raise buttons (≜10 + triangle) shown at the selected row's right.

Polish checklist (acdream)

  1. Name color → white.
  2. Level → gold sprite digits (find the number-sprite font/ids); caption "Character"/"Level" 2-line.
  3. Add "Total Experience (XP):" caption.
  4. Add "XP for next level:" caption + value (un-consume from the meter, or render alongside).
  5. Row text larger (≈icon height) + rows tighter.
  6. Selection highlight → sprite 0x06000F93 (dark bars), not gold tint. (Corrected 2026-08-24 — see the CORRECTION note above; the sprite id in this checklist item was originally 0x06001397.)
  7. Selected footer title → white.
  8. Maxed attribute → "Experience To Raise: Infinity!".
  9. Footer title wording = "Select an Attribute to Improve" (Attribute).