How Bedrock Handles Custom Block Redstone
In older versions of Bedrock Edition, block creators tried to react to redstone using legacy JSON block events, which have since been removed from the format. Today, custom block redstone is split into two distinct responsibilities: passive physical properties and active logic.
Passive properties dictate whether redstone dust connects to the block, whether a repeater can push strong power through it, and whether redstone wire can climb up its sides while stepping up a slope. This is configured directly inside the block JSON using `minecraft:redstone_conductivity`. Active logic—such as switching a block state when powered by an adjacent lever or emitting a redstone signal itself—is not currently exposed as a simple declarative JSON trigger. Instead, you implement active behavior using the `@minecraft/server` Script API alongside `minecraft:custom_components`.
The minecraft:redstone_conductivity Component
The `minecraft:redstone_conductivity` component tells the game's redstone engine whether to treat your custom block like an opaque full block (such as stone) or an insulator (such as glass). Without this component, Bedrock determines conductivity from the block's collision and material settings, which often causes custom geometry blocks to accidentally cut redstone lines or fail to transmit power from repeaters.
You can place this component in the base `components` block of your JSON file, or inside `permutations` if you want your block to dynamically switch between conducting and insulating states depending on a block state.
| Field | What it does | Notes |
|---|---|---|
| redstone_conductor | Controls whether the block can be strongly powered by repeaters and torches to energize adjacent redstone dust. | Boolean. Defaults to false for most custom geometry blocks unless specified. |
| allows_wire_to_step_down | Determines if a redstone dust line stepping down the side of this block is cut off or allowed to connect to the block below. | Boolean. Set to false on transparent blocks like glass or glowstone so dust can travel up them in a staircase without being cut going down. |
{
"format_version": "1.21.30",
"minecraft:block": {
"description": {
"identifier": "wiki:conductive_casing"
},
"components": {
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1.5
},
"minecraft:redstone_conductivity": {
"redstone_conductor": true,
"allows_wire_to_step_down": true
}
}
}
}Building a Redstone-Reactive Block with Permutations
To build a block that visibly reacts to redstone—like a custom redstone lamp—you first define a boolean block state in the block description. When that state flips to true, a permutation swaps the texture in `minecraft:material_instances` and raises the light emission using `minecraft:light_emission`.
Because Bedrock does not provide a native JSON event for 'on redstone power changed', the block uses `minecraft:tick` alongside `minecraft:custom_components` to poll its own redstone power level every few ticks via script. Polling every 2 game ticks matches the 1-redstone-tick delay of standard vanilla redstone components.
{
"format_version": "1.21.30",
"minecraft:block": {
"description": {
"identifier": "wiki:copper_lamp",
"states": {
"wiki:lit": [false, true]
}
},
"components": {
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1.0
},
"minecraft:redstone_conductivity": {
"redstone_conductor": true,
"allows_wire_to_step_down": true
},
"minecraft:material_instances": {
"*": {
"texture": "copper_lamp_off",
"render_method": "opaque"
}
},
"minecraft:light_emission": 0,
"minecraft:tick": {
"interval_range": [2, 2],
"looping": true
},
"minecraft:custom_components": [
"wiki:redstone_lamp_logic"
]
},
"permutations": [
{
"condition": "q.block_state('wiki:lit') == true",
"components": {
"minecraft:material_instances": {
"*": {
"texture": "copper_lamp_on",
"render_method": "opaque"
}
},
"minecraft:light_emission": 15
}
}
]
}
}Detecting Redstone Power in Script API
In your behavior pack script, you register the `wiki:redstone_lamp_logic` custom component during the `worldInitialize` startup event. Inside the `onTick` handler, you call the `getRedstonePower()` method on the `Block` object. This method returns an integer from `0` to `15` representing the strongest redstone signal currently reaching that block space, or `undefined` if the block cannot receive redstone power.
Always check whether the current block state already matches the redstone state before calling `setPermutation`. Calling `setPermutation` on every single tick even when nothing has changed triggers unnecessary chunk mesh rebuilds and will cause severe frame rate drops when players place dozens of your blocks in a single chunk.
import { world } from "@minecraft/server";
world.beforeEvents.worldInitialize.subscribe((eventData) => {
eventData.blockComponentRegistry.registerCustomComponent("wiki:redstone_lamp_logic", {
onTick(event) {
const block = event.block;
const power = block.getRedstonePower() ?? 0;
const shouldBeLit = power > 0;
const currentPerm = block.permutation;
const isCurrentlyLit = currentPerm.getState("wiki:lit");
if (isCurrentlyLit !== shouldBeLit) {
block.setPermutation(currentPerm.withState("wiki:lit", shouldBeLit));
}
}
});
});Current Limitations of Custom Redstone Blocks
While `minecraft:redstone_conductivity` and `getRedstonePower()` cover passive conductivity and power detection, Bedrock's custom block system still has hard boundaries regarding redstone output. There is currently no stable JSON component that lets a custom block emit its own redstone power level like a vanilla redstone block, daylight detector, or target block.
If you need a custom block to act as a power source (such as a custom button, pressure plate, or generator), creators typically work around the limitation by either replacing an adjacent air block with an invisible technical block, or by checking for custom blocks directly inside the `onTick` scripts of neighboring custom machines rather than relying on vanilla redstone dust to carry the signal.
Which versions this applies to
Requires format_version 1.21.30 or higher for stable minecraft:redstone_conductivity and minecraft:custom_components without any experimental toggles enabled. Uses @minecraft/server version 1.14.0 or newer in manifest.json.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| [Blocks][error]-wiki:copper_lamp | minecraft:redstone_conductivity is not a valid component | Your block JSON declares an older format_version (such as 1.20.10 or 1.19.50) before the redstone conductivity component was added to the stable schema. | Update the format_version at the top of your block JSON file to at least "1.21.30". |
| block.getRedstonePower() always returns undefined in script even when a lever is attached and switched on. | The block has custom geometry or non-conductive material properties and lacks the minecraft:redstone_conductivity component, so the game's redstone graph completely ignores the block position. | Add "minecraft:redstone_conductivity": { "redstone_conductor": true } to the block's components so the engine calculates redstone signal strength for that block. |
| [Scripting][error]-Failed to find custom component 'wiki:redstone_lamp_logic' for block 'wiki:copper_lamp' | The custom component was registered inside world.afterEvents.worldInitialize or at the top level of the script file instead of inside the beforeEvents hook. | Move blockComponentRegistry.registerCustomComponent inside world.beforeEvents.worldInitialize.subscribe() so it registers before block definitions are parsed. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
