docs(modules): the Carbon rig, R19 proven, and one refuted claim
rust-carbon (id 18, 87fb1f67) is built on the same egg with FRAMEWORK=carbon, a clean install rather than a converted one. Install 122s, boot 543s. R19 is proven. The byte-identical RunicGateway.cs that runs on the Oxide rig, with no conditional compilation in it at all, loaded on Carbon 2.0.259.0 and behaved identically - same startup line, same no-stall retry against an absent sidecar. That contract now holds on three platforms from one source file: Windows/Mono, Linux/Oxide, Linux/Carbon. R18's amendment is confirmed the best way it could have been. The plugin's own config, written by the same Oxide-compat API on both rigs, landed at oxide/config/RunicGateway.json on one and carbon/configs/RunicGateway.json on the other. Had the R18 editor used a literal path it would not have found its own plugin's config on half of all installs, and no test would have caught it. One claim is REFUTED, and it was wrong about Oxide as well as Carbon. CARBON.md said Oxide stores permissions as JSON and Carbon as Protobuf or SQLite. Both rigs say otherwise: both store Protobuf, under IDENTICAL filenames (oxide.users.data, oxide.groups.data), differing only in directory - Carbon writes its own data into files named after Oxide. This strengthens R2's API-only rule rather than weakening it: a file reader would have worked on both rigs today and broken silently for the one operator who ran c.migrate_perms_sql. Two things nobody had thought to claim, found by looking. Carbon auto-creates a third default group, moderator, which R2's full-set push must tolerate or report drift for ever. And c.plugins exposes per-plugin hook telemetry that is most of section 6's fired-hook mechanism, free, and only on Carbon. Also: a wrong console command is indistinguishable from success at the API. Pterodactyl's command endpoint returns 204 either way and Carbon prints nothing for an unknown command, so oxide.plugins on Carbon looks exactly like it worked. Anything driving the console must read a log to know. CARBON.md gains a scorecard (section 10) and drops its unproven banner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
This commit is contained in:
@@ -1763,15 +1763,15 @@ including one finding that changes R20's shape.
|
||||
| | |
|
||||
|---|---|
|
||||
| Panel | `http://192.168.0.12` (no TLS — `https://` fails outright), node 1 `Main` |
|
||||
| Server | `rust-oxide`, id **17**, identifier **`e6758c06`** |
|
||||
| Egg | 18 `Rust Autowipe`, `ghcr.io/pterodactyl/games:rust` |
|
||||
| `FRAMEWORK` | `oxide` |
|
||||
| Servers | `rust-oxide` id **17** / **`e6758c06`**, and `rust-carbon` id **18** / **`87fb1f67`** (§14.5) |
|
||||
| Egg | 18 `Rust Autowipe`, `ghcr.io/pterodactyl/games:rust` — both rigs, one egg |
|
||||
| `FRAMEWORK` | `oxide` / `carbon` |
|
||||
| Limits | 8192 MB memory, 25600 MB disk — deliberately under half the node, so the Carbon rig fits beside it |
|
||||
| Allocations | 21000 game (default), 21001 query, 21002 RCON, 21003 Rust+, **21004 held for the sidecar's `[web].bind`** |
|
||||
| Allocations | oxide 21000-21004, carbon 21005-21009 — game, query, RCON, Rust+, **and one held for the sidecar's `[web].bind`** |
|
||||
| World | procedural, size 3000, seed 1234 |
|
||||
| SFTP | `192.168.0.12:2022` |
|
||||
|
||||
The RCON password is a generated 24-byte token rather than the old rig's `letmein`, kept out of this
|
||||
The RCON passwords are generated 24-byte tokens rather than the old rig's `letmein`, kept out of this
|
||||
document and out of the repo. §6 named that shape as the thing nothing published should copy; this is
|
||||
the first rig where it was not copied.
|
||||
|
||||
@@ -1943,6 +1943,67 @@ string is composed so that whatever the entrypoint prepends still lands on `Rust
|
||||
is more work and survives upstream changing its entrypoint; the second is free and depends on a line
|
||||
in somebody else's repository. Raised rather than settled.
|
||||
|
||||
|
||||
### 14.5 The Carbon rig, and R19 proven
|
||||
|
||||
`rust-carbon` — id **18**, identifier **`87fb1f67`**, same egg, same world (procedural, 3000, seed
|
||||
1234), same limits, allocations **21005-21009 with 21009 held for the sidecar**, `FRAMEWORK=carbon`.
|
||||
**A clean install, never a converted one**, per R21: install 122s, boot 543s, running.
|
||||
|
||||
**R19 is proven.** The byte-identical `RunicGateway.cs` that runs on the Oxide rig — no `#if CARBON`
|
||||
anywhere in it, nothing conditional at all — loaded on Carbon **2.0.259.0** and behaved the same:
|
||||
|
||||
```
|
||||
[INFO] Carbon 2.0.259.0 [2026.09.03.0] 21063e8 on Linux
|
||||
[INFO] [Runic Gateway] protocol 1, serverId 'main', sidecar 127.0.0.1:7799
|
||||
[INFO] Loaded plugin Runic Gateway v0.1.0 by RunicGateway [2367ms]
|
||||
[INFO] [Runic Gateway] cannot reach the sidecar: Connection refused - retrying quietly [RunicGateway Link|26]
|
||||
```
|
||||
|
||||
That last line is the no-stall contract holding on its **third** platform now — Windows/Mono,
|
||||
Linux/Oxide, Linux/Carbon — from one source file. [`CARBON.md`](CARBON.md) §10 is the full scorecard;
|
||||
the parts that change decisions are below.
|
||||
|
||||
**R18's amendment is confirmed the best way it could have been.** The plugin's own config, written by
|
||||
the same Oxide-compat API on both rigs, landed at `/oxide/config/RunicGateway.json` on one and
|
||||
**`/carbon/configs/RunicGateway.json`** on the other. D3 put the plugin's config inside R18's editor;
|
||||
had that editor used a literal `oxide/config/`, **it would not have found its own plugin's config on
|
||||
half of all installs.** No test would have caught it; only two rigs would.
|
||||
|
||||
**And one claim was refuted — the one with the sharpest consequence.** `CARBON.md` had said Oxide
|
||||
stores permissions as JSON and Carbon as Protobuf or SQLite, offering the difference as the reason
|
||||
not to read the file. Both rigs say otherwise:
|
||||
|
||||
| | Oxide rig | Carbon rig |
|
||||
|---|---|---|
|
||||
| Path | `oxide/data/oxide.users.data` | `carbon/data/`**`oxide.users.data`** |
|
||||
| First bytes | `0a 16 0a 07 64 65 66 61 75 6c 74` | `0a 17 0a 07 64 65 66 61 75 6c 74` |
|
||||
| Format | Protobuf | Protobuf |
|
||||
| Default groups | `default`, `admin` | `default`, `admin`, **`moderator`** |
|
||||
|
||||
**Same binary format, same filenames, different directory** — and Carbon writes *its* data into files
|
||||
named after Oxide. **This makes R2's API-only rule more important, not less.** A file reader would
|
||||
have worked on both rigs today and broken silently for the one operator who ran `c.migrate_perms_sql`
|
||||
— no error, no version marker, just a site reporting drift against a store nobody is writing any
|
||||
more. The rule survives; the reasoning behind it was wrong and is now right.
|
||||
|
||||
Two things nobody had thought to claim, found by looking:
|
||||
|
||||
- **Carbon auto-creates a third default group, `moderator`**, auto-granted by auth level alongside
|
||||
`default` and `admin`. R2 pushes its *full* set on connect, so it has to tolerate a group the
|
||||
framework will recreate the moment it is deleted — otherwise the site reports drift for ever.
|
||||
- **`c.plugins` reports per-plugin `hook fires`, `hook time`, `hook memory`, `hook lag` and
|
||||
`hook exceptions`** — most of §6's "log which expected hooks have fired" mechanism, free, and only
|
||||
on Carbon. Useful when debugging on Carbon; **not a substitute** for the plugin's own counter, which
|
||||
must work on both.
|
||||
|
||||
**A warning about how a wrong console command fails here.** Pterodactyl's `command` endpoint returns
|
||||
`204` whether or not anything happened, and Carbon prints nothing for an unknown command. So
|
||||
`oxide.plugins` on Carbon — which is simply not a command — is indistinguishable from success at the
|
||||
API. Anything driving the console has to read a log to know, which is the same conclusion §14.2c
|
||||
reached about `oxide.reload` and the same shape R18's rollback needs.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[rl]: https://gitea.whitlocktech.com/RunicGateway/Rust-Link
|
||||
|
||||
Reference in New Issue
Block a user