docs: record D.2b UI Studio + importer dat-fidelity + Character window (shipped this session)

Roadmap: extend D.5-remaining ledger with three new shipped entries (UI Studio,
importer Fix A/B/C, Character window 0x2100002E). Milestone M5: update D.2b
status paragraph to name all shipped sub-phases including the studio, importer
boundary discovery (look=importer / state=runtime), and Character window with
deferred polish pointer (#151).

ISSUES: add #151 (Character window deferred polish — LOW, filed 2026-06-26;
user accepted Attributes tab as good-enough, polish items to be enumerated later).
Issues #149 (studio inventory all-black) and #150 (GameWindow font resolver) were
already present.

Divergence register: add AP-69 (per-element dat-font resolver is studio-only;
GameWindow passes null to the four Import sites until #150 lands). No row for
Fix-4 UIState-group activation (runtime-faithful, not a deviation) or for the
tab-sprite injection / footer-state hiding (same).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-26 12:18:03 +02:00
parent 9408c062d2
commit ea42c6d303
4 changed files with 23 additions and 2 deletions

View file

@ -167,6 +167,7 @@ accepted-divergence entries (#96, #49, #50).
| AP-66 | **Empty equip slots paint a frame sprite (`EmptySprite` 0x06004D20), faithfulness vs retail's empty-slot art unverified** — Slice 2 shipped the doll `UiViewport` (0x100001D5) + the Slots toggle (doll-view ↔ slot-view, decomp 175674-175706), so empty ARMOR slots are now hidden in doll-view (the 3-D body shows instead). The always-visible non-armor equip slots (and armor slots in slot-view) still paint a frame when empty. | `src/AcDream.App/UI/Layout/PaperdollController.cs:99` | The doll + toggle are faithful (decomp-cited); painting a slot frame on empty positions is plausibly retail (the outlines guide drops), but is not pixel-verified against retail's doll-view. | Empty equip slots may show a framed square where retail shows a different empty treatment — cosmetic. | `gmPaperDollUI::ListenToElementMessage` 175674-175706; user retail screenshots |
| AP-67 | **Paperdoll doll is rendered to an off-screen FBO and blitted as a 2-D sprite (RTT), not retail's in-cell `CreatureMode::Render`** — retail adds the doll to `m_pPaperDoll->creature_mode_objects` and draws it into the UI's creature cell during the frame; acdream renders the re-dressed clone into a private framebuffer (`PaperdollViewportRenderer`, sealed in a `GLStateScope`), then the `UiViewport` widget blits the color texture. | `src/AcDream.App/Rendering/PaperdollViewportRenderer.cs`; `src/AcDream.App/UI/UiViewport.cs` | Architectural adaptation: acdream's modern bindless/MDI world pipeline can't cheaply render one creature into a UI cell mid-pass; the RTT seam reuses `WbDrawDispatcher` with the retail camera/light/pose/heading so the pixels match. No visual difference intended. | An FBO-format / lighting-UBO-overwrite / blit-V-flip bug shows as a doll that's mis-lit, clipped, or upside-down vs retail — cosmetic, confined to the viewport. | retail `CreatureMode::Render` 0x004529d0; `RedressCreature` 0x004a3bc0 |
| AP-68 | **Per-race paperdoll pose (`gmPaperDollUI::UpdateForRace`) not implemented** — the ctor-default pose animation `0x030003C0` is applied for ALL body types; retail's `UpdateForRace` (decomp 174129) can override `m_didAnimation` per race. | `src/AcDream.App/Rendering/GameWindow.cs` (`ResolvePaperdollPoseDid`) | cdb-confirmed `UpdateForRace` does NOT fire for Horan, so the ctor default 0x030003C0 is authoritative for the gate character; other races/genders may pose differently. | A non-default-race character could hold the wrong stance in the doll — cosmetic. | `gmPaperDollUI::UpdateForRace` decomp 174129; cdb trace 2026-06-25 |
| AP-69 | **Per-element dat-font resolver (Fix C) wired into the STUDIO path only**`LayoutImporter.Import` + `DatWidgetFactory` support a `Func<uint,UiDatFont?>` resolver that gives each text element its own dat font; `StudioWindow` supplies this resolver. `GameWindow`'s four `Import`/`Build` call sites pass `null`, so the live game still uses a single global font. **Retire with #150.** | `src/AcDream.App/Rendering/RenderBootstrap.cs` (`RenderStack.ResolveDatFont` — the pattern to mirror into GameWindow) + `src/AcDream.App/Studio/StudioWindow.cs` (resolver wired) + `src/AcDream.App/Rendering/GameWindow.cs` (~4 import sites pass null) | Studio is the proving-ground path; GameWindow threading is Issue #150 (small, safe, orthogonal to M5 gameplay). The live panels still render with the global dat font (same as before Fix C), so behavior is unchanged in the shipped game. | Text elements whose dat `FontDid` differs from the global font render with the wrong size/face in the live game — cosmetic; the studio shows the correct dat font. | `DatWidgetFactory.BuildText`; `LayoutImporter.Import(fontResolver)`; commit `a0d3395` (Fix C) |
---