papyrus-reference
Papyrus Reference
Overview
This skill provides offline lookup for Papyrus function signatures, parameter shapes, return types, flags, and doc-comments. The reference corpus is generated from BellCube's papyrus-index and ships in this skill's references/ tree. The body walks the lookup procedure, the surgical-read pattern that uses each index entry's line_start/line_end to read only the relevant entry block from its source file, the bundled-or-warn fallback when a function isn't in the corpus, and the tier strategy that gates SKSE-plugin sources by modlist content.
This skill covers the API surface — function signatures and docs. Reading actual .psc source from a modlist, and compiling .psc → .pex, are separate concerns handled with your normal file-reading and compiler tooling.
For the compiles-clean-but-misbehaves traps a correct signature does NOT reveal — GetForm returning None for the whole ESL range, SendModEvent's 4-arg handler arity, FormList.HasForm missing base-NPC_ entries, mixed storage backends, Utility.Wait in a paused menu, literal/docstring escaping, common-noun type collisions — see references/silent-biters.md. It is a hand-curated companion, separate from the by-construction signature corpus.
First step
When you encounter a Papyrus function call you need to verify, or when authoring a .psc, open the function index at references/index.jsonl. The index is JSONL — one entry per line — and resolves an unqualified function name to the per-script reference file that documents it AND the 1-indexed line_start/line_end range of the entry block within that file. The index is grep-friendly: the entries are compact JSON (no spaces after colons), so match the full quoted token "name":"FunctionName" — a spaced pattern like "name": "…" matches nothing.
Once you have the matching index entry, do NOT read the whole reference file — use the entry's line_start/line_end to read just the entry block via your file-reading tool's line-range (offset/limit) capability. The whole-file load is typically 10-300 KB; the targeted block read is 200-1500 bytes. Don't bulk-load the index either; it is ~1.5 MB and that defeats the per-session token economics. Use targeted reads throughout.
Reasoning framework / Lookup procedure
- Identify the unqualified function name from the call site — for
Self.GetActorValue("Health")the name isGetActorValue; forStringUtil.Substring(str, 0, 4)the name isSubstring.