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

8.3 KiB
Raw Blame History

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 (b56087b7c006d1)

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 (366af0c1be7e65)

Spec/plan docs/superpowers/{specs,plans}/2026-06-21-d2b-inventory-window-finish*.md.

  • ScrollUiItemList 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 UiItemSlots 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.