Files
docs/modules/rust/agent/README.md
wtclaude 4e2c2dc439 docs(modules): mirror the rest of the Oxide ecosystem, and add a machine-readable set
Completes the uMod mirror beyond the Rust hook table, and adds agent/ — the
same facts in TSV/JSONL at ~46% of the tokens.

New prose:
- OXIDE_API.md: the 19 developer pages under umod.org/documentation/api/ —
  plugin structure, hooks, commands, IPlayer, permissions, config, data files,
  database, localization, timers, web requests, dependencies, integration,
  preprocessor directives, security, style guide, CI, review. This is the
  framework our plugin is a guest in, where HOOKS.md is what the game says.
- OPERATING.md: the 6 operator pages — installing Oxide on a server, then
  installing, configuring and permissioning plugins.

New machine-readable set (agent/):
- hooks.tsv    477 rows, ~31% of HOOKS.md
- items.tsv    678 rows, ~80% of DEFINITIONS.md's item table
- skins.tsv    104 rows covering 2,590 skins, ~77%
- api.jsonl    150 code examples, ~47% of the two prose docs
Generated in the same pass as the markdown, so the two cannot drift.

HOOKS.md gains the universal-hook split: 34 of the 477 are uMod's own
Covalence hooks, raised identically on every game uMod supports. Verified
against /documentation/games/universal in the same capture - all 34 are in
the Rust set and the Rust page adds none of its own, so the overlap is exact.
The distinction is architectural: a universal hook is the portable part of
the surface.

Two things worth recording from building it:
- The first skins.tsv was one row per skin and came out 11% LARGER than the
  markdown it replaces. Grouping it one row per item is what made it a
  saving. The token win is real for prose (3.2x on hooks) and small for
  tables that were already dense - agent/README.md says so plainly rather
  than claiming a flat number.
- Signature extraction by brace depth silently captured body lines (a nested
  '}' in OnUserConnected's example ended the block early). It now matches on
  the hook's own name; all 477 rows verified to carry a real signature.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
2026-09-15 10:01:11 -05:00

5.3 KiB
Raw Permalink Blame History

agent/ — the same reference, in machine shape

The four files here carry the same facts as the markdown one directory up, stripped of prose and formatting so a coding agent can load or grep them cheaply. They are generated from the same scrape, in the same pass — they are not a separate capture and cannot drift from it.

File Rows Replaces ~tokens vs. the markdown
hooks.tsv 477 ../HOOKS.md ~19.6k 31%
items.tsv 678 ../DEFINITIONS.md § Items ~6.9k 80%
skins.tsv 104 ../DEFINITIONS.md § Skins ~17.9k 77%
api.jsonl 150 ../OXIDE_API.md + ../OPERATING.md ~7.8k 47%
Total ~52k 46%

Token counts are len(chars)/4 estimates, not a real tokenizer — accurate enough to choose a file, not to budget a context window.

Be honest about where the win is. It is large for hooks (3.2×) and the API prose (2.1×), because both are mostly explanation. It is modest for the item and skin tables (~1.25×), because DEFINITIONS.md is already a dense table — there was not much ceremony left to strip. The first attempt at skins.tsv was one row per skin and came out 11% larger than the markdown it was meant to replace; grouping it one row per item is what made it a saving at all.


Which file to reach for

  • "Which hook fires when X happens?"hooks.tsv. It is the whole catalogue; grep the description column.
  • "What exactly does this hook give me, and what may I return?"hooks.tsv answers both in the signatures and returns columns. Only go to ../HOOKS.md for the worked example body.
  • "How do I do in a plugin?"api.jsonl, grep section or code. It is every code example uMod publishes, addressed by page and heading.
  • "What is this item's id / short name?"items.tsv.
  • "What skins exist for this item?"skins.tsv, one grep, one line.

Read the markdown instead when you want the reasoning — the return-contract rules, the callouts, the cautions. Those are deliberately not in here.


Formats

All files are UTF-8 with LF endings and a header line. TSV fields are tab-separated with no quoting and no escaping — tabs and newlines are stripped from values at generation time, so a naive split('\t') is always correct.

hooks.tsv

name  category  universal  returns  signatures  description
  • category — one of the 20 uMod subcategories (Server, Player, Entity, …).

  • universal1 for the 34 uMod universal (Covalence) hooks, which fire identically on every game uMod supports; empty for Rust-specific ones. This is the portable/non-portable split.

  • returns — the return contract, normalised to one of five codes:

    Code uMod's wording What to declare
    none No return behavior void. Nothing you return is read.
    nonnull Returning a non-null value overrides default behavior object. null proceeds; anything else cancels.
    bool Returning true or false overrides default behavior object. null abstains — false is not abstaining.
    data Returning a string will kick…, and similar The value is consumed as data, not just as a veto.
    ? upstream states no return behaviour at all 3 hooks. Not a guess — genuinely absent.
  • signatures — every declaration uMod publishes for the hook, joined by ;;. Twelve hooks have more than one (overloads); the rest have exactly one. Extracted by matching the hook's own name, so no body line is ever mistaken for a signature.

  • description — the descriptive bullets, joined by ; , with the return-behaviour bullet moved into returns.

items.tsv

shortname  item_id  display_name

Sorted by short name. shortname is the only key safe to persist — see ../DEFINITIONS.md § Which key to use.

skins.tsv

item_shortname  skins (id=name;id=name;...)

One row per item, not per skin — 104 rows covering 2,590 skins. A ; inside a skin name is replaced with , so the field splits cleanly.

api.jsonl

One JSON object per line, one object per code example uMod publishes:

{"page":"api/timers","section":"Single timer","lang":"csharp","code":"timer.Once(1f, () =>\n{\n    Puts(\"Hello world!\");\n});"}
  • page — the uMod path, e.g. api/permissions. Prefix with https://umod.org/documentation/ for the source.
  • section — the nearest heading above the example.
  • langcsharp, json or text.

This is the examples only. The prose that explains them is in ../OXIDE_API.md and ../OPERATING.md, which is exactly the trade that makes it 47% of the size.


Regenerating

These are build outputs, not hand-edited files. Re-capture and regenerate together — ../README.md § Provenance and refreshing has the procedure. Never edit a file here by hand: it will be silently overwritten on the next capture, and it would put the machine copy out of step with the markdown, which is the one thing this directory promises cannot happen.