Files
docs/website/SHARD_VISIBILITY.md
wtclaude 6ce60a82c3 docs(link): the player-vendor marketplace (Protocol 3.0 §8)
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>
2026-07-29 09:52:14 -05:00

9.0 KiB

Shard visibility — who sees which shard data

Status: Built (Protocol 3.0 Part A). Admin → Shard Visibility. Audience: shard owners and admins. Companion to ../link/v3.md §3 (the design) and BACKEND_DESIGN.md §6 (the security contract).

The website surfaces a lot of live shard data. What your players, your staff and the anonymous internet may each see is yours to decide, per feature, from Admin → Shard Visibility.

Nothing changes until you change it: every setting ships at the value that reproduces how the site behaved before this panel existed.


1. The audience ladder

Five rungs. Each one includes everyone below it.

Rung In the UI Who that is
anonymous Everyone Anyone at all, signed in or not.
logged_in Signed in Any registered account, whether or not they've linked a game account.
player Linked players Accounts with a linked in-game account. Staff always qualify, linked or not.
staff Staff Admins and moderators.
admin Admins only Admins.

Two notes that surprise people:

  • editor is a content role, not a shard role. Editors write news and wiki pages; they get no shard privilege from that. An editor is treated by link status like any other member. This matches the rest of the site, where shard staff powers are admin-or-moderator.
  • Staff satisfy player without linking. Otherwise an admin would be locked out of surfaces they'd gated to players, which is how the /player/* routes already behave.

2. What you can set per feature

Enabled. Off means gone. The feature's pages return “not found”, not “forbidden” — a disabled feature doesn't advertise that it exists.

Who can see it. The minimum rung, from the ladder above.

Live updates. Whether this feature pushes changes to open pages in real time. Turning it off doesn't break the page; it just refreshes on load instead of updating in place.

Sensitive fields. Some features expose a field that deserves its own rung — you can publish the board while holding back one column. See the table in §3.

3. The features, and their defaults

Feature What it exposes Default Sensitive fields
Shard status Connection state, online count, gold-supply series Everyone
Activity feed Deaths, kills, skill gains, quests, logins Everyone
Champion spawns The live champion / mini-champ / sea-boss board Everyone
Guilds Guild rosters, alliances, leaders Everyone
Town governors City Loyalty governors, elections, term history Everyone
Houses / IDOC Houses in danger Everyone House owner → Staff · House price → Staff
Players online Population aggregate, staff-online widget Everyone In-game location → Staff
Shard rules Skill/stat caps, house limits, vet rewards, the ruleset Everyone Connect address → Everyone
Spawn atlas Bestiary and spawn locations (static content) Everyone
Leaderboards Point and loyalty standings Everyone Character names → Everyone
Marketplace The shard-wide player-vendor index Everyone, live updates off Vendor owner name → Everyone · Vendor owner character id → Everyone · In-game location → Everyone

Why the marketplace ships with live updates off. A live feed of every vendor's full inventory would be the single largest thing the site sends. No page needs it — the marketplace is a search over stored data with a “prices last refreshed N minutes ago” stamp. Turn it on only if you want it.

Why the marketplace's fields default to Everyone. A vendor's shop name, its owner's character name and where it is standing are already visible to every player in game: the stock Vendor Search gump surfaces exactly that set to anyone who opens it. Publishing them on the site is not a new disclosure. They stay configurable because a shard may still prefer to keep its economy behind a login — and because "already public in game" is a judgement about your shard, not ours.

Location is one setting covering four things. Hiding it removes the facet, the coordinates, the region and the house name together. That is deliberate: those are four ways of saying the same thing, and a setting that hid the coordinates while publishing the house name would not have hidden anything.

Hiding the owner name also hides the owner character id. They are separate settings so you can be explicit, but leaving the id published while hiding the name achieves nothing — the leaderboards and guild boards resolve that same id back to a character name. Set both.

What hiding a vendor cannot do. Only vendors whose owner left the in-game Vendor Search flag ON are ever sent to the site, so a player who hides their shop in game is hidden here too — and no setting on this page can override that. It works the other way as well: these settings control who sees the index, not whether players can find each other's shops in game.

Why house owner/price default to Staff. The public Houses page has always been a "where are the falling houses" board — location only. Owner and price are the staff view. That split is preserved.

4. What you cannot change

Two rules are enforced in code and are not settings. Attempting to set them returns an error rather than silently ignoring you.

1. Game account names and website user ids are admin-only, always. acct and webId never appear below the admin rung on any surface. A character name is visible in game to anyone standing next to them; the account behind it is not, and neither is the website user it's linked to. Publishing those would disclose something the shard itself doesn't, and would tie a player's in-game identity to their forum identity without their consent.

This rule matches the meaning of a field, not one spelling of it. Some responses nest the player who owns a record (leader.acct); others flatten it into the row (ownerAcct, leaderWebId, governorAcct). Every one of those is locked, and the admin API refuses to configure any of them — so a new response shape can't quietly reopen the hole by naming the field differently.

2. Unknown event kinds are never broadcast below admin. The live stream maps each event kind to a feature. A kind with no mapping — a new event from a shard plugin the site doesn't know yet, say — goes to admins only. It fails closed. This is what keeps the stream safe by default when the shard starts sending something new: the worst case is that staff see it and players don't, never the reverse.

5. How it's enforced

Three places, one config:

  • Page and API requests are checked before the handler runs, and the response is then stripped of any field above the caller's rung.
  • The live stream resolves a viewer's rung once, when they connect, and freezes it for that connection — a long-open page can't gain privilege because something changed underneath it. Each event is then gated and stripped per viewer, so two people watching the same page can legitimately receive different versions of the same event, or one of them nothing.
  • Navigation hides links a viewer can't follow, so they don't hit a wall. This is presentation only — the gate is server-side either way.

Stored history answers the same way the live stream does. The activity feed reads from the event log rather than the live stream, but it resolves the same question against the same config: which kinds you may read, and which fields survive. So moving a feature up a rung hides it from the history as well as the stream — there is no back door where yesterday's copy of an event is more revealing than today's.

One deliberate asymmetry: turning live updates off for a feature stops the push, not the reading. The marketplace ships this way — its history and its pages are public, only the firehose is off.

Changes take effect within about five seconds, including on streams that are already open. You don't need to restart anything.

If the database is briefly unreachable, the site falls back to the built-in defaults — the pre-v3 behavior — rather than to "everything is public".

6. Worked examples

"I want a private shard — nothing public until people register." Set every feature to Signed in. Anonymous visitors still get the site itself; the shard data disappears from the nav.

"Publish the market, but don't tie vendors to players." Marketplace → Everyone, with Vendor owner name → Staff. Prices, items and locations stay public; who owns each vendor doesn't.

"Leaderboards for members only." Leaderboards → Linked players. Anyone who's linked a game account sees the standings; drive-by visitors don't.

"Let players see house owners." Houses → Everyone, House owner → Linked players. Note this is a real disclosure: house ownership is visible in game, but the website makes it searchable in a way the game doesn't.