acdream/docs/research/2026-06-21-d2b-inventory-finish-handoff.md
Erik e6c8b65f77 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>
2026-06-21 21:31:24 +02:00

130 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.