acdream/docs/research/2026-06-21-d2b-bgrid-shipped-bcontroller-next-handoff.md
Erik 4e23a7b9bc 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>
2026-06-21 07:52:40 +02:00

173 lines
10 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: 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.