feat(shard): the four Protocol 3.0 content screens #31
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/protocol-3-screens"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
M11 Part 2 of 2 — the screens. Stacked on #30: this targets
feat/protocol-3-visibility, so the diff shows only this part. Merge #30 first, then retarget this tomain.Every screen hangs on the visibility plumbing #30 added: each is hidden from the menu when the shard doesn't publish its feature, and each self-reports "not available here" from its own
404/403, so a deep link to a gated surface still lands on an honest answer rather than a generic error.Rules —
/public/shard/rulesetA
nullbody is a success state, not the feature being off: the shard is reachable and simply hasn't emittedworld.rulesetyet. The screen tells the two apart, since conflating them would tell an operator their config is broken when the plugin just hasn't swept.Blocks render only when published — an omitted block means the system is off, not unknown, so an empty section would assert something false. Skill caps are converted out of tenths; the raw
1000reads as a shard with ten times the usual limit. Live viaworld.ruleset, which the shard re-emits on every sidecar reconnect, so a restart with edited config updates an open screen.Leaderboards —
/public/shard/pointsBoards order most-contested first, live via
points.boardmerged through the existingLiveBoard.maxPoints: 0is uncapped, so no cap line is drawn and nothing divides by it; a cliloc-named board (nameString: null, the usual case on a real shard) falls back to the humanisedPointsTypekey. A nameless rank is a valid row — the character name is the feature's one admin-configurable field, so a shard can publish standings without naming who holds them.There is deliberately no
points.removehandling: the system set is fixed for a shard build, the same argumentcity.updatemakes.Market —
/public/shard/market+/meta+/vendors/:serialNot live, on purpose. The
marketfeature ships with its SSE fan-out disabled — a firehose of full vendor inventories would be the site's biggest bandwidth consumer — so this is a plain paginated read that never waits on a frame. It's searched on submit rather than per keystroke because it's the site's first genuinely rate-limited public endpoint.The staleness line is required, not decoration: the shard sweeps vendors round-robin, so a price can legitimately be a full cycle old, and a screen implying live prices sends someone to an item that sold twenty minutes ago.
The vendor screen is the only surface that can render the two states a result list can't — a
truncatedshop ("showing 250 of 3,104"), and a gated location, which it states as a real answer rather than leaving a blank coordinate. The nesting is what makes that clean: one admin rule takes the facet, coordinates, region and house together, so there's no half-populated location to render.Atlas —
/public/atlas/creatures[/:slug]Static shard content, so it stays readable while the shard is down — but it is site-mode gated, unlike
/shard/*. Rows lead with the server's placement label ("Despise, Felucca"), which is the point-in-rect transform the whole feature exists for; the fallback chain ends at raw coordinates, which is honest for the ~17% of stock spawns that resolve to no named place.Respawn delays are read as seconds — the unit the server's parser normalises XmlSpawner's mixed minutes/seconds into. Facet filter options are discovered from the shard's own data and a filtered page doesn't narrow them; nothing here names a facet, since a shard may add, replace or rename them.
Verified
./gradlew testDebugUnitTest— 336 tests, 0 failures (32 new). Covers the tenths conversion, uncapped-vs-zero-cap, the seconds unit, gated-location-is-null, stack counts, board ordering, live-frame merge, and each screen's404/403→ "not available"../gradlew lint— clean.The five-rung on-device walk (
v3.md§11) runs against a local website on the cutover branch before the cutover merges — that's the remaining gate, and it's why the cutover is being held.Co-Authored-Bytrailer.🤖 Generated with Claude Code
https://claude.ai/code/session_01U7CBg11prhLimL9iHSX1bP
M11 Part 2 (docs/android/PLAN.md §9), on the visibility plumbing Part 1 added. Each screen hides from the menu when the shard doesn't publish its feature, and self-reports "not available here" from its own 404/403 so a deep link still lands on an honest answer. - Rules (/public/shard/ruleset). A null body means the shard has never published a ruleset, which is a SUCCESS state, not the feature being off — the screen tells the two apart. Blocks render only when published, since an omitted block means the system is off rather than unknown. Skill caps are converted out of tenths; the raw 1000 reads as ten times the real limit. Live via world.ruleset, which the shard re-emits on every reconnect. - Leaderboards (/public/shard/points). Boards order most-contested first, live via points.board. maxPoints 0 is uncapped so no cap line is drawn, and a cliloc-named board (nameString null, the usual case) falls back to the humanised PointsType key. A nameless rank is a valid row: the character name is the feature's one admin-configurable field. - Market (/public/shard/market + /meta + /vendors/:serial). NOT live: the market feature ships with its SSE fan-out disabled, so this is a plain paginated read, searched on submit rather than per keystroke because it is the site's first rate-limited public endpoint. The staleness line is required, not decoration — the round-robin sweep means a price can be a full cycle old. The vendor screen is the only surface that can render a truncated shop and a gated location, the latter as a real answer rather than a blank coordinate. - Atlas (/public/atlas/creatures[/:slug]). Static shard content, so it stays readable while the shard is down — but site-mode gated, unlike /shard/*. Rows lead with the server's placement label ("Despise, Felucca"), which is the transform the whole feature exists for. Respawn delays are read as SECONDS, the unit the parser normalises XmlSpawner's mixed minutes/seconds into. Facet filter options are discovered from the shard's own data — nothing here names a facet, since a shard may add, replace or rename them. 336 unit tests pass (32 new); lint clean. The five-rung on-device walk runs against a local website on the cutover branch before the cutover merges. Co-Authored-By: Claude <noreply@anthropic.com>