Redstone Notifier Order

Java Edition 1.21.11・redstone dust update order analysis

All 60 patterns & probabilities →
Mode
Click directions in observed order (1 → 7)
How it works

1 · Vec3i.hashCode()

BlockPos extends Vec3i and inherits its hash. The formula encodes all three axes into a single 32-bit integer.

// net.minecraft.core.Vec3i
public int hashCode() {
  return (getY() + getZ() * 31) * 31
       + getX();
}

2 · HashMap internal spread

Java's HashMap applies an XOR-spread before assigning a bucket. This code is inside the JDK, invisible in Minecraft source.

// java.util.HashMap  (JDK internal)
static final int hash(Object key) {
  int h = key.hashCode();
  return h ^ (h >>> 16);
}
// bucket = hash(key) & (capacity−1)
//        = hash(key) & 15

3 · DefaultRedstoneWireEvaluator.updatePowerStrength()

When power changes, a HashSet<BlockPos> (initial capacity 16) is built by inserting SELF then Direction.values() in enum order: DOWN, UP, NORTH, SOUTH, WEST, EAST. Iterating the set — bucket 0→15, ties broken by insertion order — drives the updateNeighborsAt() calls.

// net.minecraft.world.level.redstone.DefaultRedstoneWireEvaluator
public void updatePowerStrength(Level level, BlockPos pos,
    BlockState state, Orientation orientation, boolean added) {

  int i = calculateTargetStrength(level, pos);
  if (state.getValue(RedStoneWireBlock.POWER) != i) {
    if (level.getBlockState(pos) == state)
      level.setBlock(pos, state.setValue(RedStoneWireBlock.POWER, i), 2);

    // Insertion order: SELF, DOWN, UP, NORTH, SOUTH, WEST, EAST
    HashSet<BlockPos> set = Sets.newHashSet();
    set.add(pos);
    for (Direction dir : Direction.values())
      set.add(pos.relative(dir));

    // Iteration order = bucket order = coordinate-dependent
    for (BlockPos p : set)
      level.updateNeighborsAt(p, wireBlock);
  }
}

4 · Why 60 patterns across the world

Near the origin where |hashCode| < 65536, the term h >>> 16 is zero and the XOR has no effect, producing 26 distinct patterns that repeat with period 16. For large coordinates where |hashCode| ≥ 65536, upper bits bleed into the lower 16 via XOR, unlocking 34 additional rare patterns — totalling 60. About 97% of all wire positions share just 6 patterns; the rarest appears in only ~0.005% of locations.

See all 60 patterns with exact probabilities.

What is a notifier?

Notifier

A notifier is a block position that acts as the source of a neighbor update. When level.updateNeighborsAt(notifier, wireBlock) is called, it triggers updates on all 6 faces of the notifier in a fixed, constant order: −X, +X, −Y, +Y, −Z, +Z.

This per-notifier order is always the same regardless of world position. The coordinate dependence comes entirely from which position becomes the notifier, and in what sequence the 7 notifiers fire.

Where the coordinate dependence enters

The 7 candidate notifiers (wire + 6 neighbours) are stored in a HashSet. Iteration order over a HashSet follows bucket index, and each bucket index is derived from (hashCode ^ (hashCode >>> 16)) & 15. Because hashCode is a function of absolute world coordinates, the firing order of the 7 notifiers — and therefore the sequence of all resulting neighbor updates — is coordinate-dependent.

Summary of the update sequence

1 Wire's power changes → updatePowerStrength() called
2 7 positions (self + ±X/Y/Z) placed into HashSet — order determined by hashCode of each absolute position
3 Each position fires as a notifier in HashSet iteration order (coordinate-dependent)
4 Each notifier updates its 6 faces in fixed order: −X, +X, −Y, +Y, −Z, +Z (always constant)