Roadmap: refresh the D.5.2 entry to its final shipped state (per-pixel gradient surface overload 0x004415b0; AP-43/AP-44 retired by visual verification; range 419c3ac..fb288ad). Add an explicit D.5 sub-phase ledger: D.5.4 client object/item data model (foundation, NEXT) -> D.5.3 selected-object + spell shortcuts -> window manager -> D.5.5+ core panels. Handoff doc gains a paste-ready new-session prompt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
120 lines
7.7 KiB
Markdown
120 lines
7.7 KiB
Markdown
# Handoff — the client object/item data model (next phase, post-D.5.2)
|
||
|
||
**Date:** 2026-06-18
|
||
**From:** the D.5.2 stateful-icon session (icon system SHIPPED + visually confirmed on a
|
||
live Coldeve server). This handoff frames the NEXT phase: the real item/object data model.
|
||
**Status of this work:** branch `claude/hopeful-maxwell-214a12` (kept, not merged). D.5.2 is
|
||
complete: `52306d9..fb288ad`.
|
||
|
||
---
|
||
|
||
## 0. Why this phase exists (the root cause we uncovered)
|
||
|
||
Visual-verifying D.5.2 on a live server (character **Barris** on Coldeve) showed **4 of 6
|
||
hotbar items render no icon**. The diagnostic (`icon-dump.txt`, since removed) proved the
|
||
cause: those items are **`NOT-ENRICHED`** — `ItemRepository.GetItem(guid)` returns null
|
||
because their `CreateObject` was **dropped**.
|
||
|
||
The mechanism is acdream's **scaffold item model**:
|
||
- `EnrichItem` is **enrich-existing-only**: it updates an item ONLY if it was already seeded
|
||
as a stub (from `PlayerDescription` at login). A `CreateObject` for an item with no
|
||
pre-existing stub is silently discarded (the toolbar handoff called this out:
|
||
*"new-item ingestion is the inventory phase"*).
|
||
- So only items in the login seed set get icons; everything else (most pack contents) falls
|
||
on the floor. The 2 that showed (Energy Crystal, Revenant's Scythe) are wielded items the
|
||
server announces up front.
|
||
|
||
This is **NOT a D.5.2 bug** (the icon composite is correct for every item that reaches it —
|
||
confirmed: Energy Crystal's Magical gradient tint + the no-mana scroll's black edges both
|
||
match retail). It is the **item/object data model** being a placeholder.
|
||
|
||
## 1. The retail model to port (the oracle)
|
||
|
||
Retail has **one master object table** — `ClientObjMaintSystem` — and **`CreateObject` is the
|
||
canonical create/update for every object** (item, creature, player). The UI never owns item
|
||
data: a hotbar slot, an inventory cell, a paperdoll slot, a vendor cell all hold a `guid` and
|
||
resolve it live via `ClientObjMaintSystem::GetWeenieObject(guid)`. (Confirmed in our spine
|
||
research: *"the cell never holds item data — it holds an itemID and resolves it live."*)
|
||
|
||
acdream **inverted** this: login snapshot = source of truth, `CreateObject` = second-class
|
||
enrich. The fix is to flip it: **`CreateObject` is the authoritative ingestion**;
|
||
`PlayerDescription` / `ViewContents (0x0196)` / shortcuts become **references + supplementary
|
||
data**, not the primary seed. Every object the server tells us about is tracked; the UI
|
||
resolves by guid.
|
||
|
||
## 2. THE crux design question (settle this FIRST in the brainstorm)
|
||
|
||
acdream currently has **two object tracks**:
|
||
- the **WorldEntity** system (3D creatures / players / world items, fed by `CreateObject` →
|
||
`GameWindow.OnLiveEntitySpawned` → `WorldEntity`), and
|
||
- the **ItemRepository** (inventory items, `src/AcDream.Core/Items/`).
|
||
|
||
Retail unifies these under one `ClientObjMaintSystem` (every object is an `ACCWeenieObject`).
|
||
**Decision to make:** unify acdream into ONE object table (retail shape), or keep the two
|
||
tracks with a shared ingestion seam? This choice drives everything downstream (inventory,
|
||
equipment/paperdoll, vendor, trade all resolve items from whatever table wins). Think it
|
||
through up front — don't discover it halfway in.
|
||
|
||
## 3. Sources that feed the model (the ingestion surface to design around)
|
||
|
||
| Wire message | Role |
|
||
|---|---|
|
||
| `CreateObject (0xF745)` | **canonical** object create/update (full weenie: icon/name/type/stack/container/wielder/effects/…) |
|
||
| `DeleteObject (0xF747)` | remove |
|
||
| `PlayerDescription (0x0013)` | login snapshot: inventory + equipped + shortcuts (references; some props) |
|
||
| `ViewContents (0x0196)` | a container's `{guid, slot}` list when opened |
|
||
| move events `0x0019/1A/1B`, `0x0022/23`, `0x019A` | re-parent (container/wield/3D) |
|
||
| `Public/PrivateUpdateProperty* (0x02CD–0x02DA)` | per-property live updates (D.5.2 wired `0x02CE` UiEffects → icon) |
|
||
| `InventoryServerSaveFailed (0x00A0)` | speculative-move rollback |
|
||
|
||
## 4. Grounding research (already written — read before the brainstorm)
|
||
|
||
- `docs/research/2026-06-16-inventory-deep-dive.md` — inventory panel + the wire catalog
|
||
- `docs/research/2026-06-16-ui-item-slot-icon-dragdrop-spine-deep-dive.md` — `ClientObjMaintSystem`,
|
||
`ServerSaysMoveItem`, the resolve-by-guid model
|
||
- `docs/research/deepdives/r06-items-inventory.md` — the item/container property model
|
||
- `docs/research/2026-06-16-ui-panels-synthesis.md` — core-panels build order (item-model is
|
||
the prerequisite for the inventory panel)
|
||
- `claude-memory/project_d2b_retail_ui.md` — D.2b/D.5.1/D.5.2 state
|
||
- `claude-memory/feedback_weenie_vs_static.md` — items are server weenies, not dat-baked
|
||
|
||
## 5. Recommended approach
|
||
|
||
Full process (the user values it): **brainstorm → spec → plan → subagent implementation.**
|
||
Open the brainstorm on **the unify-vs-separate question (§2) first**, then the ingestion
|
||
lifecycle (§3), then how the UI (toolbar/inventory/paperdoll) binds by guid. This is the
|
||
foundation the remaining D.5 core panels sit on — get it solid.
|
||
|
||
NOTE the user's standing constraint for this phase: *"No quick fixes — needs to be
|
||
architecturally solid and thought through."* Do not band-aid `EnrichItem` to add new items;
|
||
design the model properly.
|
||
|
||
## 6. New-session prompt (paste into a fresh session)
|
||
|
||
> Design and build acdream's **client object/item data model** — the foundation under the D.5
|
||
> core panels (inventory, equipment/paperdoll, vendor, trade). This is roadmap **D.5.4** and it
|
||
> blocks D.5.5+. **Read this handoff first: `docs/research/2026-06-18-item-object-model-handoff.md`**,
|
||
> then `docs/research/2026-06-16-ui-item-slot-icon-dragdrop-spine-deep-dive.md` and
|
||
> `docs/research/2026-06-16-inventory-deep-dive.md`.
|
||
>
|
||
> The problem (confirmed live on Coldeve, character Barris): acdream's item model is
|
||
> **enrich-existing-only** — `ItemRepository.EnrichItem` only fills items pre-seeded as stubs
|
||
> from `PlayerDescription`, and DROPS `CreateObject`s for anything else, so most hotbar/pack
|
||
> items render no icon (4 of 6 hotbar slots were blank). Port retail's `ClientObjMaintSystem`:
|
||
> **`CreateObject` is the canonical object create/update**, `PlayerDescription`/`ViewContents`/
|
||
> shortcuts become references, and the UI resolves items by guid. This is NOT a D.5.2 icon bug
|
||
> (the composite is correct for every item that reaches it).
|
||
>
|
||
> **Do this as a proper design — the user's standing constraint is "architecturally solid, no
|
||
> quick fixes" (do NOT band-aid `EnrichItem` to add new items).** Use the full
|
||
> brainstorm → spec → plan → subagent-driven-development flow. **Open the brainstorm by settling
|
||
> the crux FIRST (§2): unify acdream's two object tracks — the `WorldEntity` 3D system (fed by
|
||
> `GameWindow.OnLiveEntitySpawned`) and `ItemRepository` — into ONE object table like retail, or
|
||
> keep them separate with a shared ingestion seam?** Then the ingestion lifecycle (§3 wire
|
||
> surface) and how the toolbar/inventory/paperdoll bind by guid. Follow the mandatory
|
||
> grep-named→cross-ref→pseudocode→port workflow for any AC-specific wire format; conformance
|
||
> tests throughout. Work continues on branch `claude/hopeful-maxwell-214a12` (kept, unmerged;
|
||
> D.5.2 = `52306d9..fb288ad`).
|
||
|
||
**MEMORY.md index line:**
|
||
- [Handoff: client object/item data model (2026-06-18)](research/2026-06-18-item-object-model-handoff.md) — next phase after D.5.2. Root cause of the live-Coldeve "4/6 hotbar items missing": acdream's item model is enrich-existing-only (drops CreateObjects without a pre-seeded stub). Fix = port retail's `ClientObjMaintSystem` (CreateObject = canonical ingestion; UI resolves by guid). CRUX to settle first: unify the WorldEntity + ItemRepository tracks into one object table, or keep separate w/ shared ingestion? Grounding research + ingestion surface listed. User constraint: architecturally solid, no quick fixes.
|