feat(site): phase 17 - per-game module pages, /runicnpc/, and checkTerms over the built site
All checks were successful
PR checks / checks (pull_request) Successful in 2m37s

PLAN.md §16 phase 17, built on the org lead's answers of 2026-10-22,
recorded as D75-D79 (count of record 79).

- D75: core marketing pages describe what a game module adds in core's
  words. "Game intelligence" became "What a game module adds"; each
  game's own list moved to src/data/games/ and renders only on the new
  /modules/uo/ and /modules/rust/. /modules/ is a card per game.
- The page-side capability check is per game (assertGameCoverage), the
  item phase 13 moved here.
- D76: the homepage keeps its game screenshot, labelled. screens.mjs
  entries may carry `game` (D67); Screenshot.astro and the app grid
  print the game's name and mark the figure data-game.
- D77: /app/ describes the Rust screens (released the same day).
- D78: /runicnpc/, the standalone page, is in the header and footer;
  the narrow header was re-measured so five links keep two rows.
- D79: checkTerms.mjs --built reads every built page's visible text
  after the build; game routes and data-game elements allow their
  game's words. Proven against ten plants. Still the twelfth check.
- Re-read fixes: /architecture/'s "two machines is also the maximum",
  Discord "guild" on /integrations/, and collection.mjs against what
  Steam sign-in and the Rust module keep (PLAY_DATA_SAFETY.md
  regenerated; the Play answers are unchanged).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-10-22 20:10:51 -05:00
parent ec65b2d5aa
commit 56473d4d51
32 changed files with 1924 additions and 451 deletions

122
src/data/games/rust.mjs Normal file
View File

@@ -0,0 +1,122 @@
/**
* games/rust.mjs — what the Rust module adds, in Rust's own words.
*
* PLAN.md §16, phase 17. `/modules/rust/` renders this; the core pages describe what a game
* module adds in core's words and link there (D75). It is the Rust half of the coverage
* assertion phase 13 moved here: `caps` is the contract with `platform.json`'s
* `games.rust.module.capabilities`, re-read by `checkFacts.mjs` from `Module-Rust`'s own
* `module.json`, and `assertGameCoverage()` in `index.mjs` holds the two together.
*
* Every item was written from the Rust docs group, which phase 15 walked on the walk site
* and checked against the module's source (D36) — this file says less than those pages and
* nothing they do not. `rust` names the module itself rather than a surface (Module-Rust's
* README: "the single gate a whole navigation group hangs on"), so it rides on the server
* list, which is the page that gate opens.
*
* The staff items carry no `caps`: a capability is what a client feature-detects on, and
* the admin screens are not something any client detects.
*
* No `demoPath` anywhere: the demo instance planned in §15 runs Ultima Online.
*/
/** @typedef {import('../capabilities.mjs').Capability} Capability */
/** For visitors and players. @type {Capability[]} */
export const features = [
{
label: 'Every server, live',
caps: ['rust', 'servers'],
detail:
'Every Rust server the community runs, as it last reported itself: up or down, who is ' +
'on, which map, and when the next wipe is. One sidecar serves one server, so a ' +
'community with six servers sees six — and a server that is down says so while the ' +
'site carries on.',
},
{
label: 'The kill feed',
caps: ['killfeed'],
detail:
'Kills, chat, comings and goings, RunicNPC bosses, and the world itself — cargo, ' +
'helicopters, airdrops — as they happen. Every kind passes a default-deny allowlist ' +
'before it reaches a public page; staff read the rest, connection records and player ' +
'reports included.',
},
{
label: 'Leaderboards, per wipe',
caps: ['leaderboard'],
detail:
'Kills, deaths, NPC kills, structures and time played, for one wipe or all-time — with ' +
'the chat titles players have earned. The record survives the wipe: the game forgets, ' +
'and the site does not.',
},
{
label: 'Who is online',
caps: ['presence'],
detail:
'Who is on right now, and who is asleep. Nothing names a player to the public by ' +
'default: how far a name reaches — staff, signed-in players, everyone — is the ' +
'operator’s choice, made per surface.',
},
{
label: 'Wipes',
caps: ['wipes'],
detail:
'Every wipe the site has seen, and the next one once the server has a wipe schedule — ' +
'the monthly forced wipe or a rule of your own.',
},
{
label: 'The live map',
caps: ['map'],
detail:
'The server’s own map picture with layers on it: monuments and world events, the ' +
'zones and NPCs your events placed, players, bases as positions only, and a player’s ' +
'own clan. Each layer has its own audience, and positions are never stored.',
},
{
label: 'Steam accounts, linked',
caps: ['identity'],
detail:
'A player joins their Steam account to their site account with a code from /link in ' +
'game, or by signing in with Steam. Staff can undo a wrong link. Rewards go to Steam ' +
'ids, so a player earns them before they ever link.',
},
{
label: 'Clans are Teams',
detail:
'Each clan on a server is a Team on the site: a page, a feed for its members and ' +
'core’s Team notifications. Who may see a clan’s roster is set alongside who may see ' +
'a name at all.',
},
];
/** For staff, one per admin screen the module adds. @type {Capability[]} */
export const staffFeatures = [
{
label: 'Permissions and groups, from the site',
detail:
'The site holds every server’s Oxide or Carbon groups and permissions and pushes them ' +
'in. One vip on the site is one vip in game, on the servers it covers, and a change ' +
'made in game is noticed rather than silently kept.',
},
{
label: 'Mod config, from the site',
detail:
'Edit your plugins’ config files on the game host from the admin panel, with a backup ' +
'first, a watched reload, and an automatic undo if the plugin does not come back.',
},
{
label: 'Events, zones and rewards',
detail:
'Rust steps for core’s scheduled events: open a ZoneManager zone with a dome, place ' +
'NPCs, count who is present, reward a kit, pay coins, start a raid base, or run ' +
'console commands. Every step arrives switched off, on the server as well as on the ' +
'site.',
},
{
label: 'Optional plugins, recognised',
detail:
'BetterChat, Economics, Backpacks, TruePVE, Dynamic PVP, Dangerous Treasures, Guarded ' +
'Crate, RaidableBases and more each add something where they are installed: coins, ' +
'titles, map layers, event steps. None is required.',
},
];