How Clutter was built

Raw game files read

Processing

"Clutter" is one block code (clutter, plus the clutter-devastation and clutter-aquatic variants) with the ShapeFromAttributes behavior: what it actually is — a skull, a statue, a barricade, a broken anvil — is a per-instance type attribute on the placed block, not part of its code. That is why the item index only ever shows a bare "Clutter" entry.

Like tapestries, every worldgen schematic a structure actually references is pre-filtered (from its header block-code list) down to those containing a clutter code, then fully decoded: each BlockEntities value is Ascii85-decoded into a TreeAttribute whose type string (e.g. skull/human-crystal) is read. Types are then grouped, with which structures place each and how many times.

Names come from the game's own lang keys, built the way BlockClutter builds them: clutter- + the type with / replaced by -. A type with no such key is shown by its raw type string and flagged.

Schematic-authored, not guaranteed. This is what the structure schematics contain; some clutter is also scattered by stackrandomizer-clutter/loot mechanisms at world generation, which isn't visible in schematic data.

Decoder. The TreeAttribute layouts follow the game's own vsapi source (libs/vs-schematic/src/schematicDecode.ts). Every block entity in the vanilla and BetterRuins schematics decodes without error (npm run decode-stats), and npm test pins each attribute type.

Pipeline code