Files
Iris/docs/23 - Loot, Entities, Spawners, Markers.md
T
2026-08-08 00:29:48 -06:00

17 KiB
Raw Blame History

23 - Loot, Entities, Spawners, Markers

Loot tables fill containers and entity drop inventories. Entities describe what to spawn. Spawners schedule ambient and initial spawns. Markers pin spawners to placed objects. Together they form the pack-side entity and loot systems.

Related: 05 - Concepts & Pack Layout.md, 11 - Dimensions.md, 12 - Regions.md, 13 - Biomes.md, 19 - Objects.md, 20 - Object Placement.md, 03 - Configuration.md, 10 - Studio & VSCode Schemas.md.

Where files live

Path Registrant Role
loot/<key>.json IrisLootTable Weighted item tables
entities/<key>.json IrisEntity Entity type, gear, drops, flags
spawners/<key>.json IrisSpawner When/where entity keys spawn
markers/<key>.json IrisMarker Marker definition that lists spawner keys

Keys use pack-relative paths without .json (for example standard/hostile/zombie, temperate/hostile, global-treasure).

Wiring

Source Field Loads
Dimension loot (IrisLootReference) Global tables for the dimension
Region loot Regional tables
Biome loot Biome tables
Entity loot Drop tables when entity is Lootable
Object placement loot / vanillaLoot Containers in placed objects
Dimension / region / biome entitySpawners Spawner keys for ambient spawning
Object placement markers (IrisObjectMarker[]) Places markers on matching blocks
Marker spawners Spawner keys at that marker

Ambient spawning merges dimension, then region, then surface-biome entitySpawners when settings.json has world.ambientEntitySpawningSystem true (default). Marker spawning uses mantle markers when world.markerEntitySpawningSystem is true (default).

The shipping overworld pack includes entities/standard/..., spawners/<climate>/..., and loot/... resources, but its dimensions, regions, and biomes do not currently reference those spawner keys through entitySpawners. Ambient Iris spawners only fire after a parent lists them.

Loot tables (IrisLootTable)

Folder: loot/.

Field Type Default Notes
name string "" Required display name (min length 2)
rarity int ≥ 1 1 Table 1-in-N chance factor
minPicked int 0..64 1 Min successful picks per roll
maxPicked int 1..64 5 Max successful picks per roll
maxTries int 1..256 10 Cap on pick attempts
loot IrisLoot[] [] Entries; empty table yields no items

Roll procedure: RNG picks a random entry each try, keeps items that pass entry rarity and match the requested InventorySlotType, stops at maxPicked successes or maxTries.

Loot entry (IrisLoot, snippet type loot)

Field Type Default Notes
type string "" Required. Vanilla material name such as diamond or DIAMOND_SWORD (not minecraft:* except for namespaced third-party items)
slotTypes InventorySlotType STORAGE STORAGE, FUEL, FURNACE, BLAST_FURNACE, SMOKER
rarity int ≥ 1 1 Sub-rarity after table pick
minAmount / maxAmount int 1..64 1 Stack size
displayName string null Color codes via &
lore string[] [] Wrapped lore lines
minDurability / maxDurability 0..1 0 / 1 Remaining durability percent
customModel int null Custom model data float
unbreakable boolean false
itemFlags string[] [] Bukkit ItemFlag names
enchantments IrisEnchantment[] []
attributes IrisAttributeModifier[] []
dyeColor string null DyeColor name for colorable items
leatherColor string null #RRGGBB for leather armor
customNbt object null Platform NBT map; also used for third-party items

Combined rarity is table rarity × entry rarity. Studio debug lore can show table name and combined chance.

Loot reference (IrisLootReference, snippet type loot-registry)

Used on dimensions, regions, biomes, and entities:

{
"loot": {
  "mode": "FALLBACK",
  "multiplier": 0.5,
  "tables": ["temperate/clutter", "temperate/food"]
}
}
Field Type Default Notes
mode IrisLootMode ADD ADD, CLEAR, REPLACE, FALLBACK
tables string[] [] Loot table keys
multiplier double 0..16 1 Scales loot source counts
  • ADD — append to parent tables.
  • CLEAR / REPLACE — drop parent tables then add these (same effective clear-then-add).
  • FALLBACK — use only when no object-level loot already defined.

Overworld dimension example:

{
"loot": {
  "mode": "FALLBACK",
  "tables": ["global-clutter"]
}
}

Object loot

On IrisObjectPlacement:

Field Notes
loot IrisObjectLoot[] — pack table name + optional block filter + weight
vanillaLoot Vanilla loot table bindings
overrideGlobalLoot When true, object tables replace dim/region/biome tables for that placement

IrisObjectLoot fields: name (loot table key), weight (default 1), filter (block list, empty = all containers), exact (exact block-data match).

Real overworld loot sample

From loot/global-treasure.json (abbreviated):

{
  "name": "Global Treasure",
  "rarity": 1,
  "maxPicked": 2,
  "minPicked": 0,
  "maxTries": 20,
  "loot": [
    { "type": "diamond", "minAmount": 1, "maxAmount": 3, "rarity": 4, "slotTypes": "STORAGE" },
    { "type": "emerald", "minAmount": 1, "maxAmount": 4, "rarity": 3, "slotTypes": "STORAGE" },
    {
      "type": "enchanted_book",
      "minAmount": 1,
      "maxAmount": 1,
      "rarity": 14,
      "slotTypes": "STORAGE",
      "enchantments": [{ "enchantment": "mending", "minLevel": 1, "maxLevel": 1, "chance": 1.0 }]
    }
  ]
}

Entities (IrisEntity)

Folder: entities/.

Field Type Default Notes
type string null Required namespaced entity type (minecraft:zombie or bare keys resolved by platform). Use unknown with specialType for external plugins
specialType string "" PluginName:MobName via external data service
applySettingsToCustomMobAnyways boolean false Apply Iris gear/flags on custom mobs
reason string null CreatureSpawnEvent.SpawnReason name; default NATURAL
customName / customNameVisible string / bool "" / false
aware / ai boolean true Mob awareness / AI
glowing / gravity / invulnerable / silent boolean false / true / false / false
pickupItems / removable / keepEntity / baby boolean false
helmet / chestplate / leggings / boots / mainHand / offHand IrisLoot null Gear; each entry uses its own rarity
passengers IrisEntity[] [] Nested riders
attributes IrisAttributeModifier[] []
loot IrisLootReference empty ADD Drop tables
leashHolder IrisEntity null Spawns holder and leashes
spawnEffect IrisEffect null On-spawn effect
spawnEffectRiseOutOfGround boolean false Rise-from-ground VFX
pandaMainGene / pandaHiddenGene string null Panda genes
surface IrisSurface LAND Spawn surface check: LAND, ANIMAL, WATER, OVERWORLD, LAVA
rawCommands IrisCommand[] [] Run with {x} {y} {z}

Minimal overworld entities are often one field:

{"type": "ZOMBIE"}

Path key: entities/standard/hostile/zombie.json → load key standard/hostile/zombie.

Entity commands (IrisCommand)

rawCommands executes console commands after an entity spawns. The same command object is also used by ambient effect command registries.

Field Default Behavior
commands [] Required command strings; a leading / is removed and {x}, {y}, {z} are replaced with block coordinates
delay 0 Delay before first execution, in server ticks; negative values clamp to zero
repeat false Repeats indefinitely after the first delay; no cancellation handle is exposed and repeats stop on server restart
repeatDelay 100 Ticks between repeats; values below one clamp to one
timeBlock any time Required world-time window
weather ANY Required weather: NONE, DOWNFALL, DOWNFALL_WITH_THUNDER, or ANY

Bukkit and modded entity spawning both apply AI/awareness flags, spawn effects, and raw commands. Spawner time and weather gates are also enforced on both platform families.

Ambient effects (IrisEffect)

Biomes and regions accept effects[]. Each entry performs a 1-in-chance check no more often than interval milliseconds and can combine a potion, sound, particle, and command registry.

Field Default / range Behavior
interval 150 ms, ≥0 Minimum interval between effect attempts
chance 50, ≥1 One successful attempt in this many intervals
potionEffect "" Potion-effect registry key
potionStrength -1 (11024) Amplifier; -1 disables potion application
potionTicksMin / potionTicksMax 75 / 155 Random potion duration in ticks
sound null Sound registry key
soundDistance 12 (0512) Maximum random sound offset from the player
minPitch / maxPitch 0.5 / 1.5 Random pitch interval
volume 1.5 Sound volume
particleEffect null Particle registry key; modded supports simple particle types that need no extra particle data
particleOffset 0 (3232) Random vertical surface offset
particleCount 0 (0512) Count; zero lets the alternate XYZ values behave as motion on Bukkit
particleDistance 20 (064) Forward sampling distance
particleDistanceWidth 24 (0128) Side-to-side sampling radius
particleAway 5 (016) Minimum forward offset
particleAltX / particleAltY / particleAltZ 0 (88) Particle offset or motion components
randomAltX / randomAltY / randomAltZ true / false / true Randomize each alternate component between its negative and positive value
extra 0 Particle-specific extra value
commandRegistry null Optional command casting configuration

IrisCommandRegistry fields:

Field Default Behavior
rawCommands [] IrisCommand[] to run
commandOffsetX / commandOffsetY / commandOffsetZ 0 (88) Coordinate offsets from the player
commandRandomAltX / commandRandomAltY / commandRandomAltZ true / false / true Randomize each coordinate within the signed offset
commandAllRandomLocations true Pick a new random coordinate for each command object; false reuses one coordinate

Example:

{
  "particleEffect": "minecraft:ash",
  "particleCount": 8,
  "sound": "minecraft:ambient.cave",
  "interval": 1000,
  "chance": 8,
  "commandRegistry": {
    "commandOffsetX": 4,
    "commandOffsetZ": 4,
    "rawCommands": [{ "commands": ["particle minecraft:smoke {x} {y} {z}"] }]
  }
}

Spawners (IrisSpawner)

Folder: spawners/.

Field Type Default Notes
spawns IrisEntitySpawn[] [] Ongoing spawns
initialSpawns IrisEntitySpawn[] [] Per-chunk initial pass (EXECUTES PER CHUNK)
maxEntitiesPerChunk int 1 Skip if living entities exceed
timeBlock IrisTimeBlock any time startHour / endHour in 24h (024)
weather IrisWeather ANY NONE, DOWNFALL, DOWNFALL_WITH_THUNDER, ANY
maximumRate IrisRate infinite Global rate limit
maximumRatePerChunk IrisRate infinite Per-chunk rate limit
allowedLightLevels IrisRange 0..15 Inclusive block light
group IrisSpawnGroup NORMAL Placement band

IrisSpawnGroup:

Value Placement
NORMAL Surface land biomes only
CAVE Valid for all biome inferred types; uses cave-floor markers when available
UNDERWATER Sea biomes, between seafloor and surface
BEACH Shore biomes

IrisRate: amount (0 = infinite) and per (IrisDuration). Empty duration means an infinite rate and is always allowed.

IrisDuration fields are additive:

Field Runtime unit
milliseconds 1 ms
minecraftTicks 50 ms
seconds / minutes / hours / days Real-time units
minecraftHours 50 real seconds
minecraftDays 20 real minutes
minecraftWeeks 7 Minecraft days (2 h 20 min)
minecraftLunarCycles 8 Minecraft days (2 h 40 min)

Entity spawn entry (IrisEntitySpawn, snippet entity-spawn)

Field Type Default Notes
entity string "" Required entity key
rarity int ≥ 1 1 1-in-N for some spawn paths
minSpawns / maxSpawns int ≥ 1 1 Count range when selected

Overworld sample spawners/temperate/hostile.json:

{
  "group": "NORMAL",
  "maximumRate": { "amount": 8, "per": { "seconds": 15 } },
  "timeBlock": { "startHour": 20, "endHour": 3 },
  "maxEntitiesPerChunk": 2,
  "weather": "ANY",
  "spawns": [
    { "entity": "standard/hostile/zombie", "rarity": 5, "maxSpawns": 4, "minSpawns": 2 },
    { "entity": "standard/hostile/skeleton", "rarity": 30, "maxSpawns": 2, "minSpawns": 1 }
  ]
}

To activate ambient spawning, list the spawner key on a parent:

{
"entitySpawners": ["temperate/hostile", "temperate/passive"]
}

Markers (IrisMarker)

Folder: markers/.

Field Type Default Notes
spawners string[] [] Spawner keys attached at this marker
removeOnChange boolean true Drop marker when assigned block changes
emptyAbove boolean true Require two air blocks above when placing
exhaustionChance double 0 Chance to remove marker on use; <0 never; ≥1 always on first use

Placing markers from objects (IrisObjectMarker, snippet object-marker)

On object placement markers[]:

Field Type Notes
mark IrisBlockData[] Required block types to tag
marker string Required marker key
maximumMarkers int 1..16 Default 8
exact boolean Exact block-data match

When marker entity spawning is enabled, MarkerSpawnScanner loads the marker tag, resolves its spawners, and WorldEntitySpawner fires those spawners at the marker position. Marker exhaustion can remove the mantle marker after use.

Custom block drops (IrisBlockDrops)

Dimensions, regions, and biomes accept blockDrops[]. On Bukkit, a matching biome provider runs first; unless any matching biome provider has skipParents: true, matching region and dimension providers are appended in that order.

Field Default Behavior
blocks [] Required IrisBlockData[] to match
exactBlocks false False compares material only; true compares the complete block state
drops [] IrisLoot[]; each entry's rarity is rolled independently
skipParents false On a matching biome provider, prevents region and dimension drop providers from running for that break
replaceVanillaDrops false If any matching provider enables it, suppresses vanilla block drops while retaining Iris drops from all selected providers
{
  "blocks": [{ "block": "minecraft:stone" }],
  "exactBlocks": false,
  "drops": [{ "type": "flint", "rarity": 4 }],
  "skipParents": false,
  "replaceVanillaDrops": false
}

The custom block-drop router is a Bukkit runtime feature; modded pack loading preserves the schema but does not install the Bukkit block-break event router.

Runtime settings that gate spawning

From settings.jsonworld:

Key Default Effect
ambientEntitySpawningSystem true Dim/region/biome entitySpawners
markerEntitySpawningSystem true Marker-driven spawners
targetSpawnEntitiesPerChunk 0.95 Ambient density target
asyncTickIntervalMS 700 Spawn tick interval
forcePersistEntities true Force entity persistence globally

Studio command /iris studio loot previews chest loot at the player position (see 10 - Studio & VSCode Schemas.md, 04 - Commands & Permissions.md).

Authoring checklist

  1. Write loot/<key>.json tables; reference them from dim/region/biome loot.tables or object loot[].name.
  2. Write entities/<key>.json with at least type.
  3. Write spawners/<key>.json with spawns entity keys and rates.
  4. Add spawner keys to entitySpawners on dimension, region, and/or biome — or attach via markers on object placements.
  5. Optional markers under markers/ plus placement markers arrays for structure-bound spawns.
  6. Validate with studio open + hotload; use studio loot preview for chests.