Surface rule

This feature is exclusive to Java Edition.
 

Surface rules are used to determine the block for each solid position of the terrain. They are responsible for grass and dirt layers, creating different bands of terracotta in badlands, for deepslate, bedrock, and more.

Surface rules are used in the noise settings of a data pack.

JSON format

A surface rule is a type of decision tree. Using a combination of sequences and conditions, it can implement checks to place the right blocks in the right places.

  • [NBT Compound / JSON Object] The root object.
    • [String] type: Type of the surface rule as a resource location.
    • Extra fields of the surface rule, described below.

The possible values for [String] type and associated extra fields:

  • block — Places a specified block.
    • [NBT Compound / JSON Object] result_state: The block state to place.
      • Block state see Template:Nbt inherit/block state/template
  • condition — Checks a condition
    • [NBT Compound / JSON Object] if_true: The surface condition (see below) to check.
    • [NBT Compound / JSON Object] then_run: The surface rule to run if the condition matches.
  • sequence — Tries surface rules in order, only the first that matches is applied.
    • [NBT List / JSON Array] sequence: A list of surface rules to try.
      • [NBT Compound / JSON Object] A surface rule object.

Surface conditions

  • [NBT Compound / JSON Object] The root object.
    • [String] type: Type of the surface condition as a resource location.
    • Extra fields of the surface condition, described below.

The possible values for [String] type and associated extra fields:

  • above_preliminary_surface — Checks if the current position is above the preliminary surface level, which is a Y-level usually a few blocks below the main surface, ignoring noise caves. This is used to prevent grass blocks from being placed in noise caves. This condition has no extra fields. The preliminary surface level is calculated from the initial_density_without_jaggedness noise router density function.
  • biome — Checks the biome at the current position.
    • [NBT List / JSON Array] biome_is: A list of biomes where this condition matches.
      • [String] A resource location of a biome.
  • hole — Passes for columns where the surface depth is 0. This condition has no extra fields.
  • noise_threshold — Computes the noise value of the current column using a specified noise and checks if it is between the min and max threshold.
    • [String] noise: One noise (an [String] ID).
    • [Double] min_threshold: The minimum noise value where the condition passes.
    • [Double] max_threshold: The maximum noise value where the condition passes.
  • not — Inverts a surface conditions, passing when the nested condition fails.
    • [NBT Compound / JSON Object] invert: The surface condition object to invert.
  • steep — Checks if the current position is a steep face on the north or east sides of a mountain. This condition has no extra fields.
  • stone_depth — Checks if the current position is within a specified distance from the surface, either upward or downward, using terrain depth. This is used in vanilla to place grass blocks and dirt layers on the surface in the overworld, and soul sand, soul soil, gravel and basalt floors and ceilings in the nether.
    • [String] surface_type: Either floor or ceiling. If floor, the blocks will be placed based on the distance to the surface above, if ceiling, the distance to the surface below will be used instead.
    • [Int] offset: The vertical offset.
    • [Boolean] add_surface_depth: If true, adds the surface depth to the offset. Note: this is not add_stone_depth!
    • [Int] secondary_depth_range: Adds a mapped value of the secondary surface depth to the offset, calculated using the formula: map(surface_secondary(X,0,Z), -1, 1, 0, secondary_depth_range).
  • temperature — Checks if the current block is in a biome that is cold enough for snowfall. This condition has no extra fields.
  • vertical_gradient — Compares the current Y position, with a messy transition, just like the deepslate and bedrock transitions.
    • [String] random_name: Used as a seed to randomize the gradient.
    • [NBT Compound / JSON Object] true_at_and_below: The lower vertical anchor. Positions at and below this always pass.
      • Choices for a vertical anchor (must choose only one of the three) see Template:Nbt inherit/vertical anchor/template
    • [NBT Compound / JSON Object] false_at_and_above: The upper vertical anchor. Positions at and above this always fail. The Y-coords between the two vertical anchors produces a gradient where the probability of success is (false_at_and_above - Y) / (false_at_and_above - true_at_and_below).
      • Choices for a vertical anchor (must choose only one of the three) see Template:Nbt inherit/vertical anchor/template
  • water — Checks if the current position is above water, based on terrain depth. Note that if there is no water above this block, the condition always passes, regardless of the values of the fields.
    • [Int] offset: The value added to the water depth before the comparison is done. This value can be negative to match blocks at a specific depth relative to water surface.
    • [Int] surface_depth_multiplier: Value between -20 and 20. How much it is affected by the surface depth. surface_depth(X,Z) * surface_depth_multiplier is added to offset before comparing.
    • [Boolean] add_stone_depth: If true, adds the distance to the surface to the offset, effectively checking if the surface block above this one is above water.
  • y_above — Checks if the current position is above a specified height (exclusive).
    • [NBT Compound / JSON Object] anchor: The vertical anchor to compare the height with.
      • Choices for a vertical anchor (must choose only one of the three) see Template:Nbt inherit/vertical anchor/template
    • [Int] surface_depth_multiplier: Value between -20 and 20. How much it is affected by the surface depth. surface_depth(X,Z) * surface_depth_multiplier is added to anchor before comparing.
    • [Boolean] add_stone_depth: If true, adds the distance to the surface above to the offset.

Surface depth

The surface depth is an integer value computed for each column, which is used by various conditions. It uses the minecraft:surface noise. The calculation is as follows: floor(surface(X,0,Z) × 2.75 + 3.0 + positional_noise(X,0,Z) × 0.25) where surface returns the noise value of the minecraft:surface noise and positional_noise returns a random value between 0 and 1.

Secondary surface depth

The secondary surface depth is a value between -1 and 1 computed for each column, which can be used by the stone_depth condition. It uses the minecraft:surface_secondary noise.

Terrain depth

The generator tracks the vertical distance to the surface above (internally stoneDepthAbove) and the cavity below (internally stoneDepthBelow), as well as how deep underwater each block is (if there is any water above it at all; waterHeight). These values are used in the stone_depth, water and y_above conditions.

History

This section of the article is empty.
 
You can help by expanding it.

Navigation