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>
8.3 KiB
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 —
UiItemListclip+scroll via the sharedUiScrollable; gutter scrollbar0x100001C7bound likeChatWindowController; 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)
- Grid cells must be
Anchors = None.UiElement.DrawSelfAndChildrenrunsApplyAnchoron every child AFTEROnDraw; with defaultLeft|Topanchors it captured each cell's scroll-0 position and resetTopto it every frame, fightingUiItemList.LayoutCells' scroll offset → the grid "escaped the window" when scrolled.AddItemnow setscell.Anchors = NonesoLayoutCellsis the sole authority. The unit tests missed it by callingLayoutCellsin isolation, never the draw traversal — the regression test now drives theApplyAnchorinteraction. (Fix14ea938.) - Scroll reuses
UiScrollable+ a whole-row logical clip (no GL scissor) — mirrorsUiText.cs:198(cell.Visible = top >= 0 && top + h <= Height). The gutter scrollbar0x100001C7is a factory Type-11UiScrollbarinheriting base0x2100003E; bind itsModeltogrid.Scroll- the same scrollbar sprite ids the chat scrollbar uses.
- Vertical-resize cascade via anchors. Frame:
Resizable=true; ResizeX=false; ResizableEdges=Bottom. The stretch elements (grid0x100001C6, its sub-window0x100001CF, scrollbar0x100001C7, backdrop0x100001D0, + the content root) getAnchors=Left|Top|Bottom(fixed width, height tracks parent); paperdoll0x100001CD+ side-bag0x100001CEpinnedLeft|Top.ComputeAnchoredRect: Top|Bottom ⇒h = parentH − mB − mT. - Capacity-padding pattern. The contents grid + side-bag column pad empty
UiItemSlots up to the pack capacity (playerItemsCapacitydefault 102;ContainersCapacitydefault 7) after the loose-item loop inInventoryController.Populate. Padding changed several existing tests' counts (intended — update, don't revert). - DO-NOT auto-kill the client. The user manages client lifecycle: launch with a plain
dotnet run --no-build(noGet-Process … CloseMainWindow/Stop-Processpreamble). 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 blueUiDatElementborder. (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.mdfirst. B-Wire + the inventory window finish Stage 1 (scroll, 8-piece frame, vertical resize, 102-slot grid) shipped + visually confirmed onclaude/hopeful-maxwell-214a12(tip1be7e65;mainis a clean ff ancestor). Next: fix the wrong empty-slot background art — inventory + side-bag empty cells use the toolbar empty sprite0x060074CF; they need the retail pack-slot frame from the UIItem cell template0x21000037(see.layout-dumps/uiitem-0x21000037.txt). Then the main-pack backpack icon (AP-51), then Sub-phase C (paperdollUiViewportdoll +0x10000032per-slot equip silhouettes). Use the full brainstorm → spec → plan → subagent/inline flow. DO NOT auto-kill the running client — launch with plaindotnet run --no-build; if a rebuild is locked by a running client, ask the user to close it.