# 24 - Pack Mods & Snippets Snippets are active reusable JSON fragments for types annotated `@Snippet`; fields accept either an inline object or a path under `snippet//`. Iris also loads the legacy `IrisMod` JSON schema from `mods/`, but no engine path applies those injector or replacer fields at runtime. Related: `05 - Concepts & Pack Layout.md`, `10 - Studio & VSCode Schemas.md`, `11 - Dimensions.md`, `12 - Regions.md`, `13 - Biomes.md`, `14 - Generators & Noise.md`, `20 - Object Placement.md`, `25 - Pack Management.md`. ## Pack mod schema (`IrisMod`, inactive) Folder: `mods/`. The loader key is the path under `mods/` without `.json`. `IrisData` can parse and expose these registrants to schema and tooling paths, but engine creation and Studio hotload do not consume them. Treat the fields below as an inactive schema, not a supported way to modify a dimension. | Field | Type | Default | Notes | |-------|------|---------|-------| | `name` | string | `"A Pack Modification"` | Required human name (min length 2) | | `forDimension` | string | `""` | Optional dimension load key; empty = any dimension | | `overrideFluidHeight` | int -1..512 | `-1` | `-1` leaves fluid height unchanged | | `removeBiomes` | string[] | `[]` | Biome keys to remove | | `removeObjects` | string[] | `[]` | Object keys to remove | | `removeRegions` | string[] | `[]` | Region keys to remove | | `injectRegions` | string[] | `[]` | Region keys to inject into the dimension | | `biomeInjectors` | `IrisModBiomeInjector[]` | `[]` | Inject biomes into a region | | `biomeReplacers` | `IrisModBiomeReplacer[]` | `[]` | Swap biomes | | `objectReplacers` | `IrisModObjectReplacer[]` | `[]` | Swap object keys | | `biomeObjectPlacementInjectors` | `IrisModObjectPlacementBiomeInjector[]` | `[]` | Inject object placements into a biome | | `regionObjectPlacementInjectors` | `IrisModObjectPlacementRegionInjector[]` | `[]` | Inject object placements into a region | | `regionReplacers` | `IrisModRegionReplacer[]` | `[]` | Swap regions | | `blockReplacers` | `IrisObjectReplace[]` | `[]` | Block find/replace rules (same shape as object material replacers) | | `styleReplacers` | `IrisModNoiseStyleReplacer[]` | `[]` | Replace `NoiseStyle` usages | ### Injector and replacer shapes **Biome injector** (`@Snippet("biome-injector")`): ```json { "region": "temperate", "inject": ["temperate/meadows"] } ``` **Biome replacer** (`biome-replacer`): ```json { "find": ["temperate/plains"], "replace": "temperate/lush-plains" } ``` **Region replacer** (`region-replacer`): ```json { "find": ["temperate"], "replace": "forests" } ``` **Object replacer** (`object-replacer`): ```json { "find": ["clutter/camp1"], "replace": "clutter/camp3" } ``` **Object placement biome injector** (`object-placement-biome-injector`): ```json { "biome": "temperate/plains", "place": [{ "chance": 0.01, "place": ["clutter/camp1"] }] } ``` **Object placement region injector** (`object-placement-region-injector`): field name is `biome` in code but the registry type is `IrisRegion` (region load key): ```json { "biome": "temperate", "place": [{ "chance": 0.01, "place": ["clutter/camp1"] }] } ``` **Noise style replacer** (`noise-style-replacer`): | Field | Notes | |-------|-------| | `find` | `NoiseStyle` enum value to match | | `replaceTypeOnly` | When true, only swap the style type and keep other style fields | | `replace` | Full `IrisGeneratorStyle` replacement | **Block replacer** (reuses `IrisObjectReplace`, snippet `object-block-replacer`): `find` block list, `replace` palette, optional `exact`, `chance` 0..1. ### Schema example `mods/example-swap.json`: ```json { "name": "Example Temperate Swap", "forDimension": "overworld", "biomeReplacers": [ { "find": ["temperate/plains"], "replace": "temperate/meadows" } ], "biomeInjectors": [ { "region": "temperate", "inject": ["temperate/shattered-plains"] } ] } ``` The example is parseable as `IrisMod`, but it has no effect on generated terrain. Apply equivalent changes directly to the target dimension, region, biome, generator, or object-placement JSON. ## Snippets ### Mechanism 1. Many nested pack types carry `@Snippet("type-name")`. 2. Gson type adapters in `IrisData` intercept those types on read. 3. A field may be either: - an inline JSON object of that type, or - a **string** `"snippet//"` that loads `snippet//.json` from the pack root. 4. If the string starts with `snippet/` but uses a different type folder, the loader rewrites to the expected `snippet//` prefix for that field. 5. Missing snippet files log an error and yield null for that value. Studio schemas (`SchemaBuilder`) expose every snippet as `anyOf` object-or-string and list files under `snippet//` in the workspace enum. ### Disk layout ``` pack/ snippet/ decorator/ bush.json dry_grass.json ... style/ bedrock.json deepslate.json ``` Folder is singular `snippet/`, not `snippets/`. Subfolders match the `@Snippet` value exactly. ### Overworld usage Dimension ores reference style snippets: ```json { "chanceStyle": "snippet/style/bedrock" } ``` `snippet/style/bedrock.json`: ```json { "style": "STATIC" } ``` Biome decorators accept snippet strings in arrays: ```json { "decorators": [ "snippet/decorator/wildflowers", "snippet/decorator/bush" ] } ``` `snippet/decorator/bush.json`: ```json { "chance": 0.03, "style": { "style": "CLOVER_HERMITE", "zoom": 0.52, "exponent": 2.5, "axialFracturing": true }, "slopeCondition": { "maximumSlope": 5 }, "palette": [ { "block": "minecraft:bush", "weight": 1 }, { "block": "minecraft:air", "weight": 4 } ] } ``` `biomes/dev.json` uses the same pattern for a minimal decorator list. ### `@Snippet` type names (engine/object) Each value is the folder name under `snippet/` and the string prefix after `snippet/`: | Snippet value | Class (representative) | |---------------|------------------------| | `attribute-modifier` | `IrisAttributeModifier` | | `axis-rotation` | `IrisAxisRotationClamp` | | `biome-injector` | `IrisModBiomeInjector` | | `biome-palette` | `IrisBiomePaletteLayer` | | `biome-replacer` | `IrisModBiomeReplacer` | | `block-drops` | `IrisBlockDrops` | | `cave-field-module` | `IrisCaveFieldModule` | | `cave-profile` | `IrisCaveProfile` | | `color` | `IrisColor` | | `command` | `IrisCommand` | | `command-registry` | `IrisCommandRegistry` | | `coral` | `IrisCoral` | | `crystal` | `IrisCrystal` | | `custom-biome` | `IrisBiomeCustom` | | `custom-biome-particle` | `IrisBiomeCustomParticle` | | `custom-biome-spawn` | `IrisBiomeCustomSpawn` | | `decorator` | `IrisDecorator` | | `deposit` | `IrisDepositGenerator` | | `deposit-variant` | `IrisDepositVariant` | | `dimension-carving-entry` | `IrisDimensionCarvingEntry` | | `dimension-mode` | `IrisDimensionMode` | | `duration` | `IrisDuration` | | `effect` | `IrisEffect` | | `enchantment` | `IrisEnchantment` | | `entity-spawn` | `IrisEntitySpawn` | | `expression-function` | `IrisExpressionFunction` | | `expression-load` | `IrisExpressionLoad` | | `floating-child-biome` | `IrisFloatingChildBiomes` | | `formation` | `IrisFormation` | | `fungus` | `IrisFungus` | | `generator` | `IrisNoiseGenerator` | | `generator-layer` | `IrisBiomeGeneratorLink` | | `image-map` | `IrisImageMap` | | `loot` | `IrisLoot` | | `loot-registry` | `IrisLootReference` | | `noise-style-replacer` | `IrisModNoiseStyleReplacer` | | `object-block-replacer` | `IrisObjectReplace` | | `object-limit` | `IrisObjectLimit` | | `object-loot` | `IrisObjectLoot` | | `object-marker` | `IrisObjectMarker` | | `object-placement-biome-injector` | `IrisModObjectPlacementBiomeInjector` | | `object-placement-region-injector` | `IrisModObjectPlacementRegionInjector` | | `object-placer` | `IrisObjectPlacement` | | `object-replacer` | `IrisModObjectReplacer` | | `object-rotator` | `IrisObjectRotation` | | `object-scale` | `IrisObjectScale` | | `object-translator` | `IrisObjectTranslate` | | `object-vanilla-loot` | `IrisObjectVanillaLoot` | | `palette` | `IrisMaterialPalette` | | `position-3d` | `IrisPosition` | | `potion-effect` | `IrisPotionEffect` | | `procedural-objects` | `IrisProceduralObjects` | | `procedural-tree` | `IrisProceduralTree` | | `range` | `IrisRange` | | `rate` | `IrisRate` | | `region-replacer` | `IrisModRegionReplacer` | | `ruin` | `IrisRuin` | | `ruin-decorator` | `IrisRuinDecorator` | | `shaped-style` | `IrisShapedGeneratorStyle` | | `slope-clip` | `IrisSlopeClip` | | `stilt-settings` | `IrisStiltSettings` | | `style` | `IrisGeneratorStyle` | | `style-range` | `IrisStyledRange` | | `time-block` | `IrisTimeBlock` | | `tree` | `IrisTree` | | `tree-branches` | `IrisTreeBranches` | | `tree-canopy` | `IrisTreeCanopy` | | `tree-decorator` | `IrisTreeDecorator` | | `tree-layer` | `IrisTreeLayer` | | `tree-secondary-leaf` | `IrisTreeSecondaryLeaf` | | `tree-settings` | `IrisTreeSettings` | | `tree-size` | `IrisTreeSize` | | `tree-sub-branches` | `IrisTreeSubBranches` | | `vacuum-settings` | `IrisVacuumSettings` | Registrants that are whole files (dimensions, regions, biomes, generators, loot tables, entities, spawners, markers, mods, objects, structures) are not snippet types; only nested field types listed above are. ### Registered schemas without a production authoring path Schema registration alone does not prove a runtime consumer. The following types are discoverable by loaders or Studio schema generation but are not supported pack features: | Surface | Current status | |---------|----------------| | `potion-effect` / `IrisPotionEffect` | Snippet schema exists, but no production field consumes this type; use the potion fields on `IrisEffect` instead | | `matter/` resources | A loader exists for Matter binaries, but generation and runtime code do not consume pack `matter/` resources | | `IrisObjectPlacement.translateCenter` | Serialized and copied by `toPlacement`, but no placement path reads the value | The `mods/*.json` family is likewise schema/tooling-only as documented above. ### Authoring snippets 1. Create `snippet//.json` matching the field type shape. 2. Reference as `"snippet//"` (no `.json` suffix in the string). 3. Prefer snippets for values reused across many biomes (decorators, styles, palettes). 4. Open studio so VSCode schemas list available snippet paths under `.iris/schema/snippet/`. ## Related commands - Pack validation: `/iris pack validate` — see `25 - Pack Management.md`, `04 - Commands & Permissions.md`. - Studio open/hotload: `10 - Studio & VSCode Schemas.md`.