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

10 KiB
Raw Blame History

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) — 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.