Skip to main content

Overview

Surface modifiers allow you to inject or modify surface rules that control what blocks generate on the surface and underground in different biomes and conditions. This is essential for customizing terrain appearance without modifying biome files.

Add Surface Rule

Adds surface rules to specified dimension level stems. Surface rules determine which blocks generate at various heights and conditions.
public record AddSurfaceRuleModifier(
    int priority,
    List<ResourceKey<LevelStem>> levels,
    SurfaceRules.RuleSource surfaceRule
) implements Modifier

How It Works

Surface rule injection is independent of other modifiers. The modifier stores the rules during application, and they are later merged into the dimension’s noise generation settings during world initialization.

Parameters

type
string
required
Must be "lithostitched:add_surface_rule"
priority
integer
default:"1000"
Execution priority. Lower values execute first, affecting rule order.
levels
string[]
required
Array of dimension level stem registry IDs to apply the surface rule to.Common values:
  • "minecraft:overworld"
  • "minecraft:the_nether"
  • "minecraft:the_end"
surface_rule
object
required
A SurfaceRules.RuleSource object defining the surface rule logic.Supports all vanilla rule types plus Lithostitched extensions:
  • minecraft:sequence - Execute rules in order
  • minecraft:condition - Conditional rule application
  • minecraft:block - Place a specific block
  • minecraft:bandlands - Bandlands surface patterns (Lithostitched)
  • lithostitched:reference - Reference another surface rule

Examples

{
  "type": "lithostitched:add_surface_rule",
  "priority": 1000,
  "levels": ["minecraft:overworld"],
  "surface_rule": {
    "type": "minecraft:condition",
    "if_true": {
      "type": "minecraft:biome",
      "biome_is": ["minecraft:desert"]
    },
    "then_run": {
      "type": "minecraft:sequence",
      "sequence": [
        {
          "type": "minecraft:condition",
          "if_true": {
            "type": "minecraft:stone_depth",
            "offset": 0,
            "surface_type": "floor",
            "add_surface_depth": false,
            "secondary_depth_range": 0
          },
          "then_run": {
            "type": "minecraft:block",
            "result_state": {
              "Name": "minecraft:red_sand"
            }
          }
        }
      ]
    }
  }
}

Surface Rule Conditions

Lithostitched adds custom surface rule conditions beyond vanilla:

Slope Condition

Checks the steepness of terrain at a position.
public record SlopeCondition(
    double minSlope,
    double maxSlope
) implements SurfaceRules.ConditionSource
{
  "type": "lithostitched:slope",
  "min_slope": 0.0,
  "max_slope": 0.3
}
min_slope
number
default:"0.0"
Minimum slope value (0.0 = flat, 1.0 = vertical)
max_slope
number
default:"1.0"
Maximum slope value

Biome Condition

Extended biome matching with tag support.
{
  "type": "lithostitched:biome",
  "biomes": [
    "#minecraft:is_ocean",
    "minecraft:beach"
  ]
}

All Of Condition

All conditions must be true.
{
  "type": "lithostitched:all_of",
  "conditions": [
    {
      "type": "minecraft:biome",
      "biome_is": ["minecraft:plains"]
    },
    {
      "type": "minecraft:y_above",
      "anchor": {"absolute": 80},
      "surface_depth_multiplier": 0,
      "add_stone_depth": false
    }
  ]
}

Any Of Condition

At least one condition must be true.
{
  "type": "lithostitched:any_of",
  "conditions": [
    {
      "type": "minecraft:biome",
      "biome_is": ["minecraft:desert"]
    },
    {
      "type": "minecraft:biome",
      "biome_is": ["minecraft:badlands"]
    }
  ]
}

Surface Rule Sources

Bandlands Rule

Creates repeating horizontal bands of blocks, similar to badlands biomes.
public record BandlandsRule(
    List<Band> bands
) implements SurfaceRules.RuleSource
See the bandlands example above for usage.

Reference Rule

References another surface rule by registry ID, enabling rule reuse.
public record ReferenceRule(
    ResourceKey<SurfaceRules.RuleSource> rule
) implements SurfaceRules.RuleSource
{
  "type": "lithostitched:reference",
  "rule": "mymod:common_surface_rules"
}

Priority and Rule Order

Surface rules execute in sequence, with earlier rules taking precedence. Priority affects the order in which modifiers add rules:
1

Lower priority modifiers add rules first

Priority 500 rules are added before priority 1000 rules
2

Rules within each modifier maintain their order

Sequence rules execute top to bottom
3

Earlier rules can override later rules

First matching rule wins

Best Practices

Wrap multiple rules in a minecraft:sequence to ensure proper execution order. The first matching rule in the sequence will be applied.
Use biome tags (e.g., #minecraft:is_mountain) instead of listing individual biomes for more flexible and maintainable rules.
  • Generate test worlds with F3+G chunk borders visible
  • Verify surface blocks at different heights and biomes
  • Check transitions between biomes
  • Test in different climate zones
  • Avoid overly complex condition chains
  • Use simpler conditions when possible
  • Profile with F3 debug screen if experiencing lag
Create reusable surface rules in separate files and reference them to avoid duplication and simplify maintenance.

Common Use Cases

Custom Biome Surfaces

Define unique surface blocks for custom biomes using biome conditions

Height-Based Layers

Create snow caps, stone cliffs, or other height-dependent surfaces

Slope-Based Terrain

Use slope conditions to generate stone on steep cliffs

Banded Rock Formations

Create badlands-style banded terracotta formations

Technical Details

Application Timing

The AddSurfaceRuleModifier.applyModifier() method is empty because surface rules are applied differently than other modifiers:
@Override
public void applyModifier() {}
Surface rules are collected during modifier registration and then injected into the noise generation settings when dimensions are initialized. This allows proper integration with Minecraft’s surface generation pipeline.

Level Stem Reference

The levels parameter uses ResourceKey<LevelStem> rather than direct dimension references:
List<ResourceKey<LevelStem>> levels
This allows modifiers to target dimensions that may not exist yet during modifier registration.

Surface Conditions

Explore all surface rule condition types

Bandlands System

Learn about bandlands band types

Density Modifiers

Modify terrain shape with density functions

Examples

See practical surface rule examples

Build docs developers (and LLMs) love