Files
Iris/docs/17 - Trees, Fungi, Coral, Crystals, Formations, Ruins.md
T
Brian Neumann-Fopiano ebfe278b3b Docvks
2026-08-10 15:47:26 -04:00

16 KiB
Raw Blame History

17 - Trees, Fungi, Coral, Crystals, Formations, Ruins

Procedural objects are baked from JSON settings into deterministic block blobs and scattered like .iob placements. They live under biome or region proceduralObjects and do not require object files. Separate systems: sapling tree overrides (IrisTree on object placements) and dimension treeSettings for growth replacement mode.

Related: 13 - Biomes.md, 12 - Regions.md, 15 - Caves & Carving.md, 16 - Surfaces, Decorators & Deposits.md, 18 - Structures Overview.md, 19 - Objects.md, 20 - Object Placement.md.

Tutorial: generate a procedural tree from biome JSON

Use a validating OVERWORLD pack with mantle and decoration enabled. Save this complete test biome as biomes/tutorial/tree-test.json, list tutorial/tree-test as a region land biome, and temporarily focus the dimension on it:

{
  "name": "Procedural Tree Test",
  "derivative": "minecraft:plains",
  "vanillaDerivative": "minecraft:plains",
  "layers": [
    { "palette": [{ "block": "minecraft:grass_block" }] }
  ],
  "generators": [
    { "generator": "flat", "min": 16, "max": 16 }
  ],
  "proceduralObjects": {
    "trees": [
      {
        "name": "tutorial-oak",
        "chance": 1,
        "density": 2,
        "variants": 4,
        "seed": 9001,
        "trunk": "minecraft:oak_log",
        "leaves": "minecraft:oak_leaves",
        "profile": "OAK",
        "heightMin": 7,
        "heightMax": 11,
        "plausible": true
      }
    ]
  }
}
  1. Reuse generators/flat.json from the minimal dimension walkthrough, validate the pack, and open Studio on seed 1337.
  2. Generate several new chunks. Success is a repeatable set of oak variants anchored to the grass surface, with leaves that use normal decay-distance data because plausible is true.
  3. If no trees appear, confirm the biome is focused, new chunks were generated, dimension decorate and useMantle are true, and the console did not reject every baked variant. Keep chance: 1 until placement is proven.
  4. Tune height, profile, trunk shape, and canopy before lowering chance or increasing density. Remove focus and reduce chance only after the same seed reproduces the shapes across a Studio reopen.

Container (IrisProceduralObjects)

Field Type Contents
trees IrisProceduralTree[] Procedural trees
fungi IrisFungus[] Mushrooms / shelf fungi
coral IrisCoral[] Underwater coral forms
crystals IrisCrystal[] Cave crystal clusters
formations IrisFormation[] Rock landmarks
ruins IrisRuin[] Crumbling man-made shapes

Attach on biomes and regions:

{
"proceduralObjects": {
  "trees": [ { "...": "..." } ],
  "crystals": [ { "...": "..." } ]
}
}

Shipping overworld content currently relies on .iob tree objects more than procedural trees; the fields and generators are fully available for pack authors.

Shared placement fields

All procedural types implement placement via asPlacement()IrisObjectPlacement-compatible settings:

Field Typical default Notes
name type-specific Log key / variant key prefix
chance 0.020.4 Per-chunk attempt probability
density 1 Attempts if chance passes
variants 68 Pre-baked shape count (1..64)
seed 1337 Deterministic bake seed
mode CENTER_HEIGHT (ruins: MIN_HEIGHT) Terrain anchor mode
rotation object rotation Placement rotation
clamp height limits Min/max place height
carvingSupport SURFACE_ONLY (crystals: CARVING_ONLY) Surface vs cave
underwater type-specific Coral default true
translate zero XYZ offset
stiltSettings / vacuumSettings optional For stilt/vacuum modes

Variant objects load as keys like procedural/<name>#<i> (trees: procedural/tree/<name>#<i>). Same seed + settings always bake the same variants.

CarvingMode: SURFACE_ONLY, CARVING_ONLY, ANYWHERE.

Common ObjectPlaceMode values: CENTER_HEIGHT, MAX_HEIGHT, MIN_HEIGHT, FAST_* variants, STILT, MIN_STILT, FAST_STILT, CENTER_STILT, ERODE_STILT, ORGANIC_STILT, vacuum modes. Cave defaults often use organic/fast stilt to prevent floating.

Procedural trees (IrisProceduralTree)

Baked by ProceduralTreeGenerator.

Core materials and size

Field Default Notes
trunk / trunkPalette oak log Palette wins
leaves / leavesPalette oak leaves Palette wins; real leaves get decay distances when plausible
plausible true Vanilla leaf distance / non-persistent
heightMin / heightMax 8 / 12 Trunk height range across variants
trunkWidth 1 Base trunk thickness
profile OAK Named canopy silhouette

Profiles (IrisTreeProfile)

OAK, BIRCH, SPRUCE, JUNGLE, ACACIA, DARK_OAK, DARK_OAK_FLAT, DARK_OAK_FLAT_WIDE, CHERRY, PALM, WILLOW, COLUMNAR, BUSH, MEGA_SPRUCE.

Trunk shaping

Field Default Notes
trunkShape CONSTANT IrisTreeFunction over trunk width by height
shapeStart / shapeEnd 1 / 1 Linear width multipliers
shapeSteepness 5 Sigmoid steepness
shapeBase 2.718281828 Logarithmic base
shapePeriod / shapeAmplitude 1 / 0.2 Sine width controls
shapePeakOffset / shapeFloor 0.5 / 0.5 Parabolic waist position and minimum fraction
leanAzimuth / leanAngle 0 / 0 Compass direction and degrees from vertical
trunkCurve / curveSteepness LINEAR / 8 Lean accumulation and sigmoid steepness
leanAzimuthMode CONSTANT How lean direction changes over height
azimuthStart / azimuthEnd 0 / 0 Linear azimuth endpoints
azimuthTurns 1 Full turns for SPIRAL
azimuthAmplitude / azimuthPeriod / azimuthOffset 90 / 1 / 0 Sine azimuth controls
azimuthScale 1 Noise azimuth scale
azimuthWhorlCount 5 Branches per ring for WHORL
trunkForks / forkHeight / forkAngle 1 / 0.5 / 25 Fork count, normalized split height, and outward angle
secondaryTrunk / secondaryTrunkPalette null Optional band material; palette wins
secondaryTrunkStart / secondaryTrunkEnd 0.5 / 1 Normalized secondary band bounds
roots / rootStyle true / BUTTRESS Enable roots and select TAPROOT, BUTTRESS, or STILT
rootDepth / rootFlare 0 / 0 Explicit values; zero uses automatic scaling

IrisTreeFunction: CONSTANT, LINEAR, SIGMOID, LOG, SINE, PARABOLIC, EXPONENTIAL, SQRT, STEP, BELL, EASE_IN_OUT.

IrisTreeAzimuthMode: CONSTANT, LINEAR, SPIRAL, SINE, NOISE, RANDOM, GOLDEN_ANGLE, ALTERNATING, WHORL, ZIGZAG.

Canopy (IrisTreeCanopy)

Field Default Notes
startAngle 90 Disc elevation (90 flat, lower = dome, higher = umbrella)
squish 1 Vertical scale
mode TRIMMED Leaf fill mode
leafDensity 0.85 For density/noise modes
crownStretchX / crownStretchZ 1 Ellipse crown
layers [] Explicit discs override profile
branches null Branch system drives canopy when set

IrisTreeLayer: yOffset, radius.

IrisTreeLeafMode: TRIMMED, FILLED, DENSITY, NOISE, HOLLOW, GRADIENT, CLUMPED, TATTERED, SPARSE.

Branches (IrisTreeBranches)

Probability functions (IrisTreeBranchProbability): CONSTANT, LINEAR, SIGMOID, TOP_HEAVY, GAUSSIAN, NOISE, BOTTOM_HEAVY, PERIODIC, BAND, INVERSE_GAUSSIAN, EXPONENTIAL_DECAY.

Field Default Role
probabilityFunction TOP_HEAVY Branch chance curve over normalized trunk height
probabilityConstant 0.5 CONSTANT chance
probabilityBase / probabilityCrown 0 / 1 LINEAR endpoints
probabilitySteepness / probabilityMidpoint 10 / 0.7 SIGMOID controls
probabilityExponent 2 TOP_HEAVY exponent
probabilityMean / probabilityStd 0.7 / 0.15 Gaussian center and deviation
probabilityScale 1 Noise scale
probabilityPeriods 5 Periodic whorl count
lengthFunction LINEAR Branch-length curve over trunk height
lengthBase / lengthCrown 1 / 4 Linear endpoints
lengthConstant / lengthMax 3 / 4 Constant value and nonlinear maximum
lengthSteepness 5 Sigmoid length steepness
azimuthMode / azimuth RANDOM / 0 Direction selection and fixed direction for CONSTANT
elevation / sag 0 / 0 Initial elevation and catenary droop
branchDepth 1 Recursive branch levels, 06
leafStartUp false Clamp primary branches so they do not droop below horizontal
clusterRadius / clusterMode / clusterDensity 2 / TRIMMED / 0.85 Primary tip leaf cluster
subBranches null Optional IrisTreeSubBranches configuration

subBranches fields: count (1), pitchDelta (0), yawDelta (45), lengthScale (0.5), sag (0), clusterRadius (1), clusterMode (TRIMMED), and clusterDensity (0.85).

Secondary leaves and accents

Field Notes
secondaryLeaves Single accent block
weightedSecondaryLeaves Weighted list (block, weight)
secondaryLeavesPalette Wins over both
secondaryLeafFraction Fraction replaced
decorators IrisTreeDecorator[] post accents

Tree decorator (IrisTreeDecorator)

Field Default Notes
target BRANCH_TIP Placement locus
block / palette required block Palette wins
chance 0.5 Per candidate
length 1 Max hang for CANOPY_HANG
axisAware false Orient facing away from trunk

Targets: BRANCH_TIP, TRUNK_SURFACE, CANOPY_TOP, CANOPY_BOTTOM, TRUNK_BASE, LEAF_SURFACE, CANOPY_HANG, BRANCH_SURFACE, TRUNK_TOP, GROUND_SCATTER.

Minimal tree example

{
  "name": "oak-plains",
  "chance": 0.35,
  "density": 2,
  "variants": 8,
  "seed": 9001,
  "trunk": "minecraft:oak_log",
  "leaves": "minecraft:oak_leaves",
  "profile": "OAK",
  "heightMin": 7,
  "heightMax": 11,
  "plausible": true,
  "roots": true,
  "rootStyle": "BUTTRESS",
  "canopy": {
    "mode": "TRIMMED",
    "startAngle": 88,
    "squish": 0.9
  }
}

Sapling overrides (IrisTree + IrisTreeSettings) — not procedural trees

IrisTree on object placements (IrisObjectPlacement.trees) maps grown sapling types/sizes to that object:

Field Notes
treeTypes Bukkit TreeType names
anyTree Match any type
sizes IrisTreeSize width×depth sapling footprints
anySize Match any size

Dimension treeSettings: enabled, mode (FIRST biome→region→dimension, or ALL pool). This is growth replacement, not worldgen scatter.

Fungi (IrisFungus)

Field Default Notes
stem / stemPalette mushroom_stem Palette wins
cap / capPalette red_mushroom_block Palette wins
stemHeightMin / Max 5 / 9 Stem height
stemWidth 1 13 column
stemCurve / stemLeanAzimuth / stemWaveAmplitude / stemWavePeriods lean/wave Organic stem
capShape DOME DOME, FLAT, FUNNEL, CONICAL, FLAT_WIDE
capRadiusMin / Max 3 / 5 Cap size
capThickness / capSquish / capDroop / capOverhang shape controls
gillBlock / gillPalette / gillChance underside
spotBlock / spotPalette / spotChance top speckles
shelf / shelfRadius false / 3 Sideways polypore mode

Coral (IrisCoral)

Defaults: underwater: true, waterlogged: true, mode: CENTER_HEIGHT.

Field Notes
form BRANCHING, FAN, BRAIN, PILLAR, TENDRIL
block / blockPalette Structure body
tipBlock / tipPalette / tipChance Fans/pickles
heightMin / heightMax Overall height
spread / sway Horizontal reach / wobble
Branching-only branchCount, branchLength, branchElevation, branchAzimuth (GOLDEN_ANGLE/EVEN/RANDOM), subBranches, subBranchCount, subBranchScale, tipClusterRadius
Brain-only brainRadius, brainRoughness
Pillar-only pillarRadius
Fan-only fanWidth
Tendril-only tendrilCount

Crystals (IrisCrystal)

Defaults: carvingSupport: CARVING_ONLY (cave-first).

Field Notes
growthSurface FLOOR, CEILING, WALL (orients bake only)
block / blockPalette Shard body
tipBlock / tipPalette / tipChance Tip accents
glow / glowBlock Auto glow tips if no tip block
baseBlock / basePalette / baseRadius / baseNoise Budding base blob
shardCountMin / Max Shard count
shardLengthMin / Max Shard length
shardBaseRadius / shardTaper Taper geometry
spreadAngle Cone half-angle degrees
distribution RANDOM or GOLDEN_ANGLE
jitter Angular noise

Formations (IrisFormation)

Natural landmarks. Extra field surfaceSupportBuffer (default 3) for foundation solidity.

Field Notes
form SPIRE, HOODOO, ARCH, SEA_STACK, BOULDER, BASALT_COLUMN
block / blockPalette Body
capBlock / capPalette Caprock
strataPalette / strataThickness Horizontal bands
heightMin / heightMax Height
baseWidthMin / baseWidthMax / topWidth Radii
profile CONSTANT, LINEAR, TAPER, PARABOLIC, BULGE
profileWaist / profileWaistFloor Parabolic waist
lean / leanAzimuth Tilt
roughness / jitter Surface erosion
Hoodoo hoodooCapRadius, hoodooCapHeight
Arch archSpan, archThickness
Basalt basaltColumns, basaltColumnRadius, basaltHeightVariance

Ruins (IrisRuin)

Field Default Notes
form PILLAR PILLAR, WALL, ARCH, FLOOR_SLAB, RUBBLE
block / blockPalette cobblestone Structure body
heightMin / Max 4 / 9 Height band
widthMin / Max 1 / 3 Footprint X
lengthMin / Max 3 / 7 Footprint Z
weatheredBlock / weatheringPalette mossy_cobblestone Weather remap
mossiness / weatheringScale 0.45 / 1 Weather intensity/scale
erosion / erosionScale 0.25 / 1.5 Missing-block noise
buriedFraction 0.2 Fraction sunk below surface
accents [] IrisRuinDecorator list

Ruin decorator (IrisRuinDecorator)

Field Default Notes
target TOP TOP, SURFACE, BASE_SCATTER
block / palette required Palette wins
chance 0.4 Per candidate
scatterRadius 2 BASE_SCATTER extent

Extend to other procedural families

  1. Choose system: trees for forests, fungi for mushroom biomes, coral for warm oceans, crystals for cave biomes, formations for deserts/coasts, ruins for sparse land.
  2. Add one entry using the minimal tree example above or the smallest equivalent for that family. Use one material, low chance, low density, and a fixed seed.
  3. Focus the target biome, validate, and generate enough new chunks to observe both placements and empty space.
  4. Tune dimensions and silhouette before raising density. Keep variants at 412; variants are baked during first use/cache warmup.
  5. Add palettes and decorators after shape is stable. Match carvingSupport to the environment; crystals and cave props use CARVING_ONLY.
  6. For cave props, prefer stilt place modes and the cave profile's defaultObjectPlaceMode.
  7. Remove biome focus and verify the family remains limited to its intended biome/region scope.

The tutorial passes when the same seed reproduces the family, placement density leaves the intended negative space, and no invalid variant is skipped in the log. Prefer .iob objects instead when exact hand-authored geometry matters more than variation.

Practical notes

  • Procedural content is separate from objects placements and from structure jigsaws.
  • plausible: true on trees enables natural leaf decay; false forces persistent leaves.
  • Formation surfaceSupportBuffer interacts with dimension objectSurfaceSupportBuffer (max of requirements).
  • Do not confuse IrisTree (sapling→object) with IrisProceduralTree (worldgen bake).
  • Empty variant bake (invalid sizes) skips that entry; check logs if nothing places.