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
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:
117
src/data/games/uo.mjs
Normal file
117
src/data/games/uo.mjs
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* games/uo.mjs — what the Ultima Online module adds, in Ultima Online's own words.
|
||||
*
|
||||
* PLAN.md §16, phase 17. Until this phase these items were the "Game intelligence" group of
|
||||
* `capabilities.mjs`, which the homepage and `/features/` render — core pages, which D63
|
||||
* says may name the games but not use their vocabulary. They moved here, to a file that
|
||||
* belongs to one game, and `/modules/uo/` renders them. The core pages now describe what a
|
||||
* game module adds in core's words and link here (D75).
|
||||
*
|
||||
* `caps` is the contract with `platform.json`'s `games.uo.module.capabilities`, which
|
||||
* `checkFacts.mjs` re-reads from the module's own `module.json`. `assertGameCoverage()` in
|
||||
* `index.mjs` fails the build when the two drift apart, in either direction — so the day the
|
||||
* module gains a capability, the JSON goes red, and the day the JSON moves, this page does.
|
||||
*
|
||||
* Slugs are NOT one-per-item: `shard` is the source of four separate user-facing features,
|
||||
* and the marketplace draws on `market` and `cliloc` together (item names arrive as cliloc
|
||||
* ids and are resolved against the shard's own string table). Coverage, not a bijection.
|
||||
*
|
||||
* `demoPath` is a stable public route on the module's own pages, deep-linked into a demo
|
||||
* when one is mounted (D25). Paths are read from `module-uo`'s `client/src/entry.jsx`.
|
||||
*/
|
||||
|
||||
/** @typedef {import('../capabilities.mjs').Capability} Capability */
|
||||
|
||||
/** @type {Capability[]} */
|
||||
export const features = [
|
||||
{
|
||||
label: 'Live shard status',
|
||||
caps: ['shard'],
|
||||
demoPath: '/uo/shard',
|
||||
detail:
|
||||
'Whether the shard is up, who is on it, and how long ago the site last heard from it. ' +
|
||||
'When the game is down this page is the thing that says so — the site does not go ' +
|
||||
'down with it.',
|
||||
},
|
||||
{
|
||||
label: 'Economy and activity',
|
||||
caps: ['shard'],
|
||||
demoPath: '/uo/shard/activity',
|
||||
detail:
|
||||
'A live feed of what is happening in the world, and the economy underneath it. Every ' +
|
||||
'event passes an allowlist before it can reach a public page; staff read a second ' +
|
||||
'stream carrying the rest.',
|
||||
},
|
||||
{
|
||||
label: 'Character sheets',
|
||||
caps: ['shard'],
|
||||
detail:
|
||||
'Skills, stats and equipment, drawn from the live world rather than from a form ' +
|
||||
'somebody filled in. Reachable by the account the character is linked to, and by ' +
|
||||
'staff — not by the public.',
|
||||
},
|
||||
{
|
||||
label: 'Points and loyalty boards',
|
||||
caps: ['shard'],
|
||||
demoPath: '/uo/leaderboards',
|
||||
detail:
|
||||
'The leaderboards the shard already keeps, published without anyone exporting a ' +
|
||||
'spreadsheet on a Sunday.',
|
||||
},
|
||||
{
|
||||
label: 'Player-vendor marketplace',
|
||||
caps: ['market', 'cliloc'],
|
||||
demoPath: '/uo/market',
|
||||
detail:
|
||||
'Every player vendor on the shard and what is on it, searchable without logging in to ' +
|
||||
'the game. Item names arrive from the world as cliloc ids and are resolved against the ' +
|
||||
"shard's own string table, so they read as names rather than numbers — beside the " +
|
||||
"item's own picture, in the colour it was dyed.",
|
||||
},
|
||||
{
|
||||
label: 'Houses and IDOC decay',
|
||||
caps: ['houses'],
|
||||
demoPath: '/uo/houses',
|
||||
detail:
|
||||
'Who owns what and where it stands, including which houses are decaying — published ' +
|
||||
'while it is still information rather than after it has become a rumour.',
|
||||
},
|
||||
{
|
||||
label: 'Spawn atlas',
|
||||
caps: ['atlas'],
|
||||
demoPath: '/uo/atlas',
|
||||
detail:
|
||||
"A bestiary and spawn map built by reading your shard's own spawn tables, so it " +
|
||||
"describes your server rather than someone else's idea of the game. Regions, " +
|
||||
'landmarks and champion altars come with it, and each creature is shown as the ' +
|
||||
'artwork your own client draws it with.',
|
||||
},
|
||||
{
|
||||
label: 'Champion boards',
|
||||
caps: ['champs'],
|
||||
demoPath: '/uo/champs',
|
||||
detail: 'Which altars are running, how far along they are, and what turned up.',
|
||||
},
|
||||
{
|
||||
label: 'Guilds',
|
||||
caps: ['guilds'],
|
||||
demoPath: '/uo/guilds',
|
||||
detail:
|
||||
'Guild rosters and standings, kept in step with the shard. Each guild is also a Team ' +
|
||||
'on the site, with the forum, the notifications and the voice channel that core ' +
|
||||
'attaches to one.',
|
||||
},
|
||||
{
|
||||
label: 'City governors',
|
||||
caps: ['governors'],
|
||||
demoPath: '/uo/governors',
|
||||
detail: 'Who holds which city, and what they did with it.',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* The screenshots `/modules/uo/` shows beside the list, by id from `screens.mjs`. Every one
|
||||
* is tagged `game: 'uo'` there, so it prints the game's name beside it (D67) wherever it is
|
||||
* shown. They lived on `/features/` until phase 17.
|
||||
*/
|
||||
export const screens = ['shard-status', 'marketplace', 'spawn-atlas', 'guilds', 'houses'];
|
||||
Reference in New Issue
Block a user