How Items & Blocks was built

Raw game files read

Processing

Not a registry dump. An item/block only gets a page here if it's reachable from at least one of: a recipe (input or output), a block/creature drop table, a worldgen spawn rule (ore deposit, crop/flower patch, tree, fruit tree), a trader's buy/sell list, an NPC dialogue reward, or a recipe ingredient's own tool-tag (e.g. tool-hammer). An item that exists in the raw game files but satisfies none of those (pure creative-mode novelties, debug items, etc.) will not appear.

apps/vs-wiki/src/ingest/crossref.ts builds the base index by walking every normalized recipe (input/output codes) and every flattened loot entry (drop codes). Six later passes in apps/vs-wiki/src/ingest/index.ts then widen it, each via the same ensureSpawnTarget(domain, code, kind) synthesis -- "give this code a page even though the recipe/loot walk alone never would have":

Paintings, tapestries, and clothing are a deliberate, separate exception: they never join this index at all, since they're pure decor with no recipe/drop/worldgen tie -- they get their own dedicated catalogs instead (see their own source pages).

Descriptions and C# source links

Once the index is complete, attachDescriptionsAndCodeRefs in crossref.ts gives every entry its itemdesc-/blockdesc- lang description, when the game has one. It also records the C# names its own JSON definition points at: class, entityClass, behaviors[].name and entityBehaviors[].name, including their ...ByType variants. Each name is looked up in apps/vs-wiki/src/ingest/csharpClassMap.json, a committed name-to-file mapping. It is generated by hand with apps/vs-wiki/scripts/map-csharp-classes.ts from a local clone of vssurvivalmod, by matching each api.Register...Class("Name", typeof(Type)) call to the file declaring Type. The C# source itself is never part of the build. Names implemented outside vssurvivalmod (VSEssentials, the engine, mod DLLs) are listed without a link.

Random-stack placeholders

An ItemStackRandomizer item (stackrandomizer-ore, stackrandomizer-clutter-scribe, …) is what a world-generated chest or vessel actually holds in a schematic; the game replaces it with one random stack when the container is generated. extractStackRandomizerPools in models/loot.ts reads each variant's stacks pool (glob-keyed attributesByType, like every other ...ByType field). In index.ts every pool owner is added to the item index with its results, each normalized to a 0–1 chance by the pool's total weight (the same normalization ItemStackRandomizer.OnLoaded does), and every result gets a reverse "Can be generated by" link. A stack's own attributes are kept, because for the generic clutter block they are what decide which clutter it is. The placeholders sit in a schematic's ItemCodes dictionary, so "Found in structures" also reads that, not just BlockCodes. A placed randomizer can additionally carry its own totalChance (a chance of producing nothing); that is per-instance data and isn't modelled.

Items linked from the handbook

Guide, dialogue and class text links to items with handbook://item-<code> or block-<code> (optionally domain:code). Each such link is rewritten to its /items/ page, and index.ts then makes sure every referenced item or block that really exists has a page, even if no recipe, drop or spawn rule reaches it (muddy gravel, bony soil, pit kilns).

Pipeline code