Generating Your Tree With Data Packs! - CorgiTaco-MC/Oh-The-Trees-Youll-Grow GitHub Wiki

Please make sure to do the steps in the Making And Saving Your Tree Pieces section first.

Make your Data Pack skeleton!

  1. Make a new folder with whatever name of your choice. This will be your data pack's name.

image

  1. Create a file named pack.mcmeta in the folder you made.

image

  1. Open the pack.mcmeta file with a text editor like Notepad.

image

  1. Paste in the following:
{
    "pack": {
        "description": "Data pack details here.",
        "pack_format": 15
    }
}

image

  1. Change Data pack details here. to whatever description you'd like just keep the description within the quotes:

image

  1. Save the file and exit the text editor.

  2. Make a new folder and name it data:

image

  1. Copy the folder you saved from Making And Saving Your Tree Pieces that contains your structure pieces into the data folder:

image

This should now store your tree's NBT pieces in your data pack.

  1. Go into your <namespace> folder and create a new folder with the name worldgen:

image

  1. In the worldgen folder make another folder named configured_feature:

image

Creating your tree configured feature.

Access a json generator for the feature here

  1. In the configured_feature folder make a file named <tree_name>.json:

image

  1. Open the <tree_name>.json file in a text editor and paste the following into the file:
{
  "type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
  }
}

image

  1. Inside of the "config" {} brackets we will now begin configuring our tree for generation.

Configuring your Tree Configured Feature

  1. The first config value we will define is the path to our trunk structure piece/nbt for the "base_location" field (*this is what you pasted inside of the "Structure Name" inside of the Structure block! So it should look something like: namespace:features/trees/<tree_type>/<tree_type>_trunk1):
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1"
}
  1. The second config value we will define is the path to our canopy structure piece/nbt for the "canopy_location" field (*this is what you pasted inside of the "Structure Name" inside of the Structure block! So it should look something like: namespace:features/trees/<tree_type>/<tree_type>_canopy1):
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1"
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The third config value we will define is the block filter for which this tree is allowed to grow on. This filter works by checking all of the red wool positions defined by the trunk and ensuring all of these positions reach a block that meets the criteria of this filter. For this example we will be using Minecraft's Matching block tag filter for dirt blocks. The filter is defined by the "can_grow_on_filter" field.
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    }
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The fourth config value we will define is the block filter for which this tree's leaves are allowed to place. This filter works by checking all of the leaves defined by the trunk and canopy and checking that each leaves block meets the criteria of this filter before placing itself. For this example we will be using Minecraft's Replaceable block filter. The filter is defined by the "can_leaves_place_filter" field.
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The fifth config value we will define is a list of tree decorators. Tree decorators are a vanilla system used in vanilla trees, they're responsible for placing decorations on trees such as but not limited to: Vines, Beehives, Podzol disks(beneath large source trees). Mods may add additional decorators and we may be able to use these! For this example we will be using Minecraft's beehive, vine, and podzol disk tree decorators. The list of decorators is defined by the "decorators" field and it must accept an array.
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ]
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The sixth config value we will define is our tree's height. We use Mojang's provided int providers to let us obtain a range of numbers or a single constant number. In this example we will use Mojang's Uniform Int Provider which lets us get a random number between a min and max range. This field is defined by "height".
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ],
    "height": {
      "type": "minecraft:uniform",
      "value": {
        "max_inclusive": 10,
        "min_inclusive": 5
      }
    }
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The seventh config value we will define is our tree's leaves provider. We use Mojang's provided block state providers to let us obtain block state(s). In this example we will use Mojang's Simple StateProvider which lets us get a constant block state. This field is defined by "leaves_provider". Do not worry about defining a leave's distance and persistence, the code internally will automatically set the distance and persistence state properties.
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ],
    "height": {
      "type": "minecraft:uniform",
      "value": {
        "max_inclusive": 10,
        "min_inclusive": 5
      }
    },
    "leaves_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_leaves",
        "Properties": {
          "distance": "7",
          "persistent": "false",
          "waterlogged": "false"
        }
      }
    }
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The eight config value we will define is our tree's leaves target. This is a list of the type of leave blocks we used in our structure/NBT that we want to target to replace with our "leaves_provider". If you used oak leaves in your structure/NBT set oak leaves as the target. If you used oak, azalea, and jungle leaves in your structure/NBT set oak, azalea, and jungle leaves as the leaves target. Applied to both canopy and trunk pieces. This field is defined as "leaves_target".
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ],
    "height": {
      "type": "minecraft:uniform",
      "value": {
        "max_inclusive": 10,
        "min_inclusive": 5
      }
    },
    "leaves_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_leaves",
        "Properties": {
          "distance": "7",
          "persistent": "false",
          "waterlogged": "false"
        }
      }
    },
    "leaves_target": [
      "minecraft:oak_leaves"
    ]
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The ninth config value we will define is our tree's log provider. We use Mojang's provided block state providers to let us obtain block state(s). In this example, we will use Mojang's Simple StateProvider which lets us get a constant block state. This field is defined by "log_provider". Do not worry about defining a log's axis, the code internally will automatically set the log's axis from the log in the NBT.
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ],
    "height": {
      "type": "minecraft:uniform",
      "value": {
        "max_inclusive": 10,
        "min_inclusive": 5
      }
    },
    "leaves_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_leaves",
        "Properties": {
          "distance": "7",
          "persistent": "false",
          "waterlogged": "false"
        }
      }
    },
    "leaves_target": [
      "minecraft:oak_leaves"
    ]
    "log_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_log",
        "Properties": {
          "axis": "y"
        }
      }
    }
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The tenth config value we will define is our tree's log target. This is a list of the type of log blocks we used in our structure/NBT that we want to target to replace with our "log_provider". If you used oak logs in your structure/NBT set oak leaves as the target. If you used oak, azalea, and jungle logs in your structure/NBT set oak, azalea, and jungle leaves as the log target. Applied to both canopy and trunk pieces. This field is defined as "log_target".
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ],
    "height": {
      "type": "minecraft:uniform",
      "value": {
        "max_inclusive": 10,
        "min_inclusive": 5
      }
    },
    "leaves_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_leaves",
        "Properties": {
          "distance": "7",
          "persistent": "false",
          "waterlogged": "false"
        }
      }
    },
    "leaves_target": [
      "minecraft:oak_leaves"
    ],
    "log_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_log",
        "Properties": {
          "axis": "y"
        }
      }
    },
    "log_target": [
      "minecraft:oak_log"
    ]
}

Make sure to add commas after each field definition if it has a field defined after it!

  1. The eleventh and final config value we will define is what additional blocks to place from our structure/NBT. This is a list of the type of blocks we used in our structure/NBT that we want to place in the world alongside our tree. If you used glowstone in your structure/NBT add glowstone to the list. If you used netherite blocks, diamond blocks, and emerald blocks in your structure/NBT add netherite blocks, diamond blocks, and emerald blocks to the list. Applied to both canopy and trunk pieces. This field is defined as "place_from_nbt".
"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ],
    "height": {
      "type": "minecraft:uniform",
      "value": {
        "max_inclusive": 10,
        "min_inclusive": 5
      }
    },
    "leaves_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_leaves",
        "Properties": {
          "distance": "7",
          "persistent": "false",
          "waterlogged": "false"
        }
      }
    },
    "leaves_target": [
      "minecraft:oak_leaves"
    ],
    "log_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_log",
        "Properties": {
          "axis": "y"
        }
      }
    },
    "log_target": [
      "minecraft:oak_log"
    ],
    "place_from_nbt": []
}

Make sure to add commas after each field definition if it has a field defined after it!

Our final file should look like:

"type": "ohthetreesyoullgrow:tree_from_nbt_v1",
  "config": {
    "base_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_trunk1",
    "canopy_location": "ohthetreesyoullgrow:features/trees/testv1/test_tree_canopy1",
    "can_grow_on_filter": {
      "type": "minecraft:matching_block_tag",
      "tag": "minecraft:dirt"
    },
    "can_leaves_place_filter": {
      "type": "minecraft:replaceable"
    }, 
    "decorators": [
      {
        "type": "minecraft:alter_ground",
        "provider": {
          "type": "minecraft:simple_state_provider",
          "state": {
            "Name": "minecraft:moss_block"
          }
        }
      },
      {
        "type": "minecraft:leave_vine",
        "probability": 0.5
      },
      {
        "type": "minecraft:beehive",
        "probability": 0.2
      }
    ],
    "height": {
      "type": "minecraft:uniform",
      "value": {
        "max_inclusive": 10,
        "min_inclusive": 5
      }
    },
    "leaves_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_leaves",
        "Properties": {
          "distance": "7",
          "persistent": "false",
          "waterlogged": "false"
        }
      }
    },
    "leaves_target": [
      "minecraft:oak_leaves"
    ],
    "log_provider": {
      "type": "minecraft:simple_state_provider",
      "state": {
        "Name": "minecraft:acacia_log",
        "Properties": {
          "axis": "y"
        }
      }
    },
    "log_target": [
      "minecraft:oak_log"
    ],
    "place_from_nbt": []
}

Creating your tree-placed feature

  1. Head back to the worldgen folder in your datapack.

  2. Create a new folder named placed_feature:

image

  1. In the placed_feature folder make a file named <tree_name>.json: image

  2. Use the Minecraft Wiki's article on Placed Features and/or Misode's Placed Feature Generator to define your placement for whichever conditions you'd like.

Spawning your tree-placed feature.

There are various ways to spawn your feature whether replacing an existing feature, using a Mod Loader's feature API, or adding them to your biome. I highly suggest googling for your use case. I will expand on this later on but at the moment I do not have the time to do so.

⚠️ **GitHub.com Fallback** ⚠️