Skip to content

Block column feature

The block_column feature allows you to add a column of blocks (e.g. sugar cane or cacti) to the world.

Configuration

The following configuration options are available:

Option Type Description
layers An array of Layers. See below for more information Defines which block states should be used at specific heights.
direction north, east, south, west, up or down Determines the direction of the column.
allowed_placement A BlockPredicate A predicate that has to match every block in the column before the block is placed.
prioritize_tip A boolean When set to true, all underlying block will be removed if the current block doesn't match the provided BlockPredicate

In code, the BlockColumnConfiguration class is used to configure the feature.

Layer

Layers have 2 options: height, an IntProvider that determines the height of this layer, and block, a BlockStateProvider that determines the block state to use for this layer.

Examples

As an example, here's the configured feature used to place cacti in the desert.
Please note that Minecraft uses the random_patch feature to actually spread cacti and sugar cane.

Cactus

ConfiguredFeatures.kt
@OptIn(ExperimentalWorldGen::class)
@Init(stage = InitStage.POST_PACK_PRE_WORLD)
object ConfiguredFeatures : FeatureRegistry by ExampleAddon.registry {

    val CACTUS = registerConfiguredFeature(
        "cactus",
        Feature.BLOCK_COLUMN,
        BlockColumnConfiguration(
            listOf(BlockColumnConfiguration.Layer(BiasedToBottomInt.of(1, 3), SimpleStateProvider.simple(Blocks.CACTUS))), 
            Direction.UP, 
            BlockPredicate.matchesBlocks(Blocks.AIR), 
            false 
        )
    )

}
configured_feature/cactus.json
{
  "type": "minecraft:block_column",
  "config": {
    "direction": "up", 
    "allowed_placement": {
      "type": "minecraft:matching_blocks",
      "blocks": "minecraft:air" 
    },
    "prioritize_tip": false, 
    "layers": [
      { 
        "height": { 
          "type": "minecraft:biased_to_bottom",
          "value": {
            "max_inclusive": 3,
            "min_inclusive": 1
          }
        },
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:cactus",
            "Properties": {
              "age": "0"
            }
          }
        }
      }
    ]
  }
}

Result

Glow berry vines

Or, as another example, here's the configured and placed feature for glow berries/cave vines.

ConfiguredFeatures.kt
@OptIn(ExperimentalWorldGen::class)
@Init(stage = InitStage.POST_PACK_PRE_WORLD)
object ConfiguredFeatures : FeatureRegistry by ExampleAddon.registry {

    val CAVE_VINE: ConfiguredFeature<BlockColumnConfiguration, Feature<BlockColumnConfiguration>>

    init {
        val upperStateProvider = WeightedStateProvider( 
            SimpleWeightedRandomList.builder<BlockState>()
                .add(Blocks.CAVE_VINES_PLANT.defaultBlockState(), 4)
                .add(Blocks.CAVE_VINES_PLANT.defaultBlockState().setValue(CaveVines.BERRIES, true), 1)
        )

        val bottomStateProvider = RandomizedIntStateProvider(WeightedStateProvider( 
            SimpleWeightedRandomList.builder<BlockState>()
                .add(Blocks.CAVE_VINES.defaultBlockState(), 4)
                .add(Blocks.CAVE_VINES.defaultBlockState().setValue(CaveVines.BERRIES, true), 1)
        ), CaveVinesBlock.AGE, UniformInt.of(23, 25))

        val config = BlockColumnConfiguration(
            listOf( 
                BlockColumnConfiguration.Layer(
                    WeightedListInt( 
                        SimpleWeightedRandomList.builder<IntProvider>()
                            .add(UniformInt.of(0, 19), 2)
                            .add(UniformInt.of(0, 2), 3)
                            .add(UniformInt.of(0, 6), 10)
                            .build()
                    ),
                    upperStateProvider 
                ),
                BlockColumnConfiguration.Layer(
                    ConstantInt.of(1), 
                    bottomStateProvider 
                )
            ),
            Direction.DOWN, 
            BlockPredicate.ONLY_IN_AIR_PREDICATE, 
            true 
        )

        CAVE_VINE = registerConfiguredFeature("cave_vine", Feature.BLOCK_COLUMN, config)
    }

}
PlacedFeatures.kt
@OptIn(ExperimentalWorldGen::class)
@Init(stage = InitStage.POST_PACK_PRE_WORLD)
object PlacedFeatures: FeatureRegistry by ExampleAddon.registry {

    val CAVE_VINE = placedFeature("cave_vine", ConfiguredFeatures.CAVE_VINE)
        .count(188) 
        .inSquareSpread() 
        .heightRangeUniform(VerticalAnchor.BOTTOM, VerticalAnchor.absolute(256)) 
        .environmentScan( 
            Direction.UP,
            BlockPredicate.hasSturdyFace(Direction.DOWN),
            BlockPredicate.ONLY_IN_AIR_PREDICATE,
            12
        )
        .randomVerticalOffset(-1) 
        .biomeFilter() 
        .register()

}
configured_feature/cave_vine.json
{
  "type": "minecraft:block_column",
  "config": {
    "direction": "down", 
    "allowed_placement": {
      "type": "minecraft:matching_blocks",
      "blocks": "minecraft:air" 
    },
    "prioritize_tip": true, 
    "layers": [
      { 
        "height": {
          "type": "minecraft:weighted_list",
          "distribution": [
            {
              "data": {
                "type": "minecraft:uniform",
                "value": {
                  "max_inclusive": 19,
                  "min_inclusive": 0
                }
              },
              "weight": 2
            },
            {
              "data": {
                "type": "minecraft:uniform",
                "value": {
                  "max_inclusive": 2,
                  "min_inclusive": 0
                }
              },
              "weight": 3
            },
            {
              "data": {
                "type": "minecraft:uniform",
                "value": {
                  "max_inclusive": 6,
                  "min_inclusive": 0
                }
              },
              "weight": 10
            }
          ]
        },
        "provider": {
          "type": "minecraft:weighted_state_provider",
          "entries": [
            {
              "data": {
                "Name": "minecraft:cave_vines_plant",
                "Properties": {
                  "berries": "false"
                }
              },
              "weight": 4
            },
            {
              "data": {
                "Name": "minecraft:cave_vines_plant",
                "Properties": {
                  "berries": "true"
                }
              },
              "weight": 1
            }
          ]
        }
      },
      {
        "height": 1,
        "provider": {
          "type": "minecraft:randomized_int_state_provider",
          "property": "age",
          "source": {
            "type": "minecraft:weighted_state_provider",
            "entries": [
              {
                "data": {
                  "Name": "minecraft:cave_vines",
                  "Properties": {
                    "age": "0",
                    "berries": "false"
                  }
                },
                "weight": 4
              },
              {
                "data": {
                  "Name": "minecraft:cave_vines",
                  "Properties": {
                    "age": "0",
                    "berries": "true"
                  }
                },
                "weight": 1
              }
            ]
          },
          "values": {
            "type": "minecraft:uniform",
            "value": {
              "max_inclusive": 25,
              "min_inclusive": 23
            }
          }
        }
      }
    ]
  }
}
placed_feature/cave_vines.json
{
  "feature": "minecraft:cave_vine",
  "placement": [
    {
      "type": "minecraft:count",
      "count": 188 
    },
    {
      "type": "minecraft:in_square" 
    },
    {
      "type": "minecraft:height_range", 
      "height": {
        "type": "minecraft:uniform",
        "max_inclusive": {
          "absolute": 256
        },
        "min_inclusive": {
          "above_bottom": 0
        }
      }
    },
    {
      "type": "minecraft:environment_scan", 
      "allowed_search_condition": {
        "type": "minecraft:matching_blocks",
        "blocks": "minecraft:air"
      },
      "direction_of_search": "up",
      "max_steps": 12,
      "target_condition": {
        "type": "minecraft:has_sturdy_face",
        "direction": "down"
      }
    },
    {
      "type": "minecraft:random_offset", 
      "xz_spread": 0,
      "y_spread": -1
    },
    {
      "type": "minecraft:biome" 
    }
  ]
}

Result