feat(drill): the staging drill, the week before each forced wipe (stage 9c, D307-D309, D317-D319)
A Gitea job that checks each new Rust staging build in the seven days before the monthly forced wipe: - tools/drill/static.sh: staging's managed assemblies (DepotDownloader) and Oxide's staging build; whether Oxide has caught up (fieldlist --oxide-behind), the swap's field list compared, and the plugin compiled. - tools/drill/drill.js: window (D318), gate (one check per depot manifest), live (rust-staging runs rnt.run all; rust-carbon is stopped and restarted when both 6000-map rigs run, D309) and report (one issue per build, state on the drill branch; a build waits up to three days for Oxide, D317). - tools/drill/rig-start.sh: the rig's startup; installs the branch and Oxide's build for it, and refuses to start a mismatched pair. - RunicNpcTest 0.7.2: stage 5's five fights look for a field with room for their 280 m line (D319), and the spawn check names what did not spawn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
38
README.md
38
README.md
@@ -92,7 +92,8 @@ The API version moves when a call or a raised hook changes shape, not on every r
|
||||
| `plugin/RunicNPC.cs` | The plugin. The only file a server gets. |
|
||||
| `plugin.toml` | Its declarations: API version, framework floors, required plugins. The release copies them into the manifest. |
|
||||
| `scripts/checkPlugin.js` | The static checks run on every pull request and again before a release (see its header). |
|
||||
| `tools/` | Developer scaffolding for the test rigs, never shipped: the panel scripts (see `tools/rigs.example.json`); `RunicNpcHarness.cs`, the stage 1 and 5 measurement plugin; `RunicNpcTest.cs`, the test harness (`rnt.run all`, then `rnt.after` after a reload or restart) and stage 9's performance check (`rnt.cost`, below); and `fieldlist/` with `managed.js`, which regenerate the swap's field list (below). |
|
||||
| `tools/` | Developer scaffolding for the test rigs, never shipped: the panel scripts (see `tools/rigs.example.json`); `RunicNpcHarness.cs`, the stage 1 and 5 measurement plugin; `RunicNpcTest.cs`, the test harness (`rnt.run all`, then `rnt.after` after a reload or restart) and stage 9's performance check (`rnt.cost`, below); and `fieldlist/` with `managed.js`, which regenerate the swap's field list (below). `drill/` is the staging drill's (below). |
|
||||
| `.gitea/workflows/staging-drill.yml` | The staging drill, the week before each forced wipe. |
|
||||
|
||||
## After a Rust update: the swap's field list
|
||||
|
||||
@@ -112,7 +113,7 @@ fields Rust itself serialises.
|
||||
## The update surface: what a Rust update can break
|
||||
|
||||
Everything RunicNPC takes from Rust's own classes for the swap and the brain, in one place. A Rust update
|
||||
that changes any of it breaks RunicNPC; the staging drill (PLAN.md stage 9, D308) checks exactly this list
|
||||
that changes any of it breaks RunicNPC; the staging drill (PLAN.md stage 9c, below) checks exactly this list
|
||||
against every new staging build. **Caught by** says how: *compile* means the plugin no longer compiles
|
||||
against the new assembly; *field list* means `tools/fieldlist`'s regenerated list differs from the
|
||||
plugin's (and `rnpc.status` says `missing=` or `added=` at run time); *run time* means only a running server
|
||||
@@ -138,6 +139,39 @@ The **hooks** RunicNPC listens to are listed by `rnpc.status`, which names any t
|
||||
that stays silent after an update has probably been renamed (neither framework reports a hook that matches
|
||||
nothing).
|
||||
|
||||
## The staging drill
|
||||
|
||||
Facepunch puts each Rust build on Steam's `staging` branch days before it ships, and Rust changes on the
|
||||
monthly forced wipe, the first Thursday. `.gitea/workflows/staging-drill.yml` works in the seven days
|
||||
before each forced wipe, which leaves a week to fix what it finds, and checks every new staging build in
|
||||
that week (PLAN.md stage 9c, D307–D309, D317, D318). It is scheduled daily and stops at once outside
|
||||
the week. A run by hand always goes ahead.
|
||||
|
||||
- **Static, about a minute, no server** (`tools/drill/static.sh`): Rust's managed assemblies
|
||||
from the staging branch and Oxide's staging build. It asks whether Oxide has caught up with Rust
|
||||
(`tools/fieldlist --oxide-behind`), regenerates the swap's field list and compares it, and compiles the
|
||||
plugin against them.
|
||||
- **Live, once per build** (`tools/drill/drill.js live`): the `rust-staging` server (Oxide, a 3500 map)
|
||||
installs the same pair at start (`tools/drill/rig-start.sh`), loads RunicNPC, Kits and
|
||||
`tools/RunicNpcTest.cs`, and runs `rnt.run all`. When both 6000-map rigs are running, `rust-carbon` is
|
||||
stopped for it and started again.
|
||||
- **Report:** anything that fails or differs opens one issue for that build, labelled `staging-drill`.
|
||||
The last build checked is kept on the `drill` branch.
|
||||
|
||||
A build is the manifest of Rust's Linux depot, as Steam names it. Oxide's build for a branch carries its
|
||||
own patched `Assembly-CSharp.dll`, and while it is older than Rust's, an Oxide server on that pair dies
|
||||
at boot. So a build waits, opening nothing, until Oxide catches up, for up to three days. After that it is
|
||||
reported as "Oxide has not caught up". To rehearse it on a pair known to match, run the workflow by hand
|
||||
with `branch: public`: it reports in the job summary only.
|
||||
|
||||
By hand, from Git Bash or Linux:
|
||||
|
||||
```bash
|
||||
BRANCH=public DEPOTDOWNLOADER=/path/to/DepotDownloader bash tools/drill/static.sh # → drill-work/static.json
|
||||
PANEL_KEY_FILE=/path/to/key node tools/drill/drill.js live --branch public # → drill-work/live.json
|
||||
node tools/drill/drill.js report --state /tmp/drill.json # public: prints only
|
||||
```
|
||||
|
||||
## Performance: `rnt.cost`
|
||||
|
||||
Stage 9's check (D306): 100 of RunicNPC's NPCs, idle and fighting 20 stand-in players, against the same
|
||||
|
||||
Reference in New Issue
Block a user