Files
runicgateway.com/src/pages/modules/rust.astro
wtclaude 56473d4d51
All checks were successful
PR checks / checks (pull_request) Successful in 2m37s
feat(site): phase 17 - per-game module pages, /runicnpc/, and checkTerms over the built site
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
2026-10-22 20:10:51 -05:00

200 lines
6.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
import Base from '../../layouts/Base.astro';
import PageHeader from '../../components/PageHeader.astro';
import GameFeatures from '../../components/GameFeatures.astro';
import platform from '../../data/platform.json';
import { features, staffFeatures } from '../../data/games/rust.mjs';
import { assertGameCoverage } from '../../data/games/index.mjs';
/**
* `/modules/rust/` — PLAN.md §16, phase 17.
*
* The Rust module's own page, in Rust's words (D63; `GAME_ROUTES` in `checkTerms.mjs`). The
* lists are `games/rust.mjs`, written from the Rust docs group that phase 15 walked, and the
* call below holds them to the capabilities `Module-Rust` declares — the page-side half of
* the coverage assertion phase 13 moved here.
*
* It carries the RunicNPC card D61 asked for, pointing at the standalone `/runicnpc/` page.
*
* No screenshots yet, and no slots for them: D65 brings the Rust captures in phase 18, from
* the rigs, and D4 rules out a placeholder in the meantime.
*/
assertGameCoverage('rust');
const rust = platform.games.rust;
const pieces = [
{
role: 'The module',
name: rust.module.repo,
version: platform.releases['Module-Rust'],
what: 'Every Rust screen on the site, installed from Admin → Modules.',
},
{
role: 'The sidecar',
name: 'rust-link',
version: rust.bundle.sidecar,
what: 'One beside each server, and the only part of the bridge that listens on a network.',
},
{
role: 'The bridge plugin',
name: 'RunicGateway.cs',
version: rust.bundle.plugin,
what: 'One file that runs unchanged on Oxide and Carbon, plus its optional helpers.',
},
{
role: 'NPCs',
name: 'RunicNPC',
version: rust.bundle.runicnpc,
what: 'Our NPC plugin, which the bridge drives for every NPC an event places.',
},
];
const title = 'The Rust module';
const description =
'What the Rust module adds to a Runic Gateway site: every server live, the kill feed, ' +
'leaderboards per wipe, the live map, Steam linking, and permissions, mod config and events run from the site.';
---
<Base title={title} description={description}>
<PageHeader eyebrow="Game module" title="Rust">
<p>
The <code>rust</code> module turns a Runic Gateway site into a Rust community’s site. It
follows any number of servers, each running Oxide or Carbon with a sidecar of its own,
and keeps what each one tells it after the wipe has taken it from the game.
</p>
<p>
The server side is installed as one bundle — <strong>{rust.bundle.tag}</strong>,
speaking protocol {rust.protocol} — with the installer, from a Pterodactyl egg, or by
hand. It needs Oxide {rust.bundle.oxideMin} or Carbon {rust.bundle.carbonMin} or newer,
and the uMod plugins {rust.bundle.requiresPlugins.join(' and ')}.
</p>
</PageHeader>
<section class="page section pieces" aria-labelledby="pieces-heading">
<h2 id="pieces-heading">The pieces</h2>
<ul class="pieces__list">
{
pieces.map((piece) => (
<li class="panel">
<p class="pieces__role">{piece.role}</p>
<p class="pieces__name">
<code>{piece.name}</code>
<span class="chip chip--version">{piece.version}</span>
</p>
<p class="pieces__what">{piece.what}</p>
</li>
))
}
</ul>
</section>
<GameFeatures
title="What players see"
lede="Every public surface is the operator's to widen: nothing names a player to the public by default."
items={features}
/>
<GameFeatures
title="What staff run from the site"
lede="Seven admin screens, and a Rust section on each user's page."
items={staffFeatures}
/>
<section class="page section npc">
<div class="panel npc__card">
<p class="eyebrow">Also from this project</p>
<h2>RunicNPC</h2>
<p>
Our own NPC plugin for Rust: NPCs where you want them, with the kit, health, aim and
behaviour you give them — roamers, sentries, guards, quest-givers and bosses with
phases. On a Runic Gateway server it is required and the site authors its profiles;
on any other Rust server it runs on its own, with <code>/rnpc</code> commands and an
API for other plugins.
</p>
<div class="npc__links">
<a class="btn btn--primary" href="/runicnpc/">About RunicNPC</a>
<a class="btn btn--ghost" href="/docs/rust/runicnpc/">Its documentation</a>
</div>
</div>
</section>
<section class="page section next">
<h2>Setting it up</h2>
<p class="prose">
The documentation’s Rust group starts from installing the bridge and covers every admin
screen the module adds, with the reference for each file it reads.
</p>
<div class="next__links">
<a class="btn btn--primary" href="/docs/rust/">The Rust docs</a>
<a class="btn btn--ghost" href="/modules/">All modules</a>
</div>
</section>
</Base>
<style>
.pieces h2,
.next h2 {
margin: 0 0 0.75rem;
font-size: clamp(1.5rem, 3vw, 1.95rem);
}
.pieces__list {
display: grid;
gap: 1rem;
margin: 1.25rem 0 0;
padding: 0;
list-style: none;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}
.pieces__role {
margin: 0;
color: var(--dim);
font-size: 0.78rem;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.pieces__name {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.6rem;
margin: 0.5rem 0 0;
color: var(--gold);
}
.pieces__what {
margin: 0.6rem 0 0;
color: var(--muted);
font-size: 0.94rem;
}
.npc__card h2 {
margin: 0;
color: var(--gold);
font-size: clamp(1.4rem, 2.8vw, 1.8rem);
}
.npc__card p:not(.eyebrow) {
margin: 0.75rem 0 0;
max-width: var(--measure);
color: var(--muted);
}
.npc__links,
.next__links {
display: flex;
flex-wrap: wrap;
gap: 0.7rem;
margin-top: 1.5rem;
}
.next p {
margin: 0;
color: var(--muted);
}
</style>