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>
173 lines
10 KiB
Markdown
173 lines
10 KiB
Markdown
# 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.
|