docs(D.2b): inventory finish Stage 1 — handoff + divergence rows + ISSUES

Handoff doc for the fresh session (scroll/frame/resize/102-slots shipped +
visually confirmed; next = wrong empty-slot art, then main-pack icon, then
Sub-phase C paperdoll). Divergence AP-52 (side-bag 7 fallback), AP-53 (main-pack
102 fallback), AP-54 (resize approximation). ISSUES: closed the contents-grid
overflow; filed the wrong empty-slot-background issue; Stage 1 SHIPPED entry.
(Memory digest project_d2b_retail_ui.md + MEMORY.md + the don't-kill-clients
feedback updated out-of-tree.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-21 21:31:24 +02:00
parent 1be7e65fad
commit e6c8b65f77
3 changed files with 166 additions and 1 deletions

View file

@ -0,0 +1,130 @@
# Handoff — D.2b inventory window finish (Stage 1) shipped + visually confirmed; slot-art + paperdoll next
**Date:** 2026-06-21 (after B-Wire)
**From:** the session that shipped **B-Wire** (inventory wire layer) **and Stage 1 of the
inventory window finish** (scroll + frame + vertical resize + 102-slot grid), both visually
confirmed at the live gate.
**Branch:** `claude/hopeful-maxwell-214a12`, tip **`1be7e65`** (+ this docs commit). `main` is a
clean ff ancestor — ff `main` + branch fresh, or continue this branch.
**Line numbers drift — grep the symbol.**
---
## 0. What shipped this session (all committed, build + full suite green, VISUALLY CONFIRMED)
Full suite green (`--no-build`, with the client running): **Core.Net 334 / App 543 / UI 425 /
Core 1530**, 0 failures.
### B-Wire — inventory wire layer (`b56087b``7c006d1`)
The burden bar now reads the server's wire `EncumbranceVal` (PropertyInt 5). Root cause was
**delivery, not binding**: login PD dropped the player's int table, live `0x02CD` was unparsed, and
`ObjectTableWiring` gated non-UiEffects ints out. Plus the full inventory wire pass (DropItem 0x001B
/ GetAndWieldItem 0x001A / NoLongerViewingContents 0x0195 builders; ViewContents 0x0196 /
SetStackSize 0x0197 / InventoryRemoveObject 0x0024 parsers; 0x0022 + 0x00A0 field fixes). Spec/plan
`docs/superpowers/{specs,plans}/2026-06-21-d2b-inventory-wire*.md`. Detail: the B-Wire SHIPPED entry
in `claude-memory/project_d2b_retail_ui.md`.
### Inventory window finish Stage 1 (`366af0c``1be7e65`)
Spec/plan `docs/superpowers/{specs,plans}/2026-06-21-d2b-inventory-window-finish*.md`.
- **Scroll**`UiItemList` clip+scroll via the shared `UiScrollable`; gutter scrollbar `0x100001C7`
bound like `ChatWindowController`; mouse-wheel.
- **Frame** — wrapped in the 8-piece bevel chrome (`UiNineSlicePanel`), like vitals/chat/toolbar.
- **Vertical resize** — bottom-edge only (horizontal blocked); the grid + sub-window + scrollbar +
backdrop stretch, paperdoll + side-bags pinned; scrollbar thumb reflects view/content.
- **102-slot grid** — contents grid pads empty frames to the main-pack capacity (default 102);
side-bag column pads to 7.
---
## 1. Read first
- This doc.
- `claude-memory/project_d2b_retail_ui.md` — the **Stage 1 SHIPPED** entry + DO-NOT-RETRY (updated this session).
- `docs/ISSUES.md` — the **OPEN** "Inventory + equipment slots show the wrong empty-slot background art" issue (the immediate next task) + the two **SHIPPED** entries.
- `docs/architecture/retail-divergence-register.md` — AP-52 (side-bag 7 fallback), AP-53 (main-pack 102 fallback), AP-54 (resize approximation), AP-51 (main-pack icon, still open).
- `docs/research/2026-06-16-equipment-paperdoll-deep-dive.md` — for Stage 2 (paperdoll).
- `.layout-dumps/uiitem-0x21000037.txt` — the UIItem cell template states (for the correct empty-slot sprite).
---
## 2. Key discoveries (durable, non-obvious — DO-NOT-RETRY)
1. **Grid cells must be `Anchors = None`.** `UiElement.DrawSelfAndChildren` runs `ApplyAnchor` on
every child AFTER `OnDraw`; with default `Left|Top` anchors it captured each cell's scroll-0
position and reset `Top` to it every frame, fighting `UiItemList.LayoutCells`' scroll offset →
the grid "escaped the window" when scrolled. `AddItem` now sets `cell.Anchors = None` so
`LayoutCells` is the sole authority. **The unit tests missed it by calling `LayoutCells` in
isolation, never the draw traversal** — the regression test now drives the `ApplyAnchor`
interaction. (Fix `14ea938`.)
2. **Scroll reuses `UiScrollable` + a whole-row logical clip (no GL scissor)** — mirrors
`UiText.cs:198` (`cell.Visible = top >= 0 && top + h <= Height`). The gutter scrollbar `0x100001C7`
is a factory Type-11 `UiScrollbar` inheriting base `0x2100003E`; bind its `Model` to `grid.Scroll`
+ the same scrollbar sprite ids the chat scrollbar uses.
3. **Vertical-resize cascade via anchors.** Frame: `Resizable=true; ResizeX=false;
ResizableEdges=Bottom`. The stretch elements (grid `0x100001C6`, its sub-window `0x100001CF`,
scrollbar `0x100001C7`, backdrop `0x100001D0`, + the content root) get `Anchors=Left|Top|Bottom`
(fixed width, height tracks parent); paperdoll `0x100001CD` + side-bag `0x100001CE` pinned
`Left|Top`. `ComputeAnchoredRect`: Top|Bottom ⇒ `h = parentH mB mT`.
4. **Capacity-padding pattern.** The contents grid + side-bag column pad empty `UiItemSlot`s up to
the pack capacity (player `ItemsCapacity` default 102; `ContainersCapacity` default 7) after the
loose-item loop in `InventoryController.Populate`. Padding changed several existing tests' counts
(intended — update, don't revert).
5. **DO-NOT auto-kill the client.** The user manages client lifecycle: launch with a **plain
`dotnet run --no-build`** (no `Get-Process … CloseMainWindow/Stop-Process` preamble). If a rebuild
is blocked by a running client (`MSB3021`/`MSB3027` "locked by AcDream.App"), **ASK the user to
close it** — do not kill it. (`feedback_dont_kill_clients_before_launch`.) This overrides the
CLAUDE.md graceful-close snippet.
---
## 3. Current visual state (F12, `ACDREAM_RETAIL_UI=1`)
Renders correctly + confirmed: 8-piece bevel frame; vertical bottom-edge resize (expand-only,
372..560 px); contents grid clips to its panel, scrolls (wheel + gutter scrollbar), shows the full
**102-slot** main pack (items + empty frames); side-bag column with bags + empty slots; vertical
burden bar; backdrop covers the window. **Known-wrong (next task):**
- **Empty-slot background art is wrong** — inventory + side-bag empty cells use the TOOLBAR empty
sprite (`UiItemSlot.EmptySprite = 0x060074CF`); paperdoll equip slots show a generic blue
`UiDatElement` border. (User-flagged.)
- **Main-pack cell has no backpack icon** (AP-51, placeholder `tex=0`).
---
## 4. What's next (build order)
**(a) FIX the empty-slot background art — RECOMMENDED NEXT (the OPEN ISSUE).** Inventory + side-bag
empty cells should use the retail pack-slot frame, not the toolbar's `0x060074CF`. Find the correct
sprite from the UIItem cell template `0x21000037` (`.layout-dumps/uiitem-0x21000037.txt`) empty
state; set it on the cells `InventoryController` creates (an `EmptySprite` override per slot kind, or
a controller-set default distinct from the toolbar's). The paperdoll equip slots' per-slot
silhouettes are Sub-phase C (below). Small, self-contained; brainstorm → spec → plan as usual.
**(b) Main-pack backpack icon (AP-51).** The main-pack cell (`m_topContainer 0x100001C9`) should show
the equipped-backpack art. Pin the backpack RenderSurface DID (or the equipped-pack `CreateObject`
icon path).
**(c) Sub-phase C — paperdoll.** The 3D character doll via a Core→App `IUiViewportRenderer` seam
(`UiViewport`, Type `0xD`) + the `0x10000032` `UiItemSlot` registration so equip slots draw per-slot
silhouettes. Research: `2026-06-16-equipment-paperdoll-deep-dive.md`. The heaviest piece.
**(d) Deferred polish:** container-switching (select a side pack → show its 24-slot contents via the
already-parsed `ViewContents 0x0196`); the side-bag column scrollbar (`0x100001CB`, inert — 7 fit);
shrink-below-default resize (currently expand-only); the selected-target bar + stack split slider
(per the wiki notes the user pasted). B-Drag (drag items between slots) also remains.
Each gets the full brainstorm → spec → plan → execute flow.
---
## 5. New-session prompt (paste into a fresh session)
> Continue acdream's D.2b retail-UI inventory arc. **Read
> `docs/research/2026-06-21-d2b-inventory-finish-handoff.md` first.** B-Wire + the inventory window
> finish Stage 1 (scroll, 8-piece frame, vertical resize, 102-slot grid) shipped + visually confirmed
> on `claude/hopeful-maxwell-214a12` (tip `1be7e65`; `main` is a clean ff ancestor). **Next: fix the
> wrong empty-slot background art** — inventory + side-bag empty cells use the toolbar empty sprite
> `0x060074CF`; they need the retail pack-slot frame from the UIItem cell template `0x21000037` (see
> `.layout-dumps/uiitem-0x21000037.txt`). Then the main-pack backpack icon (AP-51), then Sub-phase C
> (paperdoll `UiViewport` doll + `0x10000032` per-slot equip silhouettes). Use the full brainstorm →
> spec → plan → subagent/inline flow. **DO NOT auto-kill the running client** — launch with plain
> `dotnet run --no-build`; if a rebuild is locked by a running client, ask the user to close it.