From 4e23a7b9bc391ed9ad12b89579f1b98c61a0ffcf Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 21 Jun 2026 07:52:40 +0200 Subject: [PATCH] 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) --- ...-bgrid-shipped-bcontroller-next-handoff.md | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 docs/research/2026-06-21-d2b-bgrid-shipped-bcontroller-next-handoff.md diff --git a/docs/research/2026-06-21-d2b-bgrid-shipped-bcontroller-next-handoff.md b/docs/research/2026-06-21-d2b-bgrid-shipped-bcontroller-next-handoff.md new file mode 100644 index 00000000..785859ba --- /dev/null +++ b/docs/research/2026-06-21-d2b-bgrid-shipped-bcontroller-next-handoff.md @@ -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.