fix #416 #415: the retail button state/media machine — roster hover highlight clears; probe wait verbs bind without an artifact dir
#416 (char-select roster highlight never cleared on hover-leave): three decomp-grounded mechanisms replace the media-keyed _availableStates approximation. - UIElement_Button::UpdateState_ @0x00471CF0: the button machine commits ONLY states authored on the button's OWN ElementDesc (AccessStateDesc gate); unauthored requests no-op, preserving custom semantic states. - UIElement::SetState @0x00464E70: an unauthored state id is coerced to state 0 (the unnamed base state) and committed — ported into UiDatElement.TrySetRetailState with the base-descriptor PassToChildren cascade arm. - The SetState media rule @0x004651c0: a committed state replaces the playing media ONLY when its media array is non-empty. UiButton now keeps per-face-segment media states under that rule (segments model retail's PassToChildren children), and LayoutImporter records the raw MediaCount including the File=0 draw-nothing images the drawable filter drops — the roster bar children's base state is exactly such an image, and it is what clears the bar. The row template truth (probe, installed DAT): the row authors EMPTY Normal/rollover/Highlight descriptors with PassToChildren; the three bar children author rollover/Highlight media, NO Normal state, and a File=0 base image. An empty-media Normal_pressed still never blanks a Normal-art button (the media rule keeps the previous art — the exact behavior the old gate approximated), and the Appearance spins' property-only Highlight now genuinely commits: label recolors, arrow art lingers — the retail split AP-222 approximated with a requested-keyed label hack, now retired. Live-verified at char select: hover +alex shows the grey bar, moving off clears it, the selected row keeps its amber bar. #415 (probe wait world-* verbs dead): the filed snapshot-reset diagnosis was wrong — the automation bridge simply never bound without ACDREAM_AUTOMATION_ARTIFACT_DIR. A facts-only WorldRevealFactsAutomationRuntime now binds whenever the retained UI exists; checkpoint/screenshot verbs still require the artifact directory and now report that instead of a generic timeout. App tests 5568/3 skips, Runtime 1756/0, UI.Abstractions 926/0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7aa08045d8
commit
91c1962b0d
11 changed files with 469 additions and 86 deletions
|
|
@ -24,22 +24,57 @@ What does NOT go here:
|
|||
- Every session: scan OPEN issues at start; promote/close anything we touched during the session before ending.
|
||||
- Promoting to a Phase: mark as `DONE (promoted to Phase X)` + commit SHA where the Phase entry landed.
|
||||
|
||||
## #415 — UI-probe `wait world-visible` verb is dead after reveal completion (automation bridge reads the reset snapshot)
|
||||
## #416 — Character-select roster hover highlight never clears (sweeping the roster leaves every row highlighted)
|
||||
|
||||
**Status:** OPEN (filed 2026-08-17 at the #414 cursor repro). The script
|
||||
runner's `wait world-visible` polls
|
||||
`WorldLifecycleAutomationController.IsWorldViewportVisible`, which reads
|
||||
`_getReveal().WorldViewportObserved` from the LIVE transit snapshot. The
|
||||
reveal's `event=complete` retires that generation and the snapshot resets
|
||||
`WorldViewportObserved: false` (`RuntimeWorldTransitState.cs:583`), so the
|
||||
verb only observes true during the sub-second window between
|
||||
`event=world-visible` and `event=complete` — in practice it times out even
|
||||
though the world revealed (proved by the #414 repro logs: `wait
|
||||
world-visible 60000` timed out with `event=world-visible` present in the
|
||||
same run's `[world-reveal]` stream). Fix shape: the automation controller
|
||||
should latch world-visible per generation (or the verb should accept
|
||||
`IsWorldReady`-style completed state), not read the transient snapshot.
|
||||
Test apparatus only — no player impact.
|
||||
**Status:** ✅ FIXED 2026-08-17 (same round as #414; fix + tests in the same
|
||||
commit as this entry). **Symptom:** hovering a roster row highlights it, but
|
||||
moving off leaves the highlight on — sweep all rows and every one stays lit.
|
||||
**Root cause chain (decomp-grounded):** the roster row template
|
||||
(`0x21000004/0x100003A5`) is a media-less button whose three bar children
|
||||
(`0x10000481/82/83`) author `Normal_rollover`/`Highlight` media but NO
|
||||
`Normal` state — their BASE state instead authors a **File=0 draw-nothing
|
||||
image**. Retail clears the bar through two mechanisms our port approximated
|
||||
away: (1) `UIElement_Button::UpdateState_ @0x00471CF0` gates the machine on
|
||||
`AccessStateDesc` — any AUTHORED state commits (the row's empty
|
||||
`Normal` descriptor included), unauthored requests no-op; (2)
|
||||
`UIElement::SetState @0x00464E70`'s tail (`@0x004651c0`) resets the media
|
||||
machine ONLY when the committed state's media array is NON-EMPTY — an
|
||||
empty-media state keeps the previous media (why an empty `Normal_pressed`
|
||||
never blanks a Normal-art button), an unauthored state commits state 0
|
||||
whose BASE media applies, and the bar children's File=0 base image is what
|
||||
draws-nothing. Our media-keyed `_availableStates` gate refused the row's
|
||||
empty `Normal` commit outright, latching the rollover forever. **Fix:**
|
||||
`UiButton` now ports the machine gate (authored-on-own-desc) and the
|
||||
SetState media rule (per-face-segment media states with the non-empty-array
|
||||
reset gate; `LayoutImporter` records raw `MediaCount` including File=0
|
||||
entries); `UiDatElement.TrySetRetailState` gained retail's
|
||||
unauthored→state-0 arm with the base-descriptor `PassToChildren` cascade.
|
||||
Retires the AP-222-era requested-keyed label hack (the spins' property-only
|
||||
`Highlight` now genuinely commits — label recolors, arrow art lingers, the
|
||||
exact retail split). Live-verified at char select: hover `+alex` → grey bar;
|
||||
move off → bar clears; selected row keeps its amber bar. Tests:
|
||||
`UiButtonTests` (pressed-state face linger via draw capture, property-only
|
||||
Highlight commit, machine no-op preservation), `UiDatElementTests` (state-0
|
||||
commit/cascade/#408 guard), live-DAT spin pin updated to the commit truth.
|
||||
|
||||
## #415 — UI-probe `wait world-*` verbs are dead without `ACDREAM_AUTOMATION_ARTIFACT_DIR` (unbound deferred automation wrapper)
|
||||
|
||||
**Status:** ✅ FIXED 2026-08-17 (same round as #414/#416; fix in the same
|
||||
commit as this entry's flip). Filed as "reads the reset snapshot" — that
|
||||
diagnosis was WRONG: the completed reveal KEEPS `WorldViewportObserved`
|
||||
(only the next `BeginRevealCore` clears it). The actual cause:
|
||||
`FrameRootComposition` binds the `WorldLifecycleAutomationController` (and
|
||||
therefore the probe runtime bridge) ONLY when
|
||||
`ACDREAM_AUTOMATION_ARTIFACT_DIR` is configured; without it the
|
||||
`DeferredWorldLifecycleAutomationRuntime` wrapper stays unbound and every
|
||||
`wait world-ready/world-visible/materialized` verb silently reads false
|
||||
until timeout — even while the `[world-reveal]` stream shows the awaited
|
||||
edge (the #414 repro logs proved exactly this). **Fix:** a facts-only
|
||||
`WorldRevealFactsAutomationRuntime` now binds whenever the retained UI
|
||||
exists and the full controller is not composed — the wait verbs need only
|
||||
the reveal snapshot, which every launch has; checkpoint/screenshot verbs
|
||||
still require the artifact directory and now say so explicitly instead of
|
||||
failing with a generic timeout. Test apparatus only — no player impact.
|
||||
|
||||
## #414 — Mouse cursor disappears at character select after the in-world logoff (teardown fly-mode fallback raw-captures the cursor)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue