docs(plan): Slice 5 vendor-browse contract — research doc + the eight decisions + ordered 5.0-5.5 work
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
fa0c053ebf
commit
763b127ad9
2 changed files with 780 additions and 0 deletions
|
|
@ -554,3 +554,80 @@ already published per frame to `EntityEffectPoseRegistry` (`PublishChildPose`,
|
|||
- Existing architectural divergence, unchanged by this slice: retail re-arms
|
||||
the pick every frame for hover/tooltips (`sr_MouseOver`); acdream picks on
|
||||
demand per click against the last published frame, with an identity recheck.
|
||||
|
||||
## Slice 5 — vendor browse lifecycle (contract authored 2026-08-08)
|
||||
|
||||
**Research foundation:**
|
||||
`docs/research/2026-08-08-slice5-vendor-browse-research.md` (all wire,
|
||||
retail-symbol, and seam citations live there — this contract only records
|
||||
DECISIONS and ordered work). Browse only; every buy/sell/accept concern is
|
||||
Slice 6 (see the research doc's §D fence).
|
||||
|
||||
### Decisions on the research doc's eight open questions
|
||||
|
||||
1. `VendorState` lives in `AcDream.Core.Items`, a sibling of
|
||||
`ExternalContainerState`.
|
||||
2. The shared `PublicWeenieDesc`-body parser IS extracted from
|
||||
`CreateObject.TryParse` FIRST, as its own behavior-preserving commit
|
||||
(5.0). Existing CreateObject wire tests must pass unchanged; the
|
||||
extraction adds no parsing behavior.
|
||||
3. `ShopSystem::BuyPrice`/`SellPrice` (0x006B6120/0x006B6180,
|
||||
byte-identical to ACE's `GetBuyCost`/`GetSellCost`) are ported NOW as
|
||||
pure Core functions with golden-value conformance tests — the browse
|
||||
list shows retail-correct prices from day one.
|
||||
4. No request-correlation token in Slice 5: the panel always opens on the
|
||||
browse/Buy tab. Slice 6 adds the sell-initiated correlation.
|
||||
5. `VendorProfile::InqAcceptability` (which player items the vendor would
|
||||
accept) is deferred to Slice 6 with the sell UI it gates.
|
||||
6. Category/type filter tabs are IN SCOPE for retail parity. The
|
||||
implementer's D0 reads `VendorItemsUI::AddTypeFilter` /
|
||||
`ListContainsType` (around 0x004C05C0/0x004C0D90) into a pseudocode
|
||||
note before any UI work; if that read reveals a mechanism too large
|
||||
for this slice, STOP and report (fallback — flat list + register row —
|
||||
requires explicit approval, not implementer discretion).
|
||||
7. The vendor panel's top-level LayoutDesc id is NOT yet known: the UI
|
||||
piece budgets a LayoutImporter discovery pass (the exact process that
|
||||
found the examination window's 0x2100006B), cross-checked by the two
|
||||
known tab-control ids (0x100000B9 Buy / 0x100000BB Sell) resolving
|
||||
under the candidate root.
|
||||
8. AP-110 is narrowed in the SAME COMMIT that lands the panel: "vendor"
|
||||
leaves the absent-panels list; whatever sub-scope remains absent after
|
||||
this slice gets its own precise row.
|
||||
|
||||
### Ordered work (each lands separately, bisectable)
|
||||
|
||||
- **5.0** — extract the shared `PublicWeenieDesc`-body parser
|
||||
(behavior-preserving; wire tests unchanged; no vendor code).
|
||||
- **5.1** — `ApproachVendor` (GameEvent 0x0062) inbound parser:
|
||||
`VendorProfile` + the full-desc item list, against the research doc's
|
||||
byte-verified field table; Core.Net tests with golden byte fixtures.
|
||||
- **5.2** — `VendorState` in Core.Items + the BuyPrice/SellPrice pure
|
||||
port + conformance tests.
|
||||
- **5.3** — Runtime ownership: `RuntimeInventoryState` owns the vendor
|
||||
session per the J4.2 pattern (generation-gated, torn down on
|
||||
reset/portal/logout); the 0x0062 route opens it; close is CLIENT-LOCAL
|
||||
(nothing sent on the wire) via the retail distance-watcher semantics;
|
||||
`ItemInteractionController._activeVendorId` /
|
||||
`ItemInteractionPolicy.ActiveVendorId` finally receive the real id.
|
||||
- **5.4** — the authored vendor panel: layout-id discovery, LayoutDesc
|
||||
import via the Slice-3 examination-window pattern (foreground stacking,
|
||||
authored extent), browse list reusing Slice-1's retained list/scrollbar
|
||||
+ DAT icon resolution, category tabs per the D0 read, prices via 5.2.
|
||||
- **5.5** — register narrowing (decision 8) rides the 5.4 landing commit.
|
||||
|
||||
### Trap list (binding)
|
||||
|
||||
Do not touch: the J5.2 strict use gate's semantics (the vendor open rides
|
||||
the EXISTING use transaction — no second gate, per the J4.5 invariant);
|
||||
`CreateObject.TryParse` behavior (5.0 is extraction only); anything in the
|
||||
Slice 6 fence (no buy/sell wire, no currency mutation, no
|
||||
InqAcceptability). New event handling follows the newest existing
|
||||
GameEvent handler's registration pattern, not a bespoke route.
|
||||
|
||||
### Gates
|
||||
|
||||
Per landing: build + full suite green (clean-room before each landing
|
||||
commit). Slice gate (user, connected, ~3 min): approach a Holtburg
|
||||
vendor, use them, the authored panel opens on the browse tab with
|
||||
retail-correct items/icons/prices; category tabs filter; walking out of
|
||||
range closes the panel by itself; nothing is purchasable anywhere.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue