添加了部分来自于BedrockWiki的文章!

This commit is contained in:
boybook
2025-03-19 22:17:04 +08:00
parent 41635cf9bb
commit c25ebf2767
558 changed files with 96136 additions and 24 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,364 @@
---
title: Custom Fluids
category: Vanilla Re-Creations
tags:
- experimental
- intermediate
- scripting
mentions:
- Provedule
- JaylyDev
- QuazChick
---
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
This tutorial assumes an advanced understanding of blocks and the execute command.
Check out the [blocks guide](/blocks/blocks-intro) before starting.
:::
::: warning EXPERIMENTAL
Requires `Holiday Creator Features` for use of block tag Molang queries and to trigger block events.
Requires `Beta APIs` to use [@minecraft/server](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/minecraft-server) module version `1.6.0-beta`.
:::
Creating fluids that are identical to vanilla fluids is not currently possible, but you can make something similar! This template/tutorial is designed to assist you in creating a custom "semi-fluid".
## Flow Logic
- The fluid block has states defining whether it is a source and its depth.
- If there is air beneath fluid blocks, it will be converted into falling fluid.
- Fluids with a depth above `1` will spread horizontally with decreasing depths.
- This will not occur if there is falling fluid below.
- Flowing fluid block must have another fluid block adjacent to survive.
- Source blocks do not need to have other fluid blocks surrounding themselves.
**This implementation does not include face culling due to its current complexity.**
<WikiImage
src="/assets/images/blocks/custom-fluids/fluid_display.png"
alt=""
pixelated="true"
width=608
/>
## Source Fluid Block
Below is the code for a custom fluid. Copy and quick replace `custom_fluid` with your fluid's name. When the source block detects air in its surroundings, it replaces it with the outer fluid blocks. If the source block detects air beneath it, it will also place a falling fluid block underneath.
<BButton
link="https://github.com/Bedrock-OSS/wiki-addon/blob/main/ma-custom_fluids/rp/models/blocks/fluid.geo.json"
color=blue
>Download Custom Fluid Geometry</BButton>
<Spoiler title="Custom Fluid Block JSON">
<CodeHeader>BP/blocks/custom_fluid.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_fluid",
"menu_category": {
"category": "none"
},
"states": {
"wiki:source": [true, false],
// Depth of fluid - default to 4
"wiki:depth": [4, 5, 3, 2, 1]
}
},
"components": {
"minecraft:light_dampening": 0,
"minecraft:collision_box": false,
"minecraft:selection_box": false,
"minecraft:destructible_by_explosion": false,
// Trigger fluid spread
"minecraft:queued_ticking": {
"looping": true,
"interval_range": [20, 20], // Fluid speed in ticks
"on_tick": {
"event": "wiki:flow"
}
},
"minecraft:material_instances": {
"*": {
"texture": "custom_fluid", // Shortname defined in `RP/textures/terrain_texture.json`
"render_method": "blend",
"ambient_occlusion": false,
"face_dimming": false
}
},
"minecraft:loot": "loot_tables/empty.json",
"tag:custom_fluid": {}
},
"events": {
"wiki:flow": {
"sequence": [
// Dry out
{
"condition": "!q.block_state('wiki:source') && ((q.block_state('wiki:depth') == 5 && !q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')) || (q.block_state('wiki:depth') == 1 && !(q.block_neighbor_has_any_tag(1, 0, 0, 'custom_fluid_2') || q.block_neighbor_has_any_tag(-1, 0, 0, 'custom_fluid_2') || q.block_neighbor_has_any_tag(0, 0, 1, 'custom_fluid_2') || q.block_neighbor_has_any_tag(0, 0, -1, 'custom_fluid_2')) || q.block_state('wiki:depth') == 2 && !(q.block_neighbor_has_any_tag(1, 0, 0, 'custom_fluid_3') || q.block_neighbor_has_any_tag(-1, 0, 0, 'custom_fluid_3') || q.block_neighbor_has_any_tag(0, 0, 1, 'custom_fluid_3') || q.block_neighbor_has_any_tag(0, 0, -1, 'custom_fluid_3'))) || (q.block_state('wiki:depth') == 3 && !(q.block_neighbor_has_any_tag(1, 0, 0, 'custom_fluid_4', 'custom_fluid_5') || q.block_neighbor_has_any_tag(-1, 0, 0, 'custom_fluid_4', 'custom_fluid_5') || q.block_neighbor_has_any_tag(0, 0, 1, 'custom_fluid_4', 'custom_fluid_5') || q.block_neighbor_has_any_tag(0, 0, -1, 'custom_fluid_4', 'custom_fluid_5'))))",
"die": {}
},
// Spread
{
"condition": "q.block_state('wiki:depth') == 4",
"run_command": {
"command": [
"execute if block ~~~1 air run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute if block ~~~-1 air run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute if block ~1~~ air run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute if block ~-1~~ air run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]"
]
}
},
{
"condition": "q.block_state('wiki:source') && q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')",
"set_block_state": {
"wiki:depth": 5
}
},
{
"condition": "q.block_state('wiki:source') && !q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')",
"set_block_state": {
"wiki:depth": 4
}
},
{
"condition": "q.block_state('wiki:depth') == 3",
"run_command": {
"command": [
"execute if block ~~~1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]",
"execute if block ~~~-1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]",
"execute if block ~1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]",
"execute if block ~-1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]"
]
}
},
{
"condition": "q.block_state('wiki:depth') == 2",
"run_command": {
"command": [
"execute if block ~~~1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]",
"execute if block ~~~-1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]",
"execute if block ~1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]",
"execute if block ~-1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]"
]
}
},
{
"condition": "q.block_state('wiki:depth') == 5 && q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')",
"run_command": {
"command": [
"execute if block ~~-1~ wiki:custom_fluid [\"wiki:depth\"=3] run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]",
"execute if block ~~-1~ wiki:custom_fluid [\"wiki:depth\"=2] run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]",
"execute if block ~~-1~ wiki:custom_fluid [\"wiki:depth\"=1] run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~1~~ air run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~~~1 air run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~-1~~ air run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~~~-1 air run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]"
]
}
},
// Fall
{
"run_command": {
"command": "execute if block ~~-1~ air run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]"
}
},
{
"condition": "q.block_neighbor_has_any_tag(0, -1, 0, 'flowing_custom_fluid')",
"run_command": {
"command": "setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]"
}
}
]
},
"wiki:pick_up": {
"die": {},
"decrement_stack": {},
"run_command": {
"command": "give @s lava_bucket",
"target": "other"
}
}
},
"permutations": [
{
"condition": "q.block_state('wiki:source')",
"components": {
// Enables the block to be picked up by an item of choice
"minecraft:selection_box": {
"origin": [-7.5, 0.5, -7.5],
"size": [15, 13, 15]
},
"tag:custom_fluid_source": {}
}
},
{
"condition": "!q.block_state('wiki:source')",
"components": {
"tag:flowing_custom_fluid": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 5",
"components": {
"minecraft:geometry": "geometry.fluid.5",
"tag:custom_fluid_5": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 4",
"components": {
"minecraft:geometry": "geometry.fluid.4",
"tag:custom_fluid_4": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 3",
"components": {
"minecraft:geometry": "geometry.fluid.3",
"tag:custom_fluid_3": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 2",
"components": {
"minecraft:geometry": "geometry.fluid.2",
"tag:custom_fluid_2": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 1",
"components": {
"minecraft:geometry": "geometry.fluid.1",
"tag:custom_fluid_1": {}
}
}
]
}
}
```
</Spoiler>
## Fluid Bucket
To place your custom fluid you need a custom bucket item. Below is the JSON for the custom bucket. Replace any instance of `custom_fluid` with your fluid's name.
<Spoiler title="Custom Bucket Item JSON">
<CodeHeader>BP/items/custom_fluid_bucket.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:item": {
"description": {
"identifier": "wiki:custom_fluid_bucket",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:max_stack_size": 1,
"minecraft:icon": {
"texture": "custom_fluid_bucket" // Shortname defined in `RP/textures/item_texture.json`
},
"minecraft:block_placer": {
"block": "wiki:custom_fluid"
}
}
}
}
```
</Spoiler>
## Scripts
The fluids use a script to add the ability for the player to float/sink in the fluid. The script also adds fog. To add your fluid to the script, put the ID of your new fluids in the `fluids` string array.
<CodeHeader>BP/manifest.json</CodeHeader>
```json
{
"modules": [
...
{
"type": "script",
"language": "javascript",
"entry": "fluids.js",
"uuid": ...,
"version": [1, 0, 0]
}
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "1.6.0-beta"
}
]
}
```
<Spoiler title="Fluid Movement & Fog Script">
<CodeHeader>BP/scripts/fluids.js</CodeHeader>
```javascript
import { system, world } from "@minecraft/server";
const fluids = ["wiki:custom_fluid"];
system.runInterval(() => {
const players = world.getPlayers();
for (const player of players) {
// Fluid effects
if (
fluids.includes(world.getDimension(player.dimension.id).getBlock({ ...player.location, y: player.location.y + 1 }).typeId) ||
fluids.includes(world.getDimension(player.dimension.id).getBlock(player.location).typeId)
) {
player.addEffect("slowness", 3, { amplifier: 2, showParticles: false });
player.addEffect("slow_falling", 4, { showParticles: false });
if (player.isJumping) {
player.addEffect("levitation", 3, { amplifier: 2, showParticles: false });
}
}
// Fluid fog
if (fluids.includes(world.getDimension(player.dimension.id).getBlock({ ...player.location, y: player.location.y + 1.63 }).typeId)) {
player.runCommand("fog @s push wiki:custom_fluid_fog fluid_fog");
} else {
player.runCommand("fog @s remove fluid_fog");
}
}
});
```
</Spoiler>
## Result
By the end your BP folder should look like this:
<FolderView
:paths="[
'BP/blocks/custom_fluid.json',
'BP/items/custom_fluid_bucket.json',
'BP/scripts/fluids.js',
'RP/fogs/custom_fluid.json'
]"
></FolderView>
## Download Example Pack
If anything goes wrong, or if you require all of the template files, they are available for download here. The pack includes everything necessary for a functional fluid.
<BButton
link="https://github.com/Bedrock-OSS/wiki-addon/releases/download/download/custom_fluids.mcaddon"
color=blue
>Download MCADDON</BButton>

View File

@@ -0,0 +1,661 @@
---
title: Custom Glass
category: Vanilla Re-Creations
tags:
- experimental
- expert
mentions:
- Eko-byte
- QuazChick
---
Making glass blocks may seem like a simple task, however it comes with many drawbacks as you will find, this tutorial aims to help you achieve a vanilla like glass block.
By the end you should be able to create something like this!
![Glass Results](/assets/images/blocks/glass-block/glass_showcase.png)
## Basic Glass
::: tip FORMAT VERSION `1.20.30`
This example requires basic knowledge of blocks to understand.
Check out the [blocks guide](/blocks/blocks-intro) before starting.
:::
This will create a custom glass block which appears the same as vanilla glass blocks!
<CodeHeader>BP/blocks/custom_glass.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_glass",
"menu_category": {
"category": "construction",
"group": "itemGroup.name.glass"
}
},
"components": {
"minecraft:light_dampening": 0,
"minecraft:material_instances": {
"*": {
"render_method": "blend" // Allows translucency
}
}
}
}
}
```
<CodeHeader>RP/blocks.json</CodeHeader>
```json
{
"wiki:custom_glass": {
"textures": "custom_glass", // Shortname defined in `RP/textures/terrain_texture.json`
"sound": "glass"
}
}
```
## Vertically-Connecting Glass
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
This example requires advanced knowledge of blocks and Molang to understand.
Check out the [blocks guide](/blocks/blocks-intro), [block states](/blocks/block-states) and [Molang](/concepts/molang) before starting.
:::
::: warning EXPERIMENTAL
Requires `Holiday Creator Features` for use of `minecraft:unit_cube` and to trigger events.
:::
<Spoiler title="Vertically-Connecting Glass JSON">
<CodeHeader>BP/blocks/custom_vertical_connecting_glass.json</CodeHeader>
```json
// Add a "nothing" texture in terrain_texture, and make it have a transparent file
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_vertical_connecting_glass",
"menu_category": {
"category": "construction",
"group": "itemGroup.name.glass"
},
"states": {
// States needed for connected textures, also controls up and down culling
"wiki:connection": [0, 1, 2, 3],
// States to cull faces depending on surrounding blocks
"wiki:cull_north": [false, true],
"wiki:cull_south": [false, true],
"wiki:cull_east": [false, true],
"wiki:cull_west": [false, true]
}
},
"components": {
// Basic glass components
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1
},
"minecraft:queued_ticking": {
"looping": true,
"interval_range": [0, 0],
"on_tick": {
"event": "wiki:update"
}
},
"minecraft:unit_cube": {},
"minecraft:light_dampening": 0,
// Tags used to give connected textures, and remove culling
"tag:custom_vertical_connecting_glass": {},
"tag:glass": {}
},
"permutations": [
// These permutations control what textures are displayed at different situations
// They also use tags to determine what state they are in, (top texture then top tag)
{
"condition": "q.block_state('wiki:connection') == 0 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
"components": {
"tag:default": {},
"minecraft:material_instances": {
"*": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
}
}
}
},
{
"condition": "q.block_state('wiki:connection') == 1 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
"components": {
"tag:top": {},
"minecraft:material_instances": {
"*": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_top"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:connection') == 2 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
"components": {
"tag:bottom": {},
"minecraft:material_instances": {
"*": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_bottom"
},
"up": {
"render_method": "blend",
"texture": "nothing"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
}
}
}
},
{
"condition": "q.block_state('wiki:connection') == 3 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
"components": {
"tag:middle": {},
"minecraft:material_instances": {
"*": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_middle"
},
"up": {
"render_method": "blend",
"texture": "nothing"
},
"down": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 0",
"components": {
"tag:default": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass",
"render_method": "blend"
},
"north": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 0",
"components": {
"tag:default": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass",
"render_method": "blend"
},
"south": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 0",
"components": {
"tag:default": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass",
"render_method": "blend"
},
"east": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 0",
"components": {
"tag:default": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass",
"render_method": "blend"
},
"west": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 1",
"components": {
"tag:top": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_top",
"render_method": "blend"
},
"north": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 1",
"components": {
"tag:top": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_top",
"render_method": "blend"
},
"south": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 1",
"components": {
"tag:top": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_top",
"render_method": "blend"
},
"east": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
//in this situation if there is a block to the west and it is the upper connected texture then it shall have the west side invisible and the sides be the upper connected part
{
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 1",
"components": {
"tag:top": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_top",
"render_method": "blend"
},
"west": {
"texture": "nothing",
"render_method": "blend"
},
"up": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"down": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 2",
"components": {
"tag:bottom": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_bottom",
"render_method": "blend"
},
"north": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 2",
"components": {
"tag:bottom": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_bottom",
"render_method": "blend"
},
"south": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 2",
"components": {
"tag:bottom": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_bottom",
"render_method": "blend"
},
"east": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 2",
"components": {
"tag:bottom": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_bottom",
"render_method": "blend"
},
"west": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "custom_vertical_connecting_glass_up"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 3",
"components": {
"tag:middle": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_middle",
"render_method": "blend"
},
"north": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "nothing"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 3",
"components": {
"tag:middle": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_middle",
"render_method": "blend"
},
"south": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "nothing"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 3",
"components": {
"tag:middle": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_middle",
"render_method": "blend"
},
"east": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "nothing"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
},
{
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 3",
"components": {
"tag:middle": {},
"minecraft:material_instances": {
"*": {
"texture": "custom_vertical_connecting_glass_middle",
"render_method": "blend"
},
"west": {
"texture": "nothing",
"render_method": "blend"
},
"down": {
"render_method": "blend",
"texture": "nothing"
},
"up": {
"render_method": "blend",
"texture": "nothing"
}
}
}
}
],
"events": {
"wiki:update": {
"sequence": [
// Set the block to have no culling
{
"condition": "q.block_neighbor_has_any_tag(0,0,-1,'custom_vertical_connecting_glass')",
"set_block_state": {
"wiki:cull_north": "q.block_neighbor_has_any_tag(0,0,-1,'custom_vertical_connecting_glass')",
"wiki:cull_south": "q.block_neighbor_has_any_tag(0,0,1,'custom_vertical_connecting_glass')",
"wiki:cull_west": "q.block_neighbor_has_any_tag(-1,0,0,'custom_vertical_connecting_glass')",
"wiki:cull_east": "q.block_neighbor_has_any_tag(1,0,0,'custom_vertical_connecting_glass')"
}
},
// Control the custom texture state
{
"condition": "q.block_neighbor_has_any_tag(0,-1,0,'default')",
"set_block_state": {
"wiki:connection": 1
}
},
{
"condition": "q.block_neighbor_has_any_tag(0,1,0,'top') && !q.block_neighbor_has_any_tag(0,-1,0,'middle')",
"set_block_state": {
"wiki:connection": 2
}
},
{
"condition": "q.block_neighbor_has_any_tag(0,1,0,'top') && q.block_neighbor_has_any_tag(0,-1,0,'middle')",
"set_block_state": {
"wiki:connection": 3
}
},
{
"condition": "q.block_neighbor_has_any_tag(0,-1,0,'top')",
"set_block_state": {
"wiki:connection": 1
}
},
{
"condition": "q.block_neighbor_has_any_tag(0,-1,0,'bottom') && (q.block_neighbor_has_any_tag(0,1,0,'top') || q.block_neighbor_has_any_tag(0,1,0,'middle'))",
"set_block_state": {
"wiki:connection": 3
}
},
{
"condition": "!q.block_neighbor_has_any_tag(0,1,0,'top', 'default', 'middle', 'bottom') && q.block_neighbor_has_any_tag(0,-1,0,'middle', 'bottom')",
"set_block_state": {
"wiki:connection": 1
}
},
{
"condition": "!q.block_neighbor_has_any_tag(0,1,0,'top', 'default', 'middle', 'bottom') && !q.block_neighbor_has_any_tag(0,-1,0,'middle', 'bottom', 'top', 'default')",
"set_block_state": {
"wiki:connection": 0
}
},
{
"condition": "q.block_neighbor_has_any_tag(0,1,0,'top', 'middle', 'bottom') && !q.block_neighbor_has_any_tag(0,-1,0,'middle', 'bottom', 'top', 'default')",
"set_block_state": {
"wiki:connection": 2
}
},
{
"condition": "q.block_neighbor_has_any_tag(0,1,0,'default') && q.block_neighbor_has_any_tag(0,-1,0,'default')",
"set_block_state": {
"wiki:connection": 3
}
}
]
}
}
}
}
```
</Spoiler>

View File

@@ -0,0 +1,289 @@
---
title: Custom Glazed Terracotta
category: Vanilla Re-Creations
tags:
- easy
mentions:
- Kaioga5
---
::: tip FORMAT & MIN ENGINE VERSION `1.20.40`
This tutorial assumes a basic understanding of blocks.
Check out the [blocks guide](/blocks/blocks-intro) before starting.
:::
## Introduction
Glazed Terracotta has its own rotation mechanism, enabling players to craft aesthetically pleasing patterns for walls, floors, and ceilings. This guide will instruct you on creating your own blocks resembling glazed terracotta.
## Custom Glazed Terracotta
This will create a vanilla-like custom glazed terracotta.
<CodeHeader>BP/blocks/custom_glazed_terracotta.json</CodeHeader>
```json
{
"format_version": "1.20.40",
"minecraft:block": {
"description": {
"identifier": "wiki:glazed_terracotta_template",
"menu_category": {
"category": "construction",
"group": "itemGroup.name.glazedTerracotta"
},
"traits": {
"minecraft:placement_direction": {
"enabled_states": [
"minecraft:cardinal_direction"
]
}
}
},
"permutations": [
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'north'",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] },
"minecraft:geometry": {
"identifier": "geometry.glazed_terracotta",
"bone_visibility": {
"bottom_1": false,
"bottom_2": false,
"bottom_3": false,
"bottom_4": true
}
}
}
},
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'west'",
"components": {
"minecraft:transformation": { "rotation": [0, 90, 0] },
"minecraft:geometry": {
"identifier": "geometry.glazed_terracotta",
"bone_visibility": {
"bottom_1": false,
"bottom_2": false,
"bottom_3": true,
"bottom_4": false
}
}
}
},
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'south'",
"components": {
"minecraft:transformation": { "rotation": [0, 180, 0] },
"minecraft:geometry": {
"identifier": "geometry.glazed_terracotta",
"bone_visibility": {
"bottom_1": false,
"bottom_2": true,
"bottom_3": false,
"bottom_4": false
}
}
}
},
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'east'",
"components": {
"minecraft:transformation": { "rotation": [0, -90, 0] },
"minecraft:geometry": {
"identifier": "geometry.glazed_terracotta",
"bone_visibility": {
"bottom_1": true,
"bottom_2": false,
"bottom_3": false,
"bottom_4": false
}
}
}
}
],
"components": {
"minecraft:geometry": {
"identifier": "geometry.glazed_terracotta"
},
"minecraft:material_instances": {
"*": {
"texture": "purple_glazed_terracotta",
"render_method": "opaque"
}
}
}
}
}
```
## Geometry
Vanilla glazed terracotta rotates certain faces of the block with some specific values, which is what gives the block it's magic. Use the following geometry to replicate that behavior.
<Spoiler title="Geometry JSON">
<CodeHeader>RP/models/blocks/glazed_terracotta.geo.json</CodeHeader>
```json
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.glazed_terracotta",
"texture_width": 16,
"texture_height": 16,
"visible_bounds_width": 4,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
},
"bones": [
{
"name": "glazed_terracotta",
"pivot": [0, 0, 0]
},
{
"name": "top",
"parent": "glazed_terracotta",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 16, 16],
"uv": {
"up": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
},
{
"name": "north",
"parent": "glazed_terracotta",
"pivot": [0, 8, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 16, 0],
"pivot": [0, 8, 0],
"rotation": [180, 0, 90],
"uv": {
"north": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
},
{
"name": "south",
"parent": "glazed_terracotta",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [0, -8, 8],
"size": [16, 16, 0],
"pivot": [0, 0, 0],
"rotation": [180, 0, 270],
"uv": {
"south": {"uv": [0, 0], "uv_size": [16, 16]}
}
}
]
},
{
"name": "east",
"parent": "glazed_terracotta",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, -16, -8],
"size": [0, 16, 16],
"pivot": [0, 0, 0],
"rotation": [0, 0, -180],
"uv": {
"east": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
},
{
"name": "west",
"parent": "glazed_terracotta",
"pivot": [-16, 0, 0],
"cubes": [
{
"origin": [-24, 0, -8],
"size": [0, 16, 16],
"pivot": [-16, 0, 0],
"rotation": [0, 180, 0],
"uv": {
"west": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
},
{
"name": "bottom",
"parent": "glazed_terracotta",
"pivot": [0, 0, 0]
},
{
"name": "bottom_1",
"parent": "bottom",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 0, 16],
"uv": {
"down": {"uv": [0, 0], "uv_size": [16, 16]}
}
}
]
},
{
"name": "bottom_2",
"parent": "bottom",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 0, 16],
"uv": {
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
},
{
"name": "bottom_3",
"parent": "bottom",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 0, 16],
"uv": {
"down": {"uv": [0, 0], "uv_size": [16, 16]}
}
}
]
},
{
"name": "bottom_4",
"parent": "bottom",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 0, 16],
"uv": {
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
}
]
}
]
}
```
</Spoiler>

View File

@@ -0,0 +1,201 @@
---
title: Custom Slabs
category: Vanilla Re-Creations
tags:
- experimental
- easy
mentions:
- Kaioga5
- QuazChick
---
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
This tutorial assumes a basic understanding of blocks.
Check out the [blocks guide](/blocks/blocks-intro) before starting.
:::
::: warning EXPERIMENTAL
Requires `Holiday Creator Features` to trigger block events and for use of the `minecraft:unit_cube` component.
:::
## Introduction
Making custom slabs is a simple task, but if you find any drawbacks during recreating slabs, this tutorial will help you with it, and you'll be provided with a template for you to use.
Issues:
- Your custom slab will appear vertically centred when carried.
- Your custom slab may appear full-sized in item form (on the ground, in item frames, in hand)
## Custom Slab
This will create a vanilla-like custom slab.
<CodeHeader>BP/blocks/custom_slab.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_slab",
"menu_category": {
"category": "construction",
"group": "itemGroup.name.slab"
},
"traits": {
"minecraft:placement_position": {
"enabled_states": ["minecraft:vertical_half"]
}
},
"states": {
"wiki:double": [false, true]
}
},
"permutations": [
// Bottom Slab
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && !q.block_state('wiki:double')",
"components": {
"minecraft:collision_box": {
"origin": [-8, 0, -8],
"size": [16, 8, 16]
},
"minecraft:selection_box": {
"origin": [-8, 0, -8],
"size": [16, 8, 16]
},
"minecraft:on_interact": {
"event": "wiki:form_double",
"condition": "q.block_face == 1.0 && q.is_item_name_any('slot.weapon.mainhand', 'wiki:custom_slab')"
}
}
},
// Top Slab
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && !q.block_state('wiki:double')",
"components": {
"minecraft:collision_box": {
"origin": [-8, 8, -8],
"size": [16, 8, 16]
},
"minecraft:selection_box": {
"origin": [-8, 8, -8],
"size": [16, 8, 16]
},
"minecraft:on_interact": {
"event": "wiki:form_double",
"condition": "q.block_face == 0.0 && q.is_item_name_any('slot.weapon.mainhand', 'wiki:custom_slab')"
}
}
},
// Double Slab
{
"condition": "q.block_state('wiki:double')",
"components": {
"minecraft:unit_cube": {},
"minecraft:on_player_destroyed": {
"event": "wiki:destroy_double"
}
}
}
],
"components": {
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 7
},
"minecraft:destructible_by_explosion": {
"explosion_resistance": 6
},
"minecraft:geometry": {
"identifier": "geometry.slab",
"bone_visibility": {
"bottom_slab": "q.block_state('minecraft:vertical_half') == 'bottom'",
"top_slab": "q.block_state('minecraft:vertical_half') == 'top'"
}
},
"minecraft:material_instances": {
"*": {
"texture": "stone"
}
}
},
"events": {
"wiki:form_double": {
"set_block_state": {
"wiki:double": true
},
"run_command": {
"command": "playsound use.stone @a ~~~ 1 0.8"
},
"decrement_stack": {}
},
"wiki:destroy_double": {
"spawn_loot": {} // Spawns the block's default loot
}
}
}
}
```
## Geometry
This will be the geometry used for your custom slabs.
<Spoiler title="Geometry JSON">
<CodeHeader>RP/models/blocks/slab.geo.json</CodeHeader>
```json
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.slab",
"texture_width": 16,
"texture_height": 16,
"visible_bounds_width": 2,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "top_slab",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 8, -8],
"size": [16, 8, 16],
"uv": {
"north": {"uv": [0, 0], "uv_size": [16, 8]},
"east": {"uv": [0, 0], "uv_size": [16, 8]},
"south": {"uv": [0, 0], "uv_size": [16, 8]},
"west": {"uv": [0, 0], "uv_size": [16, 8]},
"up": {"uv": [16, 16], "uv_size": [-16, -16]},
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
},
{
"name": "bottom_slab",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 8, 16],
"uv": {
"north": {"uv": [0, 8], "uv_size": [16, 8]},
"east": {"uv": [0, 8], "uv_size": [16, 8]},
"south": {"uv": [0, 8], "uv_size": [16, 8]},
"west": {"uv": [0, 8], "uv_size": [16, 8]},
"up": {"uv": [16, 16], "uv_size": [-16, -16]},
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
}
}
]
}
]
}
]
}
```
</Spoiler>

View File

@@ -0,0 +1,254 @@
---
title: Custom Trapdoors
category: Vanilla Re-Creations
tags:
- experimental
- intermediate
mentions:
- Kaioga5
- QuazChick
---
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
This tutorial assumes a good understanding of blocks.
Check out the [blocks guide](/blocks/blocks-intro) before starting.
:::
::: warning EXPERIMENTAL
Requires `Holiday Creator Features` to trigger block events.
:::
## Introduction
Making custom trapdoors is an often difficult task to do, but after reading this tutorial you'll understand how they work in case you find any drawbacks during recreating them, and you'll be provided with a template for you to use.
## Custom Trapdoor
This will create a vanilla-like custom trapdoor.
<CodeHeader>BP/blocks/custom_trapdoor.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_trapdoor",
"menu_category": {
"category": "construction",
"group": "itemGroup.name.trapdoor"
},
"traits": {
"minecraft:placement_position": {
"enabled_states": ["minecraft:vertical_half"]
},
"minecraft:placement_direction": {
"enabled_states": ["minecraft:cardinal_direction"]
}
},
"states": {
"wiki:open": [false, true]
}
},
"permutations": [
// Top Closed
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'north' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 180] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'south' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [180, 0, 0] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'east' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [180, -270, 0] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'west' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [180, 270, 0] }
}
},
// Top Open
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'north' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [-270, 0, 0] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'south' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [270, 0, -180] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'east' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [0, 270, 90] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'west' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": {
"rotation": [180, -270, -270]
}
}
},
// Bottom Closed
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'north' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'south' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [0, 180, 0] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'east' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [0, 270, 0] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'west' && !q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [0, -270, 0] }
}
},
// Bottom Open
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'north' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [90, 0, 180] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'south' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [270, 0, 0] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'east' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [0, -270, 90] }
}
},
{
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'west' && q.block_state('wiki:open')",
"components": {
"minecraft:transformation": { "rotation": [180, 270, -270] }
}
}
],
"components": {
"minecraft:collision_box": {
"origin": [-8, 0, -8],
"size": [16, 3, 16]
},
"minecraft:selection_box": {
"origin": [-8, 0, -8],
"size": [16, 3, 16]
},
"minecraft:geometry": "geometry.trapdoor",
"minecraft:material_instances": {
"*": {
"texture": "spruce_trapdoor",
"render_method": "alpha_test"
}
},
"minecraft:on_interact": {
"event": "wiki:toggle"
}
},
"events": {
"wiki:toggle": {
"sequence": [
{
"set_block_state": {
"wiki:open": "!q.block_state('wiki:open')"
}
},
{
"condition": "q.block_state('wiki:open')",
"run_command": {
"command": "playsound close.wooden_trapdoor @a ~~~ 0.9 0.9"
}
},
{
"condition": "!q.block_state('wiki:open')",
"run_command": {
"command": "playsound open.wooden_trapdoor @a ~~~ 0.9 0.9"
}
}
]
}
}
}
}
```
## Geometry
This will be the geometry used for your custom trapdoors.
<Spoiler title="Geometry JSON">
<CodeHeader>RP/models/blocks/trapdoor.geo.json</CodeHeader>
```json
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.trapdoor",
"texture_width": 16,
"texture_height": 16,
"visible_bounds_width": 2,
"visible_bounds_height": 1.5,
"visible_bounds_offset": [0, 0.25, 0]
},
"bones": [
{
"name": "trapdoor",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, -8],
"size": [16, 3, 16],
"uv": {
"north": {"uv": [16, 3], "uv_size": [-16, -3]},
"east": {"uv": [16, 3], "uv_size": [-16, -3]},
"south": {"uv": [16, 3], "uv_size": [-16, -3]},
"west": {"uv": [16, 3], "uv_size": [-16, -3]},
"up": {"uv": [16, 16], "uv_size": [-16, -16]},
"down": {"uv": [0, 0], "uv_size": [16, 16]}
}
}
]
}
]
}
]
}
```
</Spoiler>
:::tip
Vanilla trapdoors have a few issues in the direction of the texture in certain faces and having a height of 2.95 when it should be 3. This block template and geometry fixes both of those issues.
:::

View File

@@ -0,0 +1,994 @@
---
title: Custom Trees
category: Vanilla Re-Creations
tags:
- experimental
mentions:
- MedicalJewel105
- TheItsNameless
- QuazChick
---
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
This tutorial assumes an advanced understanding of blocks.
Check out the [blocks guide](/blocks/blocks-intro) before starting.
:::
::: warning EXPERIMENTAL
Requires `Holiday Creator Features` for use of block tag Molang queries and to trigger block events.
:::
Creating your own tree with decaying leaves is complex, but possible! Follow this tutorial and you'll have your own in no time.
- Features:
- Decaying leaves
- Tree Feature compatable
- If leaves were broken using shears, they will drop the block
- Leaves don't decay if placed by player
- Logs are strippable and rotatable
- Stripping logs is compatible with tools from other add-ons (if they have the `minecraft:is_axe` tag)
- Saplings can be bonemealed and grow the tree (with structures)
- Issues:
- If you make a structure with these blocks, it will crash the game when generated using features.
## Decaying Leaves
You will notice straight away that our custom leaves have a long list to search for a vanilla log/custom log by its block tag, although the code example uses the custom logs for this tutorial. The value is 4 and this method is used to search for the nearest log in a circular radius.
<WikiImage
src="/assets/images/blocks/custom-trees/decaying_leaves_showcase_example.png"
alt="Decaying Leaves Showcase"
pixelated="false"
width=420
/>
Our custom leaves disables ticking when placed by the player which doesn't make the leaves decay and this removes the requirements for another duplicate leave block.
<Spoiler title="Code">
<CodeHeader>BP/blocks/custom_leaves.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_leaves",
"states": {
"wiki:decay_tier": [4, 3, 2, 1, 0], // Distance in blocks to find the log
"wiki:should_decay": [true, false], // Used when placed by the player or with features
"wiki:opaque": [false, true] // Optional; makes the leaves opaque when surrounded
}
},
"components": {
"tag:custom_leaves": {},
"minecraft:loot": "loot_tables/empty.json",
"minecraft:unit_cube": {},
"minecraft:on_player_placing": {
"event": "wiki:stop_decay"
},
// Triggers event that spawns different loot
"minecraft:on_player_destroyed": {
"event": "wiki:on_destroyed"
},
// We need both of these to work with world generation
"minecraft:queued_ticking": {
"looping": true,
"interval_range": [0, 0],
"on_tick": {
"event": "wiki:check"
}
},
"minecraft:random_ticking": {
"on_tick": {
"event": "wiki:check"
}
},
"minecraft:destructible_by_explosion": {
"explosion_resistance": 1
},
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 0.3
},
"minecraft:map_color": "#DDDDDD",
"minecraft:light_dampening": 0,
"minecraft:material_instances": {
"*": {
"texture": "custom_leaves",
"render_method": "blend"
}
}
},
"events": {
// Defines the loot for the tool
"wiki:on_destroyed": {
"sequence": [
{
"condition": "q.is_item_name_any('slot.weapon.mainhand','minecraft:shears')",
"spawn_loot": {
"table": "loot_tables/blocks/custom_leaves_shears.json"
}
},
{
"condition": "!q.is_item_name_any('slot.weapon.mainhand','minecraft:shears')",
"spawn_loot": {
"table": "loot_tables/blocks/custom_leaves.json"
}
}
]
},
// Checks for the log
"wiki:check": {
"sequence": [
{
"condition": "q.block_state('wiki:should_decay')",
"set_block_state": {
"wiki:decay_tier": "(q.block_neighbor_has_any_tag(0,0,-1,'log') || q.block_neighbor_has_any_tag(0,0,1,'log') || q.block_neighbor_has_any_tag(-1,0,0,'log') || q.block_neighbor_has_any_tag(1,0,0,'log') || q.block_neighbor_has_any_tag(0,-1,0,'log') || q.block_neighbor_has_any_tag(0,1,0,'log')) ? 4 : ((q.block_neighbor_has_any_tag(0,0,-1,'decay_tier_4') || q.block_neighbor_has_any_tag(0,0,1,'decay_tier_4') || q.block_neighbor_has_any_tag(-1,0,0,'decay_tier_4') || q.block_neighbor_has_any_tag(1,0,0,'decay_tier_4') || q.block_neighbor_has_any_tag(0,-1,0,'decay_tier_4') || q.block_neighbor_has_any_tag(0,1,0,'decay_tier_4')) ? 3 : ( (q.block_neighbor_has_any_tag(0,0,-1,'decay_tier_3') || q.block_neighbor_has_any_tag(0,0,1,'decay_tier_3 ') || q.block_neighbor_has_any_tag(-1,0,0,'decay_tier_3') || q.block_neighbor_has_any_tag(1,0,0,'decay_tier_3') || q.block_neighbor_has_any_tag(0,-1,0,'decay_tier_3') || q.block_neighbor_has_any_tag(0,1,0,'decay_tier_3')) ? 2 : ( (q.block_neighbor_has_any_tag(0,0,-1,'decay_tier_2') || q.block_neighbor_has_any_tag(0,0,1,'decay_tier_2') || q.block_neighbor_has_any_tag(-1,0,0,'decay_tier_2') || q.block_neighbor_has_any_tag(1,0,0,'decay_tier_2') || q.block_neighbor_has_any_tag(0,-1,0,'decay_tier_2') || q.block_neighbor_has_any_tag(0,1,0,'decay_tier_2')) ? 1 : 0 ) ) )"
}
},
{
"set_block_state": {
"wiki:opaque": "q.block_neighbor_has_any_tag(0,0,-1,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(0,0,1,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(0,1,0,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(0,-1,0,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(-1,0,0,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(1,0,0,'log','stone','custom_leaves')"
}
}
]
},
// When placed
"wiki:stop_decay": {
"set_block_state": {
"wiki:should_decay": false
}
},
// When decayed
"wiki:decay": {
"die": {},
"spawn_loot": {
"table": "loot_tables/blocks/custom_leaves.json"
}
}
},
"permutations": [
{
"condition": "q.block_state('wiki:decay_tier') == 0",
"components": {
"minecraft:random_ticking": {
"on_tick": {
"event": "wiki:decay"
}
},
"tag:decay_tier_0": {}
}
},
{
"condition": "q.block_state('wiki:decay_tier') == 1",
"components": {
"tag:decay_tier_1": {}
}
},
{
"condition": "q.block_state('wiki:decay_tier') == 2",
"components": {
"tag:decay_tier_2": {}
}
},
{
"condition": "q.block_state('wiki:decay_tier') == 3",
"components": {
"tag:decay_tier_3": {}
}
},
{
"condition": "q.block_state('wiki:decay_tier') == 4",
"components": {
"tag:decay_tier_4": {}
}
},
{
"condition": "q.block_state('wiki:opaque')",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "custom_leaves",
"render_method": "opaque"
}
}
}
}
]
}
}
```
</Spoiler>
## Custom Log
<Spoiler title="Code">
<CodeHeader>BP/blocks/custom_log.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_log",
"menu_category": {
"category": "nature",
"group": "itemGroup.name.log"
},
"states": {
// Log direction state
"wiki:axis": [0, 1, 2]
}
},
"components": {
"tag:log": {},
"minecraft:unit_cube": {},
// Sets different textures for sides and top/bottom of log
"minecraft:material_instances": {
"*": {
"texture": "custom_log"
},
"ends": {
"texture": "custom_log_top"
},
"up": "ends",
"down": "ends"
},
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1
},
// Sets log rotation on player placing
"minecraft:on_player_placing": {
"event": "wiki:set_axis"
},
// Make log strippable
"minecraft:on_interact": {
"condition": "q.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_axe')",
"event": "wiki:strip"
}
},
"events": {
"wiki:set_axis": {
"set_block_state": {
"wiki:axis": "Math.floor(q.block_face / 2)"
}
},
"wiki:strip": {
"sequence": [
{
"run_command": {
"command": "playsound hit.wood @a ~~~"
},
// Damages axe of player who stripped the log
"damage": {
"type": "durability",
"amount": 1,
"target": "item"
}
},
{
"condition": "q.block_state('wiki:axis') == 0",
"run_command": {
"command": "setblock ~~~ wiki:custom_stripped_log [\"wiki:axis\"=0]"
}
},
{
"condition": "q.block_state('wiki:axis') == 1",
"run_command": {
"command": "setblock ~~~ wiki:custom_stripped_log [\"wiki:axis\"=1]"
}
},
{
"condition": "q.block_state('wiki:axis') == 2",
"run_command": {
"command": "setblock ~~~ wiki:custom_stripped_log [\"wiki:axis\"=2]"
}
}
]
}
},
"permutations": [
{
"condition": "q.block_state('wiki:axis') == 0",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 1",
"components": {
"minecraft:transformation": { "rotation": [90, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 2",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 90] }
}
}
]
}
}
```
</Spoiler>
## Stripped Log
Here all components are the same
<Spoiler title="Code">
<CodeHeader>BP/blocks/custom_stripped_log.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_stripped_log",
"menu_category": {
"category": "nature",
"group": "itemGroup.name.log"
},
"states": {
// Log direction state
"wiki:axis": [0, 1, 2]
}
},
"components": {
"tag:log": {},
"minecraft:unit_cube": {},
// Sets different textures for sides and top/bottom of log
"minecraft:material_instances": {
"*": {
"texture": "custom_stripped_log"
},
"ends": {
"texture": "custom_stripped_log_top"
},
"up": "ends",
"down": "ends"
},
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1
},
// Sets log rotation on player placing
"minecraft:on_player_placing": {
"event": "wiki:set_axis"
}
},
"events": {
"wiki:set_axis": {
"set_block_state": {
"wiki:axis": "Math.floor(q.block_face / 2)"
}
}
},
"permutations": [
{
"condition": "q.block_state('wiki:axis') == 0",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 1",
"components": {
"minecraft:transformation": { "rotation": [90, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 2",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 90] }
}
}
]
}
}
```
</Spoiler>
## Custom Sapling
For the sapling we will need structures of our tree to make the sapling semi-realistic as features cannot currently be placed with commands on Minecraft Bedrock.
<Spoiler title="Code">
<CodeHeader>BP/blocks/custom_sapling.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_sapling",
"states": {
// Sapling's growth stage
"wiki:growth_stage": [0, 1, 2]
}
},
"components": {
"minecraft:collision_box": false,
"minecraft:selection_box": {
"origin": [-6, 0, -6],
"size": [12, 13, 12]
},
"minecraft:light_dampening": 0,
"minecraft:geometry": "geometry.custom_sapling",
"minecraft:material_instances": {
"*": {
"texture": "custom_sapling",
"render_method": "alpha_test",
"face_dimming": false,
"ambient_occlusion": false
}
},
// Add loot component so it will drop sapling placer item
"minecraft:loot": "loot_tables/blocks/custom_sapling.json",
// Allows to place block only on these blocks
"minecraft:placement_filter": {
"conditions": [
{
"allowed_faces": ["up"],
"block_filter": ["minecraft:dirt", "minecraft:grass", "minecraft:podzol"]
}
]
},
// Trigger growth on each random tick
"minecraft:random_ticking": {
"on_tick": {
"event": "wiki:grow"
}
},
// Trigger growth when bone meal is used
"minecraft:on_interact": {
"condition": "q.is_item_name_any('slot.weapon.mainhand', 'minecraft:bone_meal')",
"event": "wiki:fertilize"
}
},
"events": {
"wiki:grow": {
"sequence": [
{
"condition": "q.block_state('wiki:growth_stage') < 2",
"set_block_state": {
"wiki:growth_stage": "q.block_state('wiki:growth_stage') + 1"
}
},
{
"condition": "q.block_state('wiki:growth_stage') == 2",
"run_command": {
"command": "structure load custom_tree ~-2~~-2"
}
}
]
},
"wiki:fertilize": {
// Removes item that was used to interact
"decrement_stack": {},
// Trigger growth
"trigger": {
"event": "wiki:grow"
},
// Trigger effects
"run_command": {
"command": ["particle minecraft:crop_growth_emitter ~~~", "playsound item.bone_meal.use @a ~~~"]
}
}
}
}
}
```
</Spoiler>
## Sapling Placer
<Spoiler title="Code">
<CodeHeader>BP/items/custom_sapling_placer.json</CodeHeader>
```json
{
"format_version": "1.20.30",
"minecraft:item": {
"description": {
"identifier": "wiki:custom_sapling_placer",
"menu_category": {
"category": "nature",
"group": "itemGroup.name.sapling"
}
},
"components": {
"minecraft:max_stack_size": 64,
"minecraft:block_placer": {
"block": "wiki:custom_sapling"
},
"minecraft:icon": {
"texture": "custom_sapling_placer"
}
}
}
}
```
</Spoiler>
## Loot Tables
<Spoiler title="Code">
This loot will spawn leaves block (when you break it using shears)
<CodeHeader>BP/loot_tables/blocks/custom_leaves_shears.json</CodeHeader>
```json
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "wiki:custom_leaves"
}
]
}
]
}
```
Leaves default loot
<CodeHeader>BP/loot_tables/blocks/custom_leaves.json</CodeHeader>
```json
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "minecraft:apple",
"weight": 1
},
{
"type": "item",
"name": "wiki:custom_sapling_placer",
"weight": 5
},
{
// Nothing will drop
"type": "empty",
"weight": 10
}
]
}
]
}
```
This will spawn `wiki:custom_sapling`
<CodeHeader>BP/loot_tables/blocks/custom_sapling.json</CodeHeader>
```json
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "wiki:custom_sapling_placer"
}
]
}
]
}
```
</Spoiler>
## Exporting Structures
Build a tree for your sapling to grow into!
![](/assets/images/blocks/custom-trees/export_tree.png)
## Tree Features
:::tip
Tree Features are a really great way to get actual custom trees. You need some understanding on how they work but for this tutorial you can uses these templates.
:::
<Spoiler title="Feature">
<CodeHeader>BP/feature/custom_tree_feature.json</CodeHeader>
```json
{
"format_version": "1.13.0",
"minecraft:tree_feature": {
"description": {
"identifier": "wiki:custom_tree_feature"
},
"trunk": {
"trunk_block": "wiki:custom_log",
"trunk_height": {
"range_min": 4,
"range_max": 7
}
},
"canopy": {
"leaf_block": "wiki:custom_leaves",
"canopy_offset": {
"min": -3,
"max": 0
},
"variation_chance": [
{
"numerator": 1,
"denominator": 2
},
{
"numerator": 1,
"denominator": 2
},
{
"numerator": 1,
"denominator": 2
},
{
"numerator": 1,
"denominator": 1
}
]
},
"base_block": [
"minecraft:dirt",
{
"name": "minecraft:dirt",
"states": {
"dirt_type": "coarse"
}
}
],
"may_grow_on": [
"minecraft:dirt",
"minecraft:grass",
"minecraft:podzol",
{
"name": "minecraft:dirt",
"states": {
"dirt_type": "coarse"
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 0
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 1
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 2
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 3
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 4
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 5
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 6
}
},
{
"name": "minecraft:farmland",
"states": {
"moisturized_amount": 7
}
}
],
"may_replace": [
"minecraft:air",
{
"name": "minecraft:leaves",
"states": {
"old_leaf_type": "oak"
}
},
{
"name": "minecraft:leaves",
"states": {
"old_leaf_type": "spruce"
}
},
{
"name": "minecraft:leaves",
"states": {
"old_leaf_type": "birch"
}
},
{
"name": "minecraft:leaves",
"states": {
"old_leaf_type": "jungle"
}
},
{
"name": "minecraft:leaves2",
"states": {
"new_leaf_type": "acacia"
}
},
{
"name": "minecraft:leaves2",
"states": {
"new_leaf_type": "dark_oak"
}
}
],
"may_grow_through": [
"minecraft:dirt",
"minecraft:grass",
{
"name": "minecraft:dirt",
"states": {
"dirt_type": "coarse"
}
}
]
}
}
```
</Spoiler>
<Spoiler title="Feature Rule">
<CodeHeader>BP/feature_rules/custom_tree_feature_rule.json</CodeHeader>
```json
{
"format_version": "1.13.0",
"minecraft:feature_rules": {
"description": {
"identifier": "wiki:custom_tree_feature_rule",
"places_feature": "wiki:custom_tree_feature"
},
"conditions": {
"placement_pass": "surface_pass",
"minecraft:biome_filter": [
{
"test": "has_biome_tag",
"operator": "==",
"value": "plains"
}
]
},
"distribution": {
"iterations": 1,
"x": {
"distribution": "uniform",
"extent": [0, 16]
},
"y": "q.heightmap(v.worldx, v.worldz)",
"z": {
"distribution": "uniform",
"extent": [0, 16]
}
}
}
}
```
</Spoiler>
## Resource Pack (optional guide)
Now it is time to make a resource pack!
Make translations for blocks:
<CodeHeader>RP/texts/en_US.lang</CodeHeader>
```
tile.wiki:custom_log.name=Custom Log
tile.wiki:custom_leaves.name=Custom Leaves
tile.wiki:custom_stripped_log.name=Custom Stripped Log
tile.wiki:custom_sapling.name=Custom Sapling
item.wiki:custom_sapling_placer=Custom Sapling
```
Make terrain_texture.json and textures.
<CodeHeader>RP/textures/terrain_texture.json</CodeHeader>
```json
{
"resource_pack_name": "custom-trees",
"texture_name": "atlas.terrain",
"num_mip_levels": 4,
"padding": 8,
"texture_data": {
"custom_leaves": {
"textures": "textures/blocks/leaves_oak"
},
"custom_log": {
"textures": "textures/blocks/log_oak"
},
"custom_log_top": {
"textures": "textures/blocks/log_oak_top"
},
"custom_stripped_log": {
"textures": "textures/blocks/stripped_oak_log"
},
"custom_stripped_log_top": {
"textures": "textures/blocks/stripped_oak_log_top"
},
"custom_sapling": {
"textures": "textures/blocks/sapling_oak"
}
}
}
```
Make geometry for sapling:
<CodeHeader>RP/models/blocks/custom_sapling.geo.json</CodeHeader>
```json
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.custom_sapling",
"texture_width": 16,
"texture_height": 16,
"visible_bounds_width": 2,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "sapling",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-8, 0, 0],
"size": [16, 16, 0],
"pivot": [0, 0, 0],
"rotation": [0, 45, 0],
"uv": {
"north": {"uv": [0, 0], "uv_size": [16, 16]}
}
},
{
"origin": [-8, 0, 0],
"size": [16, 16, 0],
"pivot": [0, 0, 0],
"rotation": [0, -45, 0],
"uv": {
"north": {"uv": [0, 0], "uv_size": [16, 16]}
}
}
]
}
]
}
]
}
```
Make item_texture file
<CodeHeader>RP/textures/item_texture.json</CodeHeader>
```json
{
"resource_pack_name": "custom-trees",
"texture_name": "atlas.items",
"texture_data": {
"custom_sapling_placer": {
"textures": "textures/blocks/sapling_oak"
}
}
}
```
Add sounds to blocks
<CodeHeader>RP/blocks.json</CodeHeader>
```json
{
"format_version": [1, 1, 0],
"wiki:custom_leaves": {
"sound": "grass"
},
"wiki:custom_log": {
"sound": "wood"
},
"wiki:custom_stripped_log": {
"sound": "wood"
},
"wiki:custom_sapling": {
"sound": "grass"
}
}
```
## Result
What you have created:
<Checklist>
- [x] Custom Trees with Decaying Leaves
- [x] Working Sapling
- [x] Rotatable and Stripable Logs
</Checklist>
<FolderView :paths="[
'BP/blocks/custom_leaves.json',
'BP/blocks/custom_log.json',
'BP/blocks/custom_stripped_log.json',
'BP/blocks/custom_sapling.json',
'BP/features/custom_tree_feature.json',
'BP/feature_rules/custom_tree_feature_rule.json',
'BP/items/custom_sapling_placer.json',
'BP/loot_tables/blocks/custom_leaves.json',
'BP/loot_tables/blocks/custom_leaves_shears.json',
'BP/loot_tables/blocks/custom_sapling.json',
'BP/structures/custom_tree.mcstructure',
'RP/blocks.json',
'RP/texts/en_US.lang',
'RP/textures/terrain_texture.json',
'RP/models/blocks/custom_sapling.geo.json',
'RP/textures/item_texture.json'
]"></FolderView>
![](/assets/images/blocks/custom-trees/result.png)
## Download Example Pack
Template Pack to use in-game to get the idea.
<BButton
link="https://github.com/Bedrock-OSS/wiki-addon/releases/download/download/custom_trees.mcaddon"
color=blue
>Download MCADDON</BButton>