docs(link): the player-vendor marketplace (Protocol 3.0 §8) #71

Merged
whitlocktech merged 1 commits from docs/vendor-listing into edge 2026-07-29 20:02:36 +00:00
Member

What & why

Documentation for Protocol 3.0 order 5bvendor.listing, the player-vendor marketplace — across the four repos: servuo-plugins #5, link #19, website #116.

NEW website/MARKETPLACE.md

The operator guide. Leads with the three things the pages are required to say out loud, because each is a consequence of how the data is gathered rather than a UI preference: the prices are not live (round-robin sweep), a shop can be truncated, and an item may have no name.

Also documents the privacy contract in one place — the player's own in-game Vendor Search toggle wins, and no admin setting overrides it — plus the Bridge.cfg knobs, how they trade against each other, and the measured sweep costs with the arithmetic behind the slow-tick warning.

link/INTEGRATION.md

Catalog entry for vendor.listing / vendor.listing.remove with six consumer gotchas (the other 3.0 kinds needed four; this one has more surface). The ones most likely to be got wrong: name is null for nearly every item and cliloc is the real label; child: true means the price buys the enclosing container, so printing it against each item inside is a lie about the shard; and processing the remove promptly is how a player revoking consent reaches you.

Plus the GET /market REST section — the sidecar's only paged read, and why it orders by serial rather than shop name (a rename mid-walk would otherwise make a vendor skip or repeat a page).

website/BACKEND_DESIGN.md

shard_vendors / shard_vendor_items, the three routes, and the marketplace search recorded as the only rate-limited public read on the site — with why it earns that when nothing else does.

Explains the two columns that carry non-obvious meanings (item_count vs item_total; display_name being denormalized and re-resolved after a cliloc import) and why updated_at is written explicitly rather than left to ON UPDATE CURRENT_TIMESTAMP.

website/SHARD_VISIBILITY.md

Why the market's fields default to Everyone — the in-game gump already shows exactly that set to any player, so publishing it is not a new disclosure, and "already public in game" is a judgement about your shard rather than ours. Also: why location is one setting covering four things, and why hiding the owner name while leaving the owner id published achieves nothing.

link/PLAN.md

The amortized round-robin recorded as the one sweep pattern the bridge did not previously have, with the measured numbers.

Also updates §7's cliloc note, which had recommended resolving names website-side to avoid a server-side dependency on the client directory. That recommendation held — but the real reason is stronger than the one given: ServUO cannot resolve clilocs either, because every current client ships them compressed and the bundled Ultima.StringList reads only the older plain layout. Pushing name resolution to the plugin was never an option, and the in-game Vendor Search gump has the same gap.

link/v3.md §8.8 — what the build changed

Four things the implementation settled differently from §8 as written, chief among them:

§8.1's payload sketch had location FLAT (map/x/y/region), which would have made Part A's pre-wired market.location rule inertprojectValue matches literal JSON keys, so there would have been no location key to match. Exactly the characterName miss §7.5 records, one part later. Nesting it makes one rule cover the facet, coordinates, region and house on both the live frame and the stored read model.

Also: the diff signature is the full listing set rather than §8.3's count | Σ(serial ^ price) (which collides on two items swapping prices — i.e. on re-pricing a shop); there is no payload column on shard_vendors despite §8.5 implying the board pattern; and sweep cost is now reported because the batch cap is a claim about it.

Also

README.md gained index rows for MARKETPLACE.md and — while there — for SPAWN_ATLAS.md and CLILOCS.md, which were both missing. An index listing one of three sibling docs is worse than no index.

How it was tested

Prose only. Every code reference, measured number and behaviour described here was taken from the live runs recorded in the three implementation PRs (real shard: 209k items / 43k mobiles / 27 player vendors / 1,040 listings), not from the design as written — §8.8 exists precisely because the two diverged.

Progress tables in §Progress and §9 updated: 5a → Done, 5b → In review. Only the cutover (order 6) remains.

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

  • No AI tools were used to produce this contribution.
  • AI tools were used. Tool(s): Claude Code (Opus 5). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a Co-Authored-By trailer.

License

  • I agree that my contribution is licensed under this project's license (GNU GPL v3.0 or later), and I have the right to contribute it.
## What & why Documentation for Protocol 3.0 **order 5b** — `vendor.listing`, the player-vendor marketplace — across the four repos: servuo-plugins #5, link #19, website #116. ### NEW `website/MARKETPLACE.md` The operator guide. Leads with the three things the pages are *required* to say out loud, because each is a consequence of how the data is gathered rather than a UI preference: the prices are not live (round-robin sweep), a shop can be truncated, and an item may have no name. Also documents the privacy contract in one place — **the player's own in-game Vendor Search toggle wins, and no admin setting overrides it** — plus the `Bridge.cfg` knobs, how they trade against each other, and the measured sweep costs with the arithmetic behind the slow-tick warning. ### `link/INTEGRATION.md` Catalog entry for `vendor.listing` / `vendor.listing.remove` with **six** consumer gotchas (the other 3.0 kinds needed four; this one has more surface). The ones most likely to be got wrong: `name` is null for nearly every item and `cliloc` is the real label; `child: true` means the price buys the **enclosing container**, so printing it against each item inside is a lie about the shard; and processing the `remove` promptly is how a player *revoking* consent reaches you. Plus the `GET /market` REST section — the sidecar's only paged read, and why it orders by **serial** rather than shop name (a rename mid-walk would otherwise make a vendor skip or repeat a page). ### `website/BACKEND_DESIGN.md` `shard_vendors` / `shard_vendor_items`, the three routes, and the marketplace search recorded as **the only rate-limited public read** on the site — with why it earns that when nothing else does. Explains the two columns that carry non-obvious meanings (`item_count` vs `item_total`; `display_name` being denormalized and re-resolved after a cliloc import) and why `updated_at` is written explicitly rather than left to `ON UPDATE CURRENT_TIMESTAMP`. ### `website/SHARD_VISIBILITY.md` Why the market's fields default to *Everyone* — the in-game gump already shows exactly that set to any player, so publishing it is not a new disclosure, and "already public in game" is a judgement about your shard rather than ours. Also: why **location is one setting covering four things**, and why hiding the owner name while leaving the owner id published achieves nothing. ### `link/PLAN.md` The **amortized round-robin** recorded as the one sweep pattern the bridge did not previously have, with the measured numbers. Also updates §7's cliloc note, which had recommended resolving names website-side to avoid a server-side dependency on the client directory. That recommendation held — but the real reason is stronger than the one given: **ServUO cannot resolve clilocs either**, because every current client ships them compressed and the bundled `Ultima.StringList` reads only the older plain layout. Pushing name resolution to the plugin was never an option, and the in-game Vendor Search gump has the same gap. ### `link/v3.md` §8.8 — what the build changed Four things the implementation settled differently from §8 as written, chief among them: **§8.1's payload sketch had `location` FLAT** (`map`/`x`/`y`/`region`), which would have made Part A's pre-wired `market.location` rule **inert** — `projectValue` matches literal JSON keys, so there would have been no `location` key to match. Exactly the `characterName` miss §7.5 records, one part later. Nesting it makes one rule cover the facet, coordinates, region and house on both the live frame and the stored read model. Also: the diff signature is the full listing set rather than §8.3's `count | Σ(serial ^ price)` (which collides on two items swapping prices — i.e. on re-pricing a shop); there is no `payload` column on `shard_vendors` despite §8.5 implying the board pattern; and sweep cost is now reported because the batch cap is a *claim* about it. ### Also `README.md` gained index rows for `MARKETPLACE.md` and — while there — for `SPAWN_ATLAS.md` and `CLILOCS.md`, which were both missing. An index listing one of three sibling docs is worse than no index. ## How it was tested Prose only. Every code reference, measured number and behaviour described here was taken from the live runs recorded in the three implementation PRs (real shard: 209k items / 43k mobiles / 27 player vendors / 1,040 listings), not from the design as written — §8.8 exists precisely because the two diverged. Progress tables in §Progress and §9 updated: 5a → Done, 5b → In review. Only the cutover (order 6) remains. ## Checklist - [x] I have read [CONTRIBUTING.md](CONTRIBUTING.md). - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) - [ ] No AI tools were used to produce this contribution. - [x] AI tools were used. Tool(s): `Claude Code (Opus 5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` trailer. ## License - [x] I agree that my contribution is licensed under this project's license (**GNU GPL v3.0 or later**), and I have the right to contribute it.
wtclaude added 1 commit 2026-07-29 14:57:00 +00:00
Documents order 5b across the four repos, and records what building it changed
about §8 as designed.

- NEW website/MARKETPLACE.md — the operator guide: what the pages must say out
  loud and why, the privacy contract (the player's in-game Vendor Search toggle
  wins, and no admin setting overrides it), the Bridge.cfg knobs and how they
  trade against each other, and the measured sweep costs.
- INTEGRATION.md — catalog entry for vendor.listing / vendor.listing.remove with
  its six consumer gotchas, and the GET /market REST section (the sidecar's only
  paged read, and why it orders by serial rather than shop name).
- BACKEND_DESIGN.md — shard_vendors / shard_vendor_items, the routes, and the
  marketplace search as the only rate-limited public read.
- SHARD_VISIBILITY.md — why the market's fields default to Everyone (the in-game
  gump already shows exactly that set), why location is one setting covering
  four things, and why hiding the owner name without the owner id achieves
  nothing.
- PLAN.md — the amortized round-robin as the one sweep pattern the bridge did not
  previously have, and an update to §7's cliloc note: pushing name resolution to
  the plugin was never an option, because ServUO cannot read a modern client's
  compressed cliloc files either.
- v3.md §8.8 — the four things the build settled differently, chief among them
  that §8.1's FLAT location payload would have made Part A's pre-wired
  market.location rule inert, exactly like the characterName miss one part
  earlier.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit cdea1aa7cd into edge 2026-07-29 20:02:36 +00:00
whitlocktech deleted branch docs/vendor-listing 2026-07-29 20:02:37 +00:00
Sign in to join this conversation.
No description provided.