feat(demo): list the demo's sign-ins on /beta and link into it per game
Some checks failed
PR checks / checks (pull_request) Failing after 2m16s
Some checks failed
PR checks / checks (pull_request) Failing after 2m16s
The public demo (demo.runicgateway.com) is live, so the site's demo slot can be switched on. Two decisions of record, PLAN.md §15: - D82: /beta reads the demo's GET /api/v1/public/settings demo.logins on the server, caches it for a minute, and lists the published sign-ins with the next wipe. If the demo does not answer, /beta links to its sign-in page instead. Gate two reads as in place. - D83: a deep link into a game module's pages carries data-demo-game, and applyBrand.mjs fills it only for games in the new mounted demoGames list. The Rust features gain links into /rust and /rust/servers/demo. UO's stay hidden on a Rust demo. The public-demo not-built entry is removed, because its resolvedBy was met. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -32,9 +32,9 @@
|
||||
* 2. SOMEWHERE TO POINT IT. `ConnectScreen.kt` on `Android-app` `main` is blunt about
|
||||
* this — "nothing else in the app runs until a valid Runic Gateway site is entered and
|
||||
* validated". An installed app with no deployment behind it is a text field. D27 makes
|
||||
* the public demo (§15) the tester target rather than naming a private shard, which
|
||||
* means the beta opens when the demo VM does. `notBuilt.mjs` already carries that
|
||||
* absence; this page renders the demo link from `demoUrl` when there is one.
|
||||
* the public demo (§15) the tester target rather than naming a private shard. The demo
|
||||
* went up on 2026-10-27; with `demoUrl` mounted, `/beta` marks this gate in place and
|
||||
* lists the demo's sign-ins as the demo publishes them (D82, `lib/demoLogins.mjs`).
|
||||
*
|
||||
* Neither gate is a reason not to collect addresses now — the list is what makes the first
|
||||
* batch possible on day one — but a page that hid them would be advertising a beta that
|
||||
@@ -180,8 +180,7 @@ export const requirements = [
|
||||
body:
|
||||
'The app ships pointed at nothing. Its first screen asks for the address of a site ' +
|
||||
'running this platform and validates it before anything else in the app will run — ' +
|
||||
'so a tester needs either their own deployment or the public demo, which is the ' +
|
||||
'second of the two things this beta is waiting on.',
|
||||
'so a tester needs either their own deployment or the public demo.',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* `demoPath` — DEEP LINKS THAT ONLY EXIST WHEN A DEMO DOES
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* §15/D12 keeps the public demo out of scope while requiring the site to gain one by way of
|
||||
* §15/D12 kept the public demo out of scope while requiring the site to gain one by way of
|
||||
* a line in a mounted `brand.json`. `brand.json`'s own comment promised `/features/` a
|
||||
* "per-capability affordance" that had never been defined; D25 defines it as a deep link
|
||||
* per capability that has a stable public route, appended to the mounted `demoUrl` by
|
||||
@@ -63,8 +63,10 @@
|
||||
* behind a Team id no static page can know. Paths are read from the real route tables —
|
||||
* core's `client/src/App.jsx` and `module-uo`'s `client/src/entry.jsx` on `main` — never
|
||||
* guessed. A module's public pages are namespaced under its own id, so a route into the
|
||||
* Ultima Online module is `/uo/…`: the demo §15 plans runs that game, which is why the
|
||||
* Teams item points there and the module-supplied items in `games/` carry their own.
|
||||
* Ultima Online module is `/uo/…`. A link into a module's pages names that game
|
||||
* (`demoGame` here, the `game` prop of `GameFeatures` for the lists in `games/`), and it
|
||||
* shows only when the mounted `demoGames` lists it (D83): the demo that exists runs Rust,
|
||||
* so the Teams item's `/uo/guilds` stays hidden there and Rust's clans link stands in.
|
||||
*/
|
||||
|
||||
import { games } from './games/index.mjs';
|
||||
@@ -82,6 +84,7 @@ import { games } from './games/index.mjs';
|
||||
* @property {string[]} [caps] Module capability slugs, on a game's own items (`games/`) only.
|
||||
* @property {boolean} [needsModule] Core machinery a module has to populate (D24).
|
||||
* @property {string} [demoPath] A stable public route, deep-linked into a demo (D25).
|
||||
* @property {string} [demoGame] The game module whose pages `demoPath` is in, if any (D83).
|
||||
*
|
||||
* @typedef {object} CapabilityGroup
|
||||
* @property {string} id
|
||||
@@ -116,6 +119,7 @@ const community = {
|
||||
label: 'Teams',
|
||||
needsModule: true,
|
||||
demoPath: '/uo/guilds',
|
||||
demoGame: 'uo',
|
||||
detail:
|
||||
'A roster, a leader, a private forum, its own notification streams and a Discord ' +
|
||||
'voice channel, all hanging off one group. Core owns every part of that machinery ' +
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
* 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.
|
||||
* `demoPath` is a public route in Module-Rust's own `client/src/entry.jsx` (`/rust`, and
|
||||
* `/rust/servers/:id` with its `?tab=` search parameter, which `ServerDetail.jsx` reads).
|
||||
* The public demo runs Rust (§15), and `demo` is its server's id, fixed by
|
||||
* `website/deploy/demo/seed.json` (`modules.rust.servers`) and recreated at every wipe.
|
||||
* The links show only while the mounted `demoGames` lists `rust` (D83). The staff items
|
||||
* carry none: every admin page needs a sign-in, and D25's links are to public routes.
|
||||
*/
|
||||
|
||||
/** @typedef {import('../capabilities.mjs').Capability} Capability */
|
||||
@@ -26,6 +31,7 @@ export const features = [
|
||||
{
|
||||
label: 'Every server, live',
|
||||
caps: ['rust', 'servers'],
|
||||
demoPath: '/rust',
|
||||
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 ' +
|
||||
@@ -35,6 +41,7 @@ export const features = [
|
||||
{
|
||||
label: 'The kill feed',
|
||||
caps: ['killfeed'],
|
||||
demoPath: '/rust/servers/demo',
|
||||
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 ' +
|
||||
@@ -44,6 +51,7 @@ export const features = [
|
||||
{
|
||||
label: 'Leaderboards, per wipe',
|
||||
caps: ['leaderboard'],
|
||||
demoPath: '/rust/servers/demo?tab=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, ' +
|
||||
@@ -52,6 +60,7 @@ export const features = [
|
||||
{
|
||||
label: 'Who is online',
|
||||
caps: ['presence'],
|
||||
demoPath: '/rust/servers/demo?tab=online',
|
||||
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 ' +
|
||||
@@ -60,6 +69,7 @@ export const features = [
|
||||
{
|
||||
label: 'Wipes',
|
||||
caps: ['wipes'],
|
||||
demoPath: '/rust/servers/demo?tab=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.',
|
||||
@@ -67,6 +77,7 @@ export const features = [
|
||||
{
|
||||
label: 'The live map',
|
||||
caps: ['map'],
|
||||
demoPath: '/rust/servers/demo?tab=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 ' +
|
||||
@@ -82,6 +93,7 @@ export const features = [
|
||||
},
|
||||
{
|
||||
label: 'Clans are Teams',
|
||||
demoPath: '/rust/servers/demo?tab=clans',
|
||||
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 ' +
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
* 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`.
|
||||
* when one is mounted (D25) and the mounted `demoGames` lists `uo` (D83) — which the public
|
||||
* demo, a Rust deployment, does not. Paths are read from `module-uo`'s `client/src/entry.jsx`.
|
||||
*/
|
||||
|
||||
/** @typedef {import('../capabilities.mjs').Capability} Capability */
|
||||
|
||||
@@ -117,23 +117,9 @@ export const notBuilt = [
|
||||
resolvedBy: 'A game server that runs there.',
|
||||
link: { href: `${GITEA}/docs/src/branch/main/installer/INSTALL.md`, label: 'The operator guide' },
|
||||
},
|
||||
{
|
||||
id: 'public-demo',
|
||||
// Phase 5 added `app` and `beta`, and that is not tidying. D27 makes the demo the
|
||||
// deployment a beta tester connects to, so on those two pages this stopped being a
|
||||
// thing the site lacks and became the thing the beta is waiting for. An absence that
|
||||
// blocks a call to action has to be on the page carrying that call to action.
|
||||
scope: ['features', 'app', 'beta'],
|
||||
title: 'A public demo you can click through',
|
||||
body:
|
||||
'Planned and out of scope today: a virtual machine running the whole stack including ' +
|
||||
'a game server, with settings locked down and an hourly reset. Until it exists this ' +
|
||||
'site does not link to one, and there is no screenshot here of something that is not ' +
|
||||
'running somewhere.',
|
||||
resolvedBy:
|
||||
'The machine being stood up. The site is already built to gain it by way of one line ' +
|
||||
'in a configuration file, rather than a rebuild.',
|
||||
},
|
||||
// `public-demo` stood here until 2026-10-28. Its `resolvedBy` was met when
|
||||
// demo.runicgateway.com went up (docs/website/DEMO_MODE.md), and the site reaches it through
|
||||
// the mounted `demoUrl`, as the entry promised (D82, D83).
|
||||
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
THE ANDROID CLIENT (phase 5)
|
||||
|
||||
Reference in New Issue
Block a user