acdream/docs/research/2026-06-16-action-bar-inventory-equipment-handoff.md
Erik a5c5126e8d docs(D.5): action bar / inventory / paperdoll research drop
Five report-only deep-dives + synthesis for the next D.2b UI panels, built on the shipped widget toolkit. Confirms LayoutDesc ids (toolbar 0x21000016, inventory 0x21000023, backpack 0x21000022, paperdoll 0x21000024, 3ditems 0x21000021), the shared item-slot/item-list spine (UIElement_UIItem 0x10000032 / UIElement_ItemList 0x10000031), the 5-layer icon composite (IconData::RenderIcons @407524), the cross-panel wire catalog with acdream parse-status, and the dependency-ordered build plan.

Produced via a multi-agent research workflow; the spine agent died on a transient API error and was re-run as a focused follow-up with its decomp anchors verified against source.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:04:57 +02:00

13 KiB
Raw Blame History

Handoff — next UI phase: action bar / quick slots + inventory + equipment (paperdoll)

Date: 2026-06-16 From: the session that landed the D.2b widget generalization (merged to main at 78c9187). Purpose: kick off a deep retail-faithful research phase for the next three game panels, before any implementation. This doc + the new-session prompt at the bottom are the entry point.


1. Where we are (what you're building on)

The D.2b retail-UI toolkit is complete and on main. You have:

  • A generic, Type-registered widget toolkit built by DatWidgetFactory from the dat LayoutDesc: UiButton (Type 1), UiMenu (6), UiMeter (7), UiScrollbar (11), UiText (12), plus UiField (editable, controller-placed) and UiDatElement (generic chrome/container fallback). All in src/AcDream.App/UI/.
  • The assembly pattern: a window is a dat LayoutDescLayoutImporter.Import(...) walks the ElementDesc tree → DatWidgetFactory builds each element generically → a thin gm*UI::PostInit-style controller finds widgets by id (layout.FindElement(id) as UiX) and binds live data/behavior. See VitalsController and ChatWindowController for the two worked examples.
  • Key toolkit rules (read claude-memory/project_d2b_retail_ui.md first — it's the START-HERE digest with the full DO-NOT-RETRY list):
    • UiElement.ConsumesDatChildren — behavioral widgets are leaf (the importer doesn't build their dat sub-elements; they reproduce them procedurally).
    • The base-chain Type resolution (ElementReader.Merge) already surfaces each element's real registered Type.
    • Type 3 is chrome/container in acdream's layouts (stays UiDatElement), NOT a factory-registered editable Field.

This phase's job is to build the next real game panels on that toolkit — but they're complex (live item state, drag-drop, wire messages, icon rendering), so we research first per the project's mandatory grep named → decompile → cross-ref → pseudocode → port workflow (CLAUDE.md).

These panels are the roadmap's F.5 / D.5 "core panels" (Attributes / Skills / Paperdoll / Inventory / Spellbook).


2. The three targets + their retail entry points (concrete anchors)

All confirmed from the named decomp (docs/research/named-retail/acclient_2013_pseudo_c.txt):

A. Action bar / quick slots → gmToolbarUI (element class 0x10000007)

The retail "toolbar" is the shortcut bar. Confirmed methods (grep gmToolbarUI::):

  • UseShortcut(slot), AddShortcut, RemoveShortcut, RemoveShortcutInSlotNum, FlushShortcuts, CreateShortcutToItem, IsShortcutEligible(ACCWeenieObject*), IsShortcutSlotAvailable, GetFirstEmptyShortcutToTheRightOf, RecvNotice_AddShortcut/RemoveShortcut/UseShortcut.
  • Slots hold UIElement_UIItem widgets (UIElement_UIItem::SetShortcutNum / SetDelayedShortcutNum); the underlying object is an ACCWeenieObject with SetShortcutNum.
  • Spell shortcuts: UIElement_ItemList::ItemList_InsertSpellShortcut, CM_Magic::SendNotice_AddSpellShortcut.

B. Inventory → gmInventoryUI (element class 0x10000023), gmBackpackUI (0x10000022)

The inventory window + nested backpacks/side-packs. Items are server-spawned weenies (ACCWeenieObject) — see claude-memory/feedback_weenie_vs_static.md (selectable/interactable items are server weenies, not dat-baked).

C. Equipment / paperdoll → gmPaperDollUI (element class 0x10000024), gm3DItemsUI (0x10000021)

The paperdoll window shows equipped/wielded items + the character doll. gm3DItemsUI is likely the 3D doll viewport (a rotating character model with equipped gear).

Shared building blocks (the toolkit pieces these need that we DON'T have yet)

  • UIElement_UIItem (element class 0x10000032) — the item-in-a-slot widget: an icon (from the weenie's IconDataID), drag-drop (retail UIElement_Field's CatchDroppedItem / MouseOverTop hooks — note our UiField already documents these as future drag-drop hooks), a shortcut number, a quantity/burden overlay, a selection/highlight. This is the most important new generic widget — all three panels are grids/lists of these.
  • UIElement_ItemList (0x10000031) — a scrollable list/grid of items (retail's ListBox-for-items). Maps to a UiListBox (Type 5, not yet built) or a UiItemGrid.
  • The window manager (the other deferred Plan-2 piece): open/close/z-order/persist, drag via Dragbar (Type 2), resize via Resizebar (Type 9). Inventory/paperdoll/toolbar are pop-up/dockable windows that need this.
  • Drag-drop infrastructure: item drag between inventory ↔ equip ↔ toolbar ↔ ground, with the wire messages it triggers.

3. The research questions (the deep-research scope)

Produce a research doc per panel (or one combined doc) under docs/research/ answering these, each with a retail anchor (named class::method + decomp line, or LayoutDesc/element-class id) and cross-referenced against the references in §4.

Common / cross-cutting (do this first — it unblocks all three):

  1. The dat LayoutDesc id for each panel (gmToolbarUI / gmInventoryUI / gmPaperDollUI). The element-class ids above are the registered class; find the actual LayoutDesc (0x21xxxxxx) that builds each window. Use the AcDream.Cli layout-dump tools (dump-vitals-layout <datdir> 0xId, the LayoutIndexDump) and grep the decomp for the class's Create/PostInit.
  2. UIElement_UIItem (0x10000032) — full port spec: what Type does it resolve to in the dat? How does it render an item icon from the weenie's IconDataID (→ RenderSurface/Icon overlay — cross-ref WorldBuilder/ACViewer icon decode)? How are quantity, burden, wielded/selected states drawn? What's the drag-drop state machine (MouseOverTop/CatchDroppedItem)?
  3. The item/container data model: items are ACCWeenieObjects. How does the client learn container contents — which wire messages (CreateObject, the container/inventory messages), and how is the container hierarchy (main pack → backpacks → side-packs) represented? What does acdream already parse (cross-ref the wire-message catalog, §4)?

Action bar (gmToolbarUI): 4. The shortcut slot model — how many slots/bars, item vs spell shortcuts, what a slot stores (ShortcutNum), IsShortcutEligible. 5. Persistence + wire: is the toolbar server-persisted? What messages add/remove/use a shortcut (RecvNotice_AddShortcut/RemoveShortcut/UseShortcut) and what does activation send (use-item / cast-spell)? 6. Drag-from-inventory-to-slot + drag-to-reorder (CreateShortcutToItem, GetFirstEmptyShortcutToTheRightOf).

Inventory (gmInventoryUI / gmBackpackUI): 7. The window layout (the item grid, the side-pack tabs/list, burden/value summary). 8. The full set of inventory wire messages (server → client item arrival + client → server actions: pick up, drop, give, move-between-containers, split-stack, merge-stack). Cross-ref ACE (what the server sends/validates) + holtburger (what the client sends). 9. Icon rendering: weenie IconDataID → texture (+ any underlay/overlay/highlight for ID'd vs unidentified, wielded, selected).

Equipment / paperdoll (gmPaperDollUI / gm3DItemsUI): 10. The equip/wield slots — the coverage/location enum (which slots exist, their screen positions on the doll). 11. The wield/unwield wire messages (equip an item, the server's response, the resulting ObjDesc change on the character model). 12. The paperdoll rendering — is it the 2D doll image + slot icons, or a 3D character viewport (gm3DItemsUI)? How does it assemble the equipped-character appearance (cross-ref ACViewer's ObjDesc/CreaturePalette + WorldBuilder for the model)?


4. References (the hierarchy — cross-reference at least two per question)

Per CLAUDE.md's reference table:

  • Named retail decomp (docs/research/named-retail/acclient_2013_pseudo_c.txt + acclient.h + symbols.json) — primary oracle for the UI logic (the gm*UI / UIElement_UIItem classes). Grep by class::method.
  • holtburger (references/holtburger/) — primary oracle for client behavior + wire: what a client sends/receives for inventory, equip, use-item, drag-drop. Look in client/ + session/.
  • ACE (references/ACE/Source/ACE.Server/) — server expectations: the inventory/equip/move game-action handlers, what the server validates + broadcasts.
  • WorldBuilder + ACViewericon + 3D-model rendering: IconDataID → texture decode (ACViewer TextureCache.IndexToColor / WorldBuilder TextureHelpers); the equipped-character ObjDesc assembly (ACViewer StaticObjectManager / CreaturePalette).
  • Chorizite.ACProtocol (references/Chorizite.ACProtocol/Types/*.cs) — protocol field order for the inventory/equip messages.

Existing acdream research/memory to read first (don't re-research what's done):

  • claude-memory/project_d2b_retail_ui.md — the toolkit + the find-by-id controller pattern (START HERE).
  • claude-memory/feedback_weenie_vs_static.md — items are server weenies.
  • claude-memory/project_interaction_pipeline.md — the existing WorldPicker / Select / UseSelected interaction (B.4) — the use/pickup path partly exists.
  • claude-memory/MEMORY.md → the wire-message catalog research (research/2026-06-04-wire-message-catalog.md): 256 opcodes, what acdream parses vs stubs vs is-missing — the inventory/equip opcodes' parse status is in there.
  • docs/research/2026-06-15-layoutdesc-format.md — the LayoutDesc/ElementDesc format (for reading the panel layouts).
  • The AcDream.Cli layout-dump tools (dump-vitals-layout, LayoutIndexDump, LayoutFixtureDump from this session's Task 1) — for dumping any panel's LayoutDesc.

5. Deliverable + approach

Report-only research — no implementation, no code changes (use the /investigate discipline, or just produce research docs). Output: one or more docs/research/2026-06-NN-*-deep-dive.md docs (mirroring the existing 2026-06-04-*-deep-dive.md set), each with:

  • The retail anchors (class::method + decomp line; LayoutDesc/element-class ids).
  • The wire-message catalog for the panel (direction, trigger, field layout, ACE handler, acdream parse status).
  • The item/container model + the UIElement_UIItem port spec.
  • The drag-drop mechanics.
  • A concrete "what the toolkit needs" list — the new generic widgets (UiItemSlot/UIElement_UIItem port, UiListBox/item-grid, the window manager) + which Type they register at — so the next session can go straight to a brainstorm → spec → plan.
  • An end-of-doc MEMORY.md index line.

Suggested approach: this is broad (3 panels × decomp + 5 references + dat + wire). A multi-agent research Workflow fits well — e.g. one agent per panel for the class/LayoutDesc/wire scoping, plus one agent on the shared UIElement_UIItem/icon-rendering/drag-drop spine, then synthesize. (Ultracode authorizes this.) Or run the panels sequentially. Either way, finish with a synthesis that names the new toolkit widgets.


6. New-session prompt (paste this into a fresh session)

Deep retail-faithful research phase (report-only, no code) for acdream's next three UI panels, building on the now-complete D.2b widget toolkit (merged to main). Read the handoff first: docs/research/2026-06-16-action-bar-inventory-equipment-handoff.md, then claude-memory/project_d2b_retail_ui.md.

Targets + confirmed retail entry points (named decomp): action bar / quick slots = gmToolbarUI (element class 0x10000007); inventory = gmInventoryUI (0x10000023) + gmBackpackUI (0x10000022); equipment/paperdoll = gmPaperDollUI (0x10000024) + gm3DItemsUI (0x10000021). Shared spine: UIElement_UIItem (0x10000032, the item-in-a-slot widget) + UIElement_ItemList (0x10000031). Items are server ACCWeenieObject weenies.

Produce a docs/research/ deep-dive per panel (+ a synthesis) answering the §3 research questions in the handoff — each with a retail anchor (class::method + decomp line / LayoutDesc + element-class id), the panel's wire-message catalog (cross-ref holtburger=client, ACE=server, Chorizite.ACProtocol=field order), the item/container model, the UIElement_UIItem port spec + icon rendering (cross-ref WorldBuilder/ACViewer for IconDataID→texture), and the drag-drop mechanics. End with a concrete "new generic widgets the toolkit needs" list (the item-slot widget, an item list/grid, the window manager) + the Type each registers at, so the following session can brainstorm → spec → plan the build. Use a multi-agent research Workflow (one agent per panel + one on the shared item-slot/icon/drag-drop spine) — Ultracode is authorized. Follow the mandatory grep-named→cross-ref→pseudocode workflow; do not write implementation code this phase.