Minecraft Scripting API

Please note: Some examples on this page may be outdated or may not work as expected.

Blocks & Block States

Blocks are the fundamental building units of Minecraft. Each block has properties called "states" that define its appearance and behavior. Understanding block properties lets you detect changes, modify block behavior on the fly, and build dynamic world systems.

Understanding Block States

Block states are the dynamic properties that make blocks behave differently - a door can be open or closed, crops grow through different ages, logs face different directions. When you modify a block state, you're changing how that block looks and behaves without changing what type of block it is.

Why this matters: Instead of replacing blocks entirely, you can adjust their properties. This is more efficient and lets you create interactive systems.

How It Works

Every block has a "permutation" - a combination of its type plus all its current property values. When you want to change a block's appearance or behavior:

  1. Get the block at a location
  2. Get its current permutation (type + properties)
  3. Create a new permutation with modified properties
  4. Apply it back to the block
import { world } from "@minecraft/server";

// Get a block at a specific location
const block = world.getDimension("overworld").getBlock({ x: 0, y: 64, z: 0 });

// Read a block property (get its current value)
const age = block.permutation.getProperty("age");
console.log("Crop age:", age);

// Modify a block property (create new permutation with changed property)
const newPermutation = block.permutation.withProperty("age", 7); // Fully grown
block.setPermutation(newPermutation);

// Chain multiple properties (modify multiple at once)
const rotatedOpen = block.permutation
  .withProperty("rotation", 1)
  .withProperty("open", true);
block.setPermutation(rotatedOpen);

Why use permutations? Because changing one property resets others if you're not careful. A permutation tracks the full state, so you can modify one property while preserving the others.

Common Block Properties

Property Type Example Values Use Case
facing_direction Number 0-5 (down, up, north, south, west, east) Stairs, logs, furnaces facing different directions
rotation Number 0-15 Wall banners, map facing direction
powered Boolean true/false Redstone blocks, repeaters, comparators
open Boolean true/false Doors, gates, trapdoors
age Number 0-7 (crops), varies by plant Crop growth stages, tree growth

Reading vs. Modifying

// **Reading** - get current state (doesn't change anything)
const currentAge = block.permutation.getProperty("age");
const isOpen = block.permutation.getProperty("open");

// **Modifying** - change state (affects the block in world)
const grown = block.permutation.withProperty("age", 7);
block.setPermutation(grown); // Now the block displays fully grown

// **Combining** - modify multiple properties at once
const doorState = block.permutation
  .withProperty("open", true)
  .withProperty("facing_direction", 2); // Facing north
block.setPermutation(doorState);

Practical Examples

// Auto-harvest wheat at full growth
world.afterEvents.blockBreak.subscribe((event) => {
  const block = event.brokenBlockPermutation;
  
  if (block.type.id.includes("wheat")) {
    const age = block.getProperty("age");
    // Only drop seeds if it was fully grown (age 7)
    if (age === 7) {
      console.log("Full wheat harvested - drop seeds");
    }
  }
});

// Open doors near a redstone signal
world.afterEvents.blockBreak.subscribe((event) => {
  const block = event.block;
  
  if (block.typeId === "minecraft:redstone_block") {
    // Find nearby doors and open them
    const nearbyBlocks = block.dimension.getBlocks(
      { x: block.location.x - 5, y: block.location.y - 5, z: block.location.z - 5 },
      { x: block.location.x + 5, y: block.location.y + 5, z: block.location.z + 5 }
    );
    
    for (const nearbyBlock of nearbyBlocks) {
      if (nearbyBlock.typeId === "minecraft:oak_door") {
        const opened = nearbyBlock.permutation.withProperty("open", true);
        nearbyBlock.setPermutation(opened);
      }
    }
  }
});

// Cycle through crop ages (useful for testing or farming automation)
function advanceCropGrowth(block) {
  const currentAge = block.permutation.getProperty("age") || 0;
  const maxAge = 7; // Most crops go 0-7
  
  if (currentAge < maxAge) {
    const nextStage = block.permutation.withProperty("age", currentAge + 1);
    block.setPermutation(nextStage);
    return true;
  }
  return false; // Already fully grown
}

Best Practices

  • Always get the full permutation before modifying - don't assume other properties won't change
  • Check property exists before reading - not all blocks have all properties
  • Use in block events - detect changes with blockBreak and blockPlace events
  • Test interactively - use creative mode to see what properties blocks have
  • Chain properties carefully - order matters when you're applying multiple changes
Navigation