docs(ui): pin retained widget retail oracles
This commit is contained in:
parent
5931a820ea
commit
44f9ec13d9
10 changed files with 2753 additions and 73 deletions
|
|
@ -43,9 +43,9 @@ when the named decomp lacks a body.
|
|||
already contains the retail node. Runtime-created nodes are allowed only when
|
||||
retail creates them dynamically and the code cites that method.
|
||||
6. **Typed behavior, not stringly behavior.** State names remain DAT data, but C#
|
||||
policy uses enums/records (`UiTextInteractionMode`, button phase, cursor role,
|
||||
shortcut kind, window event). Controllers must not implement precedence by
|
||||
scattered state-name string lists.
|
||||
policy uses typed capabilities/records (independent text `Editable` and
|
||||
`Selectable` flags, button phase, cursor role, shortcut kind, window event).
|
||||
Controllers must not implement precedence by scattered state-name string lists.
|
||||
7. **Controllers have lifetimes.** Every subscribing controller implements
|
||||
`IDisposable`; subscriptions use removable named handlers or a small
|
||||
`SubscriptionBag`. `RetailUiRuntime.Dispose` tears down the complete tree.
|
||||
|
|
@ -106,32 +106,32 @@ This wave changes no runtime behavior.
|
|||
|
||||
### 0.1 Consolidate missing retail pseudocode
|
||||
|
||||
- [ ] Write focused pseudocode notes for:
|
||||
- [x] Write focused pseudocode notes for:
|
||||
- `UIElement_Text` interaction/property modes;
|
||||
- `UIElement_Button::UpdateState_`, mouse transitions, enabled/toggle behavior;
|
||||
- `UIElement::UpdateForParentSizeChange` raw edge modes 0-4;
|
||||
- Device timer delivery and focus notifications;
|
||||
- UI manager tooltip deadlines, global time delivery, and focus notifications;
|
||||
- `gmToolbarUI` global messages, drop branches, mana/stack behavior;
|
||||
- `ItemHolder::UseObject` / `AttemptPlaceIn3D` decision trees;
|
||||
- chat maximize, alpha, tabs, talk-focus and squelch;
|
||||
- paperdoll priority, Aetheria, hit testing and race updates;
|
||||
- character titles, luminance, and raise acknowledgement.
|
||||
- [ ] Correct the roadmap premise around shortcuts: `ShortCutData` is
|
||||
- [x] Correct the roadmap premise around shortcuts: `ShortCutData` is
|
||||
`index_`, `objectID_`, `spellID_`, while `PlayerModule::favorite_spells_[8]`
|
||||
is a separate subsystem. This retail toolbar restores only nonzero
|
||||
`objectID_`; it must not grow invented spell-slot behavior.
|
||||
- [ ] Pin every method address and DAT property id before implementation.
|
||||
- [x] Pin every method address and DAT property id before implementation.
|
||||
|
||||
### 0.2 Expand committed DAT conformance fixtures
|
||||
|
||||
- [ ] Add skip-by-default generators and committed `ElementInfo` JSON fixtures for
|
||||
- [x] Add skip-by-default generators and committed `ElementInfo` JSON fixtures for
|
||||
toolbar `0x21000016`, inventory `0x21000023` plus mounted sublayouts,
|
||||
paperdoll `0x21000024`, and character `0x2100002E`.
|
||||
- [ ] Include state media, cursor media, font ids, raw edge modes, default state,
|
||||
- [x] Include state media, cursor media, font ids, raw edge modes, default state,
|
||||
min/max attributes, numeric state ids, and runtime-relevant scalar/property arrays.
|
||||
- [ ] Add inheritance cases proving derived explicit `false` and `0` override base
|
||||
- [x] Add inheritance cases proving derived explicit `false` and `0` override base
|
||||
values rather than being mistaken for absence.
|
||||
- [ ] Add fixture assertions for every required controller role.
|
||||
- [x] Add fixture assertions for every required controller role.
|
||||
|
||||
### 0.3 Repair the audit trail
|
||||
|
||||
|
|
@ -148,34 +148,35 @@ This wave changes no runtime behavior.
|
|||
|
||||
## 4. Wave 1 -- exact retained-widget foundation
|
||||
|
||||
### 1.1 Give Type-12 text an explicit interaction mode
|
||||
### 1.1 Give Type-12 text independent retail capabilities
|
||||
|
||||
- [ ] Add `UiTextInteractionMode { Display, Selectable, Editable }`; default to
|
||||
`Display` for factory-imported DAT text.
|
||||
- [ ] Import retail Editable `0x16`, OneLine `0x20`, and Selectable `0x27` properties
|
||||
- [x] Default factory-imported DAT text to display-only behavior. Model Editable
|
||||
`0x16` and Selectable `0x27` as independent capabilities, matching retail; do
|
||||
not collapse them into an exclusive interaction-mode enum.
|
||||
- [x] Import retail Editable `0x16`, OneLine `0x20`, and Selectable `0x27` properties
|
||||
through the typed property bag where the DAT supplies them.
|
||||
- [ ] Make focus, key capture, selection, clipboard, and pointer-drag behavior derive
|
||||
exclusively from this mode.
|
||||
- [ ] Set the chat transcript to `Selectable`; keep the chat input explicitly
|
||||
- [x] Make focus, key capture, selection, clipboard, and pointer-drag behavior derive
|
||||
exclusively from those capabilities.
|
||||
- [x] Set the chat transcript to `Selectable`; keep the chat input explicitly
|
||||
`Editable`; all labels remain `Display`.
|
||||
- [ ] Bind the imported vitals labels `0x100000EB/ED/EF` directly and delete the
|
||||
- [x] Bind the imported vitals labels `0x100000EB/ED/EF` directly and delete the
|
||||
synthesized duplicates.
|
||||
- [ ] Add tests proving display labels cannot steal focus, capture, or window drag.
|
||||
- [x] Add tests proving display labels cannot steal focus, capture, or window drag.
|
||||
|
||||
**Oracle:** `UIElement_Text::OnSetAttribute @ 0x0046A640`, mouse/key methods
|
||||
`0x00469370..0x0046A4A0`, `gmVitalsUI::PostInit @ 0x004BFCE0`.
|
||||
|
||||
### 1.2 Port the button state machine
|
||||
|
||||
- [ ] Extract a GL-free `UiButtonStateMachine` over enabled/hovered/pressed/
|
||||
- [x] Extract a GL-free `UiButtonStateMachine` over enabled/hovered/pressed/
|
||||
captured/toggled state and available DAT states.
|
||||
- [ ] Port retail transition precedence exactly; controller code supplies semantic
|
||||
- [x] Port retail transition precedence exactly; controller code supplies semantic
|
||||
click/toggle callbacks only.
|
||||
- [ ] Preserve retail state ids `1/2/3`, selected `6/7/8`, and ghosted `13`; if the
|
||||
- [x] Preserve retail state ids `1/2/3`, selected `6/7/8`, and ghosted `13`; if the
|
||||
requested state is absent, retain the current custom semantic state rather than
|
||||
overwriting states such as `Maximized`, `Minimized`, or radar lock.
|
||||
- [ ] Make cursor media follow the active button state.
|
||||
- [ ] Cover normal, rollover, pressed, released-outside, disabled, toggle-on/off,
|
||||
- [x] Make cursor media follow the active button state.
|
||||
- [x] Cover normal, rollover, pressed, released-outside, disabled, toggle-on/off,
|
||||
and capture-loss tests using real fixture state names.
|
||||
|
||||
**Oracle:** `UIElement_Button::UpdateState_ @ 0x00471CF0`, `MouseDown
|
||||
|
|
@ -183,33 +184,35 @@ This wave changes no runtime behavior.
|
|||
|
||||
### 1.3 Replace lossy anchors with the retail layout policy
|
||||
|
||||
- [ ] Introduce `UiLayoutPolicy` containing the five raw edge modes `0..4`, original child
|
||||
- [x] Introduce `UiLayoutPolicy` containing the five raw edge modes `0..4`, original child
|
||||
rect, and original parent rect. Preserve raw modes through `ElementReader`.
|
||||
- [ ] Port `UpdateForParentSizeChange` as a pure function, including right-track,
|
||||
- [x] Port `UpdateForParentSizeChange` as a pure function, including right-track,
|
||||
center mode `3`, proportional mode `4`, and inclusive-pixel behavior for all four
|
||||
edges.
|
||||
- [ ] Keep `AnchorEdges` only as a compatibility adapter for programmatic widgets;
|
||||
- [x] Keep `AnchorEdges` only as a compatibility adapter for programmatic widgets;
|
||||
imported DAT elements use `UiLayoutPolicy` directly.
|
||||
- [ ] Test every raw mode against hand-translated decomp vectors at 800x600,
|
||||
- [x] Test every raw mode against hand-translated decomp vectors at 800x600,
|
||||
widescreen, parent grow/shrink, and nested layouts.
|
||||
|
||||
**Oracle:** `UIElement::UpdateForParentSizeChange @ 0x00462640`.
|
||||
|
||||
### 1.4 Finish Device-level timing/focus behavior
|
||||
### 1.4 Finish UI-manager timing/focus behavior
|
||||
|
||||
- [ ] Drain registered timers from `UiRoot.Tick` in deterministic due-time/order.
|
||||
- [ ] Remove a timer before dispatch for reentrancy safety and cancel subtree timers
|
||||
when a window/widget is removed so stale callbacks cannot fire.
|
||||
- [ ] Add typed focus/capture/window events; eliminate polling where retail reacts to
|
||||
- [x] Poll the hovered element's tooltip deadline in `UiRoot.Tick`, then broadcast
|
||||
retail global time message `3` to listeners in deterministic tree order.
|
||||
- [x] Tear down focus, capture, modal ownership, hover, drag, default input, and
|
||||
window registration before a removed subtree can receive another time/input pulse.
|
||||
- [x] Add typed focus/capture transition behavior; eliminate polling where retail reacts to
|
||||
a transition.
|
||||
- [ ] Pin double-click, tooltip, capture-loss, modal, and timer ordering tests.
|
||||
- [x] Pin tooltip-before-global-time, capture-loss, modal, and subtree-removal
|
||||
ordering tests. Keep double-click coverage with the existing input suite.
|
||||
|
||||
### 1.5 Add a narrow DAT named-state bridge
|
||||
|
||||
- [ ] Bind imported named states such as `ShowDetail`, `HideDetail`, enabled/
|
||||
- [x] Bind imported named states such as `ShowDetail`, `HideDetail`, enabled/
|
||||
disabled button roles, and empty-cell art without globally re-registering Type 3
|
||||
elements or teaching controllers how the importer stores states.
|
||||
- [ ] Prove state changes preserve the imported rect, anchors, dimensions, and media
|
||||
- [x] Prove state changes preserve the imported rect, anchors, dimensions, and media
|
||||
using production LayoutDesc fixtures.
|
||||
|
||||
**Gate:** vitals/chat/radar/toolbar UI Studio fixtures unchanged visually; buttons
|
||||
|
|
@ -415,14 +418,19 @@ mana selections; full suite and user visual gate.
|
|||
bottom pinning, and restore behavior on the **outer frame**.
|
||||
- [ ] Drive alpha from focus/lifecycle events and retail timing, not a fixed `0.75`.
|
||||
|
||||
### 5.4 Implement tabs and filters
|
||||
### 5.4 Confirm the retail chat surface, then port its filters
|
||||
|
||||
The named `gmMainChatUI` build proves independently filtered chat/floaty windows;
|
||||
it does **not** prove that DAT elements `0x10000522..0x10000525` are an in-window
|
||||
numbered-tab model. Do not implement tab switching from the older inference.
|
||||
|
||||
- [ ] Confirm the role of `0x10000522..0x10000525` from live retail behavior or a
|
||||
stronger DAT/call-site trace before assigning tab semantics.
|
||||
- [ ] Add a Core/VM chat-line classification carrying retail message type/channel.
|
||||
- [ ] Implement numbered tab models, active tab, display masks, unread state and
|
||||
retail-backed persistence if the PlayerModule/options payload proves it. If the
|
||||
masks are not persisted by this build, register that fact instead of inventing a
|
||||
per-character format.
|
||||
- [ ] Route each transcript through its active filter without duplicating ChatLog.
|
||||
- [ ] Port the proven per-window display masks, unread state, and persistence only
|
||||
where the PlayerModule/options payload proves it; otherwise register the absence.
|
||||
- [ ] Route every retained/floating transcript through its filter without
|
||||
duplicating `ChatLog`.
|
||||
|
||||
### 5.5 Complete talk-focus and moderation actions
|
||||
|
||||
|
|
@ -447,10 +455,12 @@ visual gate.
|
|||
|
||||
## 9. Wave 6 -- inventory completion
|
||||
|
||||
- [ ] On inventory `Hidden/Closed`, have the controller send
|
||||
`NoLongerViewingContents` exactly once for the retail-eligible side/external
|
||||
container, clear the viewed-container and panel drag state, and restore main-pack
|
||||
presentation. Main-pack close sends nothing; repeated hiding is idempotent.
|
||||
- [ ] Split the owned inventory window from the external/ground-container window.
|
||||
The proven `ClientUISystem.groundObject` lifecycle sends
|
||||
`NoLongerViewingContents` exactly once when an external view is replaced or
|
||||
closed. Owned side-bag navigation/closing sends nothing unless a live packet
|
||||
trace proves otherwise. Both lifecycles clear their own panel drag/view state;
|
||||
repeated hide is idempotent.
|
||||
- [ ] Route grid/bag clicks through target mode and global `SelectionState`.
|
||||
- [ ] Retire capacity/burden fallbacks only after wire captures prove
|
||||
`ContainersCapacity`, `ItemsCapacity`, `EncumbranceVal`, and augmentation delivery.
|
||||
|
|
@ -516,12 +526,14 @@ user visual gate.
|
|||
|
||||
### 8.3 Reconcile stat raises
|
||||
|
||||
- [ ] Trace whether retail waits for authoritative state or predicts a raise before
|
||||
choosing the implementation. If it waits, remove optimistic mutation. If it
|
||||
predicts, add per-target pending snapshots for XP, credits, ranks, and advancement
|
||||
class, then confirm/rollback on the exact retail/ACE paths.
|
||||
- [ ] Test multiple in-flight raises, reordered echoes, rejection, caps, and relog/
|
||||
disconnect cleanup without retry loops.
|
||||
- [ ] Remove `ApplyLocalRaise`: named retail sends one request, ghosts the clicked
|
||||
button, and leaves XP/credits/ranks unchanged until the authoritative quality
|
||||
update arrives.
|
||||
- [ ] Permit only one raise request in flight; clear the awaiting/ghosted state on
|
||||
the matching authoritative quality-change path. Pin the exact rejection cleanup
|
||||
with a live ACE trace before adding any extra timeout or recovery behavior.
|
||||
- [ ] Test one-in-flight enforcement, authoritative acknowledgement, rejection,
|
||||
caps, and relog/disconnect cleanup without optimistic mutation or retry loops.
|
||||
|
||||
**Oracles:** `gmStatManagementUI`, `gmAttributeUI`, `gmSkillUI`,
|
||||
`gmCharacterTitleUI @ 0x0049A610`, `UpdateExperience @ 0x004F0A70`.
|
||||
|
|
@ -584,7 +596,7 @@ scenario, UI Studio fixture, live user visual gate, divergence cleanup.
|
|||
| Imported display text steals focus/drag; duplicate vitals labels | 1 |
|
||||
| Buttons lack automatic retail states | 1 |
|
||||
| Edge mode 3 recenter and mode 4 policy lost | 1 |
|
||||
| Device timers never fire | 1 |
|
||||
| Tooltip/global UI time ordering and removed-subtree cleanup | 1 |
|
||||
| Chat maximize changes content, not outer frame | 2 / 5 |
|
||||
| Only radar persists position; windows lack lifecycle | 2 |
|
||||
| Controller subscriptions are not disposed | 2 |
|
||||
|
|
@ -599,14 +611,14 @@ scenario, UI Studio fixture, live user visual gate, divergence cleanup.
|
|||
| Mana/stack selected-object behavior missing | 4 |
|
||||
| Vitals detail state missing | 5 |
|
||||
| Duplicate ChatVM lacks `/loc` and `/framerate` providers | 5 |
|
||||
| Chat tabs, opacity, channel availability, squelch/actions incomplete | 5 |
|
||||
| Chat filter windows, opacity, channel availability, squelch/actions incomplete; numbered-tab premise unproven | 5 |
|
||||
| Chat scrollbar arrows reversed | 2 / 5 |
|
||||
| Inventory close skips `NoLongerViewingContents` | 2 / 6 |
|
||||
| External-container close lifecycle missing; owned-side-bag `0x0195` premise disproved | 2 / 6 |
|
||||
| Inventory capacity/burden/drag residuals | 6 |
|
||||
| Paperdoll Aetheria, priority, legality, dual wield, body interactions | 7 |
|
||||
| Paperdoll empty art and per-race behavior | 7 |
|
||||
| Character Titles inert, live title/luminance missing | 8 |
|
||||
| Character raise authoritative/prediction semantics are unreconciled | 8 |
|
||||
| Character raises mutate optimistically instead of using proven server-authoritative flow | 8 |
|
||||
| Radar fellowship/allegiance state missing | 9 |
|
||||
| Combat/powerbar/spellbook/effects/social residuals/floating chat/quests/map/vitae/options/smartbox/vendor/trade/salvage/tinkering/world HUD absent | 10 |
|
||||
| Stale/missing/colliding divergence rows | 0, then every wave |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue