docs(handoff): D.2b A+B-Grid shipped, #145 fixed, B-Controller next

Session handoff: window manager (F12) + inventory sub-window mount
(inheritance-children) + UiItemList grid all shipped; #145 ZLevel z-order
fixed (backdrop behind panels). B-Controller next (populate grids + burden
meter from ClientObjectTable). Key discoveries, B-Controller readiness, and
the new-session prompt captured.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-21 07:52:40 +02:00
parent 4904ff4e21
commit 4e23a7b9bc

View file

@ -0,0 +1,173 @@
# Handoff — D.2b inventory: A + B-Grid shipped, #145 fixed, B-Controller next
**Date:** 2026-06-21
**From:** the session that shipped the **window manager (Sub-phase A)**, **B-Grid** (inventory
sub-window mount + grid), and fixed **#145** (ZLevel z-order). All committed on branch
`claude/hopeful-maxwell-214a12`, tip `4904ff4`. Full suite green (2767).
**Predecessor handoff:** `docs/research/2026-06-20-window-manager-inventory-handoff.md` (the
A→B→C arc). This doc supersedes it for "what's next."
**Line numbers drift — grep the symbol.**
---
## 0. What shipped this session
- **Sub-phase A — window manager.** `UiRoot` named-window registry (`RegisterWindow` /
`ShowWindow` / `HideWindow` / `ToggleWindow` / `BringToFront`), raise-on-click, and F12 →
toggle via the **existing** `InputAction.ToggleInventoryPanel`. `UiHost` forwarders. Spec
`docs/superpowers/specs/2026-06-20-d2b-window-manager-design.md`; plan
`…/plans/2026-06-20-d2b-window-manager.md`. Commits `6409038`/`036db8b`/`882b4dd`/`e3152ad`.
Visually confirmed (F12 toggles, click raises, chat-focus gate).
- **Cross-check correction:** retail's inventory key is **F12** (`ToggleInventoryPanel`),
NOT `I` (`I` = the `Laugh` emote per `retail-default.keymap.txt:246`). The handoff guessed I.
- **Sub-phase B-Grid — inventory frame.** `UiItemList` N-cell **grid mode**
(`Columns`/`CellWidth`/`CellHeight`/`CellOffset`/`LayoutCells`; single-cell toolbar preserved)
+ the **sub-window mount** in `LayoutImporter.Resolve` + the `GameWindow` swap of the A
placeholder for `LayoutImporter.Import(0x21000023)`. Spec
`…/specs/2026-06-20-d2b-inventory-grid-mount-design.md`; plan
`…/plans/2026-06-20-d2b-inventory-grid-mount.md`. Commits `4fd4b09`/`85098f5`/`7d971a2`.
- **#145 — ZLevel z-order (DONE `45a5cc5`).** The importer mapped `ZOrder ← ReadOrder` only, so
the gmInventoryUI full-window backdrop (`0x100001D0`, ReadOrder 4) painted over the panels
(ReadOrder 1-3). Now `ZOrder = ReadOrder ZLevel·10000` (higher ZLevel = further back). See §3.
---
## 1. Read first
- This doc + the two B-Grid spec/plan files above.
- `docs/research/2026-06-16-ui-panels-synthesis.md` §4 (the core-panels build plan).
- `docs/research/2026-06-16-inventory-deep-dive.md` (gmInventoryUI nesting + wire catalog).
- `claude-memory/project_d2b_retail_ui.md` (toolkit crib — updated this session).
- `claude-memory/project_object_item_model.md` (the `ClientObjectTable` — B-Controller's data source).
---
## 2. Decomposition + status
Sub-phase B was decomposed into four steps (approved this session):
| Step | Status |
|---|---|
| **B-Grid** — UiItemList grid + sub-window mount | ✅ **SHIPPED** (mount works for all 3 panels; paperdoll equip-slot positions visually confirmed) |
| **B-Controller** — populate grids + burden meter + captions | ⬜ **NEXT** (see §5) |
| **B-Wire** — wire gaps (DropItem/ViewContents/…) | ⬜ pending |
| **B-Drag** — inventory cell as drag SOURCE (reuse the shipped spine) | ⬜ pending |
| **Sub-phase C** — paperdoll doll + per-slot equip art | ⬜ pending (the wrong-slot-graphics fix lives here) |
---
## 3. Key discoveries (durable, non-obvious)
1. **The nested panels are Type-0 inheritors, not game-class Types.** `gmInventoryUI 0x21000023`'s
three panels — paperdoll `0x100001CD`, backpack `0x100001CE`, 3D-items `0x100001CF` — are
**Type-0, media-less, childless leaves** that nest via `BaseElement`+`BaseLayoutId`
(BaseLayoutId → `0x21000024`/`0x21000022`/`0x21000021`). The research agent's "game-class Type
+ recursive Import" model was WRONG — confirmed by dumping `0x21000023`.
2. **The mount = inheritance carrying base children.** `ElementReader.Merge` dropped the base's
children. The mount (`LayoutImporter.ShouldMountBaseChildren` + the `Resolve` tail) attaches a
base's resolved subtree when the derived element is a pure container (no own children, no own
media) inheriting from a base WITH children. Inert for media-bearing inheritors (close
button/title) and childless style prototypes (vitals/chat/toolbar).
3. **ZLevel z-order: higher = further back.** `DatWidgetFactory` folds `ZLevel` into `ZOrder`
(`ReadOrder ZLevel·10000`). ZLevels observed: vitals all **0**; toolbar **0,1,2**; chat
**0,900**; inventory **0,10,50,100** (backdrop 100). Vitals unchanged; **chat + toolbar shifted
to their dat layering — needs a visual regression confirm (see §6).**
4. **The paperdoll equip slots need `0x10000032` (UiItemSlot) registration.** They resolve to type
`0x10000032`, which the factory does NOT register, so they fall back to a generic `UiDatElement`
sprite (the uniform blue border seen on screen) instead of per-slot silhouettes. This + the
dressed doll is **Sub-phase C**.
---
## 4. Current visual state (F12 with ACDREAM_RETAIL_UI=1)
The inventory window opens and renders the nested frame: outer chrome + title + the **paperdoll
equip slots correctly positioned** over the backdrop. **Gaps (all expected — next sub-steps):**
- Equip slots draw a generic border, not per-slot silhouettes → **C**.
- Backpack strip + 3D-items contents look empty (the panels mounted; their content is unpopulated)
**B-Controller**.
- Item cells empty everywhere (no items bound) → **B-Controller**.
---
## 5. B-Controller — the next step
**Goal:** make the inventory show your live contents — populate the backpack/3D-items grids from
`ClientObjectTable`, drive the burden meter, render the captions. The `gm*UI::PostInit` analogue.
**READY:**
- `ClientObjectTable.GetContents(containerGuid)` → ordered guids; `Get(guid)` → icon fields
(`src/AcDream.Core/Items/ClientObjectTable.cs`). The player's own pack is already in the table
from the CreateObject stream — **no new wire needed for the own-pack path** (B-Wire is for other
containers + live deltas).
- `UiItemList` grid mode (B-Grid) — set `Columns`/`CellWidth`/`CellHeight` (read the cell pitch
from the nested layout's item template) then `Flush()` + `AddItem()` per item.
- `IconComposer` for the cell icons; `UiItemSlot.SetItem(guid, iconTex)`.
- `ImportedLayout.FindElement(id)` to bind by id (the burden meter, the lists).
- The burden meter is element `0x100001D9` (Type 7 → `UiMeter`); drive fill via
`SetAttribute_Float`-equivalent (`UiMeter.Fill`); load ratio = burden/maxBurden.
**MISSING / to build:**
- `InventoryController`: find-by-id bind of the burden meter + the backpack/3D-items lists from
`invLayout` (the `ImportedLayout` built in `GameWindow`); subscribe to `ClientObjectTable`
`ObjectAdded/Moved/Removed`; rebuild cells.
- **Grid params:** dump `0x21000022` (backpack) + `0x21000021` (3D-items) to read the item-list
element sizes + cell template (geometry suggests backpack ~1 col, 3D-items ~6 cols of 36×36).
- **Type-0 text captions** ("Burden", "Contents of Backpack") don't render today — `UiDatElement`
doesn't draw text. Decide: promote those Type-0 elements to `UiText`, or a caption pass.
- Burden meter: verify `BuildMeter` produces a valid meter for the backpack meter's child shape
(it may differ from the vitals 3-slice shape).
**Brainstorm Qs (B-Controller):** Where does `InventoryController` get `invLayout` (expose the
`ImportedLayout` from `GameWindow`, or import inside the controller)? Cell pitch source (dump vs
hardcode 36)? Type-0 caption rendering (UiText promotion vs a caption helper)?
---
## 6. Open items / caveats
- **⚠ Confirm chat + toolbar didn't regress from the #145 ZLevel fix** (chat ZLevel 900, toolbar
1,2). The user looked but didn't explicitly confirm; first thing to eyeball next session.
- Type-0 text captions don't render (see §5).
- The B-Drag step reuses the **already-shipped** drag spine (`UiItemSlot` is a full drag source +
drop target; `IItemListDragHandler`/`ItemDragPayload`/`ShortcutStore`/the AddShortcut wire all
exist) — do NOT rebuild it. It needs the inventory cell as a SOURCE + the `SourceKind==Inventory`
branch in `ToolbarController.HandleDropRelease`.
---
## 7. Branch state
All work is on `claude/hopeful-maxwell-214a12` (tip `4904ff4`), which is `main` (`a391b86`) +
this session's A + B-Grid + #145 commits (a clean fast-forward chain — `main` is an ancestor).
Decide at the start of the next session: **fast-forward `main` to `4904ff4` and start a fresh
worktree off `main`** (matches the prior-arc pattern), or continue this branch.
---
## 8. New-session prompt (paste into a fresh session)
> Continue acdream's D.2b retail-UI inventory arc. **Read
> `docs/research/2026-06-21-d2b-bgrid-shipped-bcontroller-next-handoff.md` first.** Sub-phase A
> (window manager, F12) and B-Grid (inventory sub-window mount + UiItemList grid) shipped, and #145
> (ZLevel z-order — the backdrop now sits behind the panels) is fixed — all on
> `claude/hopeful-maxwell-214a12` (tip `4904ff4`; `main` is an ancestor, so ff `main` and branch
> fresh, or continue). F12 now shows the nested inventory frame with the paperdoll equip slots
> correctly positioned, but the backpack/3D-items panels are empty and the equip slots show a
> generic border. **Next: B-Controller** — bind the imported `gmInventoryUI` tree by id and
> populate the backpack/3D-items grids from `ClientObjectTable.GetContents(player)` + drive the
> burden meter (`0x100001D9`) + render the Type-0 captions. Use the full brainstorm → spec → plan →
> subagent-driven flow; mandatory grep-named→cross-ref→pseudocode→port for any wire format;
> conformance tests throughout. Reuse the shipped grid + window manager + drag spine — don't
> rebuild. **First, eyeball chat + toolbar for any z-order regression from the #145 ZLevel fix.**
> After B-Controller: B-Wire (wire gaps), B-Drag (inventory drag SOURCE), then Sub-phase C
> (paperdoll doll + per-slot equip art — the wrong-graphics fix; needs `0x10000032` UiItemSlot
> registration).
**MEMORY.md index line:**
- [Handoff: D.2b A+B-Grid shipped, #145 fixed, B-Controller next (2026-06-21)](research/2026-06-21-d2b-bgrid-shipped-bcontroller-next-handoff.md) — window manager (F12) + inventory sub-window mount (inheritance-children, NOT game-class Type) + UiItemList grid all shipped; #145 ZLevel z-order fixed (backdrop behind panels). Next B-Controller (populate grids + burden meter from ClientObjectTable). Paperdoll equip slots need 0x10000032; chat/toolbar ZLevel-regression unconfirmed.