In Minecraft's block system, each block has one or more block states. For example, wood has a facing direction, and leaves have different distances. These states determine how the block behaves and appears in the game.
Examples
Here are three examples to explain how to create a block with a single state and a block with multiple states in Minecraft:
The internal ID (id) represents a unique identifier for blocks. The maximum number of internal IDs is determined by the sum of two factors:
Available Block Appearance States: These are defined in the mappings.yml file. For a single block type, the more block states you "release," the higher the number of available appearance states.
Additionally Registered Real States: These are added via the additional-real-blocks.yml file. This configuration allows you to manually register extra real serverside states for specific blocks, further increasing the total pool of internal IDs.
Why Register Additional Real Blocks?
Some blocks in the game (e.g., vanilla Minecraft leaves) have more block states than actual appearance variations. For example:
Vanilla leaves have 28 block states (technical properties like distance, persistant, etc.), but only 2 distinct visual appearances (e.g., oak leaves with/without water).
The unused block states (e.g., 26 out of 28) can be repurposed to create new custom blocks (e.g., palm leaves and etc.).
The Challenge
Creating a new leaf type with unique functionality might require 28 server-side states even if it only uses 2 visual appearances. However, only 26 serverside real states are available from vanilla leaves, creating a shortage of 2 states.
state refers to the vanilla block state appearance used by a custom block state.
For example, noteblock:15 means the 16th released Note Block state in mappings.yml (counting starts at 0).
You can configure state like this if you want to precisely control the state in use
This configuration file may seem lengthy and complex, but we can simplify everything using the template system.(If you haven’t read the template system tutorial yet, make sure to study it after learning about states!)
Let’s break down states into three key sections for clarity:
1. Define Block Properties
Defines the block properties (e.g., facing, level, lit) that determine how the block behaves or interacts. For detailed info read 🏷️ Properties
properties:
axis: # Property name (e.g., axis, color)
type: axis # Data type (e.g., axis, boolean, int, string)
default: y # Default state (e.g., y for vertical orientation)
2. Configure Appearances
Appearances define the used visual states.
appearances:
axisY: # Unique appearance name (e.g., axisY, red)
state: "note_block:0" # Vanilla state (e.g., note_block:0)
model:
path: "minecraft:block/custom/stripped_palm_log" # Path to model file
generation: # (Optional) Procedural model generation rules
parent: "minecraft:block/cube_column" # Base model template
textures: # Override textures for the parent model
"end": "minecraft:block/custom/palm_log_top"
"side": "minecraft:block/custom/palm_log"
3. Map Variants
Variants link property combinations to specific appearances and internal IDs.
variants:
axis=x: # Property condition (e.g., axis=x, color=red)
appearance: axisX # Appearance to use for this variant
id: 0 # Unique internal ID (must be unique per variant)
settings: # Optional settings override
...
Example 3: Creating a Block with Multiple Properties
Don’t worry if this seems overwhelming at first! In Minecraft, only a handful of vanilla blocks have a high number of states, which is why most custom blocks are built using these "state-rich" vanilla blocks as a foundation. Let’s break it down step by step.
We start by declaring three properties for the block, which determine its possible variants:
properties:
waterlogged:
type: boolean
default: false # Whether the block contains water
persistent:
type: boolean
default: true # Whether the block persists (e.g., leaves decay if false)
distance:
type: int
default: 7 # Distance from the nearest log (1-7)
min: 1
max: 7
Total Variants
The combination of these properties creates 2 × 2 × 7 = 28 variants:
waterlogged: 2 states (true/false).
persistent: 2 states (true/false).
distance: 7 states (values 1 to 7).
Step 2: Define Visual States
Even though this block uses 28 server-side states (combinations of waterlogged, persistent, and distance), we only need two visual appearances to represent it. Here’s how we achieve this:
appearances:
default:
# (non-waterlogged) leaves
state: "oak_leaves[distance=1,persistent=false,waterlogged=false]"
model:
path: "minecraft:block/custom/palm_leaves"
generation:
parent: "minecraft:block/leaves" # Inherit vanilla leaves model
textures:
"all": "minecraft:block/custom/palm_leaves" # Custom texture
waterlogged:
# waterlogged leaves
state: "oak_leaves[distance=1,persistent=false,waterlogged=true]"
model:
path: "minecraft:block/custom/palm_leaves" # Same model as default
Step 3: Assign Internal IDs and Override Behaviors
Map all possible block state combinations to internal IDs and appearances. Some variants require overriding vanilla behaviors (e.g., waterlogged blocks being explosion-proof, distance=7 blocks triggering randomTick).
Example Configuration
variants:
distance=1,persistent=false,waterlogged=false:
appearance: "default" # Uses the "default" visual state
id: 0 # Unique internal ID
distance=2,persistent=false,waterlogged=false:
appearance: "default" # Reuse the "default" visual state
id: 1
Advanced Overrides
To customize block behavior for specific states, add logic like this:
The model of the block supports multiple models with random weights. When using it, you simply need to change "model" to "models" and provide a list containing all the models.
Additionally, you can use x and y to rotate the model by a certain degree along the x-axis or y-axis. In this example, the plugin actually uses only two models, with the variants along the x and z axes derived from rotation.