diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenActivator.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenActivator.java
index d59d6a034..1aa3ea217 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenActivator.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenActivator.java
@@ -12,6 +12,7 @@ import net.minecraft.core.player.inventory.container.ContainerInventory;
 import net.minecraft.core.player.inventory.menu.MenuActivator;
 import net.minecraft.core.player.inventory.slot.Slot;
 import net.minecraft.core.sound.SoundCategory;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -88,9 +89,9 @@ public class ScreenActivator extends ScreenContainerAbstract {
         private static final byte NONE = 0, LOCK = 1, UNLOCK = 2;
 
         @Override
-        protected void mousePressed(int x, int y, Slot slot, int button) {
+        protected void mousePressed(int x, int y, @Nullable Slot slot, int button) {
             if (button != 1 || super.isDragging() ||
-                super.getGrabbedItem() != null || slot.getItemStack() != null
+                super.getGrabbedItem() != null || slot == null || slot.getItemStack() != null
             ) {
                 super.mousePressed(x, y, slot, button);
                 return;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java
index 064a9a1b3..883fa65f7 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java
@@ -35,6 +35,7 @@ import net.minecraft.core.player.inventory.slot.SlotCreative;
 import java.util.List;
 
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.input.Keyboard;
 
 public abstract class ScreenContainerAbstract extends Screen {
@@ -135,7 +136,7 @@ public abstract class ScreenContainerAbstract extends Screen {
         return i >= slot.x - 1 && i < slot.x + 16 + 1 && j >= slot.y - 1 && j < slot.y + 16 + 1;
     }
 
-    public Slot getSlotAtPosition(final int i, final int j) {
+    public @Nullable Slot getSlotAtPosition(final int i, final int j) {
         for (int k = 0; k < this.inventorySlots.slots.size(); k++) {
             final Slot slot = this.inventorySlots.slots.get(k);
             if (getIsMouseOverSlot(slot, i, j)) {
diff --git a/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java b/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
index bc9cc7de2..ccfd71fe4 100644
--- a/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
+++ b/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
@@ -8,6 +8,7 @@ import it.unimi.dsi.fastutil.ints.IntSet;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
+import org.jetbrains.annotations.Nullable;
 import org.lwjgl.input.Keyboard;
 
 import net.minecraft.client.Minecraft;
@@ -170,7 +171,7 @@ public class ItemDragHandler extends Gui {
         this.mc.playerController.handleInventoryMouseClick(this.container.inventorySlots.containerId, action, args, this.mc.thePlayer);
 	}
 	
-	protected void mousePressed(final int x, final int y, final Slot slot, int button) {
+	protected void mousePressed(final int x, final int y, final @Nullable Slot slot, int button) {
 		ItemStack stack = getGrabbedItem();
 		
 		if(button == 0) {
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/brick_brimstone.png b/game/client/src/main/resources/assets/minecraft/textures/block/brick_brimstone.png
index 8a417b510..84f877280 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/brick_brimstone.png and b/game/client/src/main/resources/assets/minecraft/textures/block/brick_brimstone.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/brick_brimstone.png~ b/game/client/src/main/resources/assets/minecraft/textures/block/brick_brimstone.png~
new file mode 100644
index 000000000..8a417b510
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/brick_brimstone.png~ differ
diff --git a/game/core/src/main/java/net/minecraft/core/block/Block.java b/game/core/src/main/java/net/minecraft/core/block/Block.java
index b6c7968bb..cd6a1ac78 100644
--- a/game/core/src/main/java/net/minecraft/core/block/Block.java
+++ b/game/core/src/main/java/net/minecraft/core/block/Block.java
@@ -63,7 +63,6 @@ public final class Block<T extends BlockLogic>
     public int emission;
     public @Nullable Integer lightBlock = null;
     public boolean isEntityTile = false;
-    public boolean disabledNeighborMetaNotify = false;
     public boolean shouldTick = false;
     public @Nullable Supplier<@NotNull TileEntity> entitySupplier;
     public @Nullable MaterialColor overrideColor;
@@ -128,11 +127,6 @@ public final class Block<T extends BlockLogic>
         return this;
     }
 
-    public Block<T> withDisabledNeighborNotifyOnMetadataChange() {
-        this.disabledNeighborMetaNotify = true;
-        return this;
-    }
-
     public Block<T> withLightBlock(final int blockAmount) {
         this.lightBlock = blockAmount;
         return this;
@@ -628,10 +622,6 @@ public final class Block<T extends BlockLogic>
         return Blocks.lightEmission[this.id];
     }
 
-    public boolean neighborNotifyOnDataChangeDisabled() {
-        return Blocks.neighborNotifyOnMetadataChangeDisabled[this.id];
-    }
-
     public static boolean hasLogicClass(@Nullable final Block<?> block, final @NotNull Class<?> logicClass) {
         return block != null && logicClass.isAssignableFrom(block.getLogic().getClass());
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java
index f8fe18d53..f381b4741 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java
@@ -121,4 +121,9 @@ public class BlockLogicAir
     public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) {
         return Material.PISTON_DESTROY_ON_PUSH;
     }
+
+    @Override
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        return false;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java
index a911205ad..980dada5f 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBasket.java
@@ -69,19 +69,32 @@ public class BlockLogicBasket extends BlockLogic {
     }
 
     public int getFillLevel(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) {
-        if (source.getTileEntity(tilePos) instanceof TileEntityBasket basket) { // Instance check done to avoid a class cast exception that seems to sometimes happen on pushed baskets in mp, sometimes. Probably a synchronization issue in MP needs further evaluation
-            final float fill = MathHelper.clamp(basket.getNumUnitsInside() / (float) basket.getMaxUnits(), 0, 1); // Clamps the visual effect even if the basket gets overstuffed
+        return (source.getTileEntity(tilePos) instanceof TileEntityBasket basket)
+            ? getFillLevel(basket)
+            : 0;
+    }
 
-            return (int) Math.ceil(10 * fill);
-        }
-        return 0;
+    protected static int getFillLevel(@NotNull TileEntityBasket tileEntity) {
+        final float fill = MathHelper.clamp(tileEntity.getNumUnitsInside() / (float) tileEntity.getMaxUnits(), 0, 1); // Clamps the visual effect even if the basket gets overstuffed
+        return (int) Math.ceil(10 * fill);
     }
 
+
     @Deprecated
     public final int getFillLevel(final @NotNull WorldSource source, final int x, final int y, final int z) {
         return this.getFillLevel(source, new TilePos(x, y, z));
     }
 
+    @Override
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        if (world.getBlockType(thatPos) != this.block) return false;
+        if (!(world.getTileEntity(thisPos) instanceof TileEntityBasket thisBasket) ||
+            !(world.getTileEntity(thatPos) instanceof TileEntityBasket thatBasket))
+            return false;
+        return getFillLevel(thisBasket) == getFillLevel(thatBasket);
+    }
+
     @Override
     public boolean isSolidRender() {
         return false;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java
index d29c1ef19..9f0adf63a 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java
@@ -34,7 +34,7 @@ public class BlockLogicBed
 
     @Override
     protected int getMatcherEquivalenceData(final int data) {
-        return data & ~DIRECTION.mask;
+        return data & ~(DIRECTION.mask | IS_OCCUPIED.mask);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java
index 62d75eadb..0c8daee2f 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCactus.java
@@ -50,15 +50,11 @@ public class BlockLogicCactus
                 cactusHeight++;
             }
             if (cactusHeight < 3) {
-                final int data = world.getBlockData(tilePos);
-                if (data == 15) {
-                    world.setBlockData(tilePos, 0);
-                    world.setBlockType(tilePos.add(Direction.UP, queryPos), this.block);
-                    world.markBlockNeedsUpdate(tilePos);
-                    world.markBlockNeedsUpdate(queryPos);
-                    world.notifyBlocksInCapsuleOfNeighborChange(Direction.UP, tilePos, this.block);
-                } else {
-                    world.setBlockDataNotify(tilePos, data + 1);
+                int data = world.getBlockData(tilePos);
+                data = (data + 1) & 0xF;
+                world.setBlockData(tilePos, data);
+                if (data == 0) {
+                    world.setBlockTypeNotify(tilePos.add(Direction.UP, queryPos), this.block);
                 }
             }
         }
@@ -148,4 +144,9 @@ public class BlockLogicCactus
         }
         return true;
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        return 0;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java
index f5c36f7a2..8c9255995 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java
@@ -26,8 +26,11 @@ public class BlockLogicChest
     }
 
     @Override
-    protected int getMatcherEquivalenceData(final int data) {
-        return data & typeBits;
+    protected int getMatcherEquivalenceData(int data) {
+        data &= ~directionBits;
+        assert Type.SINGLE.ordinal() == 0;
+        if ((data & typeBits) != 0) data |= typeBits;
+        return data;
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java
index 0909fb927..66ac6c306 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicConduit.java
@@ -496,4 +496,11 @@ public class BlockLogicConduit extends BlockLogic {
     public static int signalConverter(int strength, boolean conduitToRedstone) {
         return Math.max(0, Math.min(PROPAGATION_LENGTH, strength));
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        if ((data & STATE_MASK) == 0) assert getOpenSides(data).length == 0;
+        else data |= STATE_MASK;
+        return data;
+    }
 }
\ No newline at end of file
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java
index e07c01202..00f5e7676 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoor.java
@@ -62,7 +62,13 @@ public class BlockLogicDoor
 
     @Override
     protected int getMatcherEquivalenceData(final int data) {
-        return data & ~(MASK_ROTATION);
+        final int MASK_NON_COLOR = MASK_OPENED | MASK_HINGE | MASK_ROTATION;
+        int d1 = data & ~MASK_NON_COLOR;
+        int d2 = data &  MASK_NON_COLOR;
+        assert (MASK_HINGE >>> 1) == MASK_OPENED;
+        d2 ^= d2 >>> 1; // flips the opened bit if hinge bit is set
+        d1 |= d2;
+        return d1 & ~(MASK_HINGE | MASK_ROTATION);
     }
 
     @Override
@@ -148,29 +154,36 @@ public class BlockLogicDoor
         if (this.material == Materials.METAL || this.material == Materials.STEEL) {
             return false;
         }
-        TilePos queryPos = new TilePos();
+        final TilePos queryPos = new TilePos();
         final int data = world.getBlockData(tilePos);
+
         if (this.isTop) {
-            final Block<?> b = world.getBlockType(tilePos.down(queryPos));
-            if (b.getLogic() instanceof BlockLogicDoor blockLogicDoor) {
-                blockLogicDoor.onInteracted(world, tilePos.down(queryPos), player, side, xHit, yHit);
-            }
-            return true;
-        }
-        final @Nullable Block<?> b = world.getBlockType(tilePos.up(queryPos));
-        if (b.getLogic() instanceof BlockLogicDoor) {
-            world.setBlockDataNotify(tilePos.up(queryPos), data ^ MASK_OPENED);
+            final var lowerPos = tilePos.down(queryPos);
+
+            final Block<?> b = world.getBlockType(lowerPos);
+            if (!(b.getLogic() instanceof BlockLogicDoor blockLogicDoor)) return false;
+            return blockLogicDoor.onInteracted(world, lowerPos, player, side, xHit, yHit);
         }
+
+        final var upperPos = tilePos.up(queryPos);
+        final boolean hasTop = world.getBlockType(upperPos).getLogic() instanceof BlockLogicDoor;
         final int openedData = data ^ MASK_OPENED;
-        world.setBlockDataNotify(tilePos, openedData);
-        if (!this.isSupported(world, tilePos, openedData)) {
+
+        if (hasTop) world.setBlockData(upperPos, openedData);
+        world.setBlockData(tilePos, openedData);
+
+        if (!this.isSupported(world, tilePos, data)) {
             this.dropWithCause(world, EnumDropCause.WORLD, tilePos, openedData, null, null);
-            world.setBlockTypeNotify(tilePos, Blocks.AIR);
-            if (world.getBlockLogic(tilePos.up(queryPos), BlockLogicDoor.class) != null) {
-                world.setBlockTypeNotify(tilePos.up(queryPos), Blocks.AIR);
-            }
+            
+            world.setBlockType(tilePos, Blocks.AIR);
+            if (hasTop) world.setBlockType(upperPos, Blocks.AIR);
         }
-        world.markBlocksDirty(tilePos.down(queryPos), tilePos);
+
+        // world.markBlocksDirty(tilePos, upperPos);
+        world.markBlockNeedsUpdate(tilePos);
+        world.markBlockNeedsUpdate(upperPos);
+        world.notifyBlocksInCapsuleOfNeighborChange(Direction.UP, tilePos, this.block);
+
         world.playBlockEvent(player, tilePos, LevelListener.EVENT_DOOR_SOUND, 0);
         return true;
     }
@@ -217,13 +230,13 @@ public class BlockLogicDoor
             final @NotNull Block<?> b = world.getBlockType(tilePos.down(queryPos));
             if (!(b.getLogic() instanceof BlockLogicDoor)) {
                 world.setBlockTypeNotify(tilePos, Blocks.AIR);
+                return;
             }
-            if (block.isSignalSource()) {
-                b.onNeighborChanged(world, tilePos.down(queryPos), block);
-            }
+            b.onNeighborChanged(world, tilePos.down(queryPos), block);
         } else {
             boolean hasCommittedSuicide = false;
-            final @NotNull Block<?> otherBlock = world.getBlockType(tilePos.up(queryPos));
+            final var upperPos = tilePos.up(queryPos);
+            final @NotNull Block<?> otherBlock = world.getBlockType(upperPos);
             if (!(otherBlock.getLogic() instanceof BlockLogicDoor)) {
                 world.setBlockTypeNotify(tilePos, Blocks.AIR);
                 hasCommittedSuicide = true;
@@ -233,11 +246,11 @@ public class BlockLogicDoor
                 world.setBlockTypeNotify(tilePos, Blocks.AIR);
                 hasCommittedSuicide = true;
                 if (otherBlock.getLogic() instanceof BlockLogicDoor) {
-                    world.setBlockTypeNotify(tilePos.up(queryPos), Blocks.AIR);
+                    world.setBlockTypeNotify(upperPos, Blocks.AIR);
                 }
             }
             if (!hasCommittedSuicide && block.isSignalSource()) {
-                final boolean hasSignal = world.hasNeighborSignal(tilePos) || world.hasNeighborSignal(tilePos.up(queryPos));
+                final boolean hasSignal = world.hasNeighborSignal(tilePos) || world.hasNeighborSignal(upperPos);
                 this.onPoweredBlockChange(world, tilePos, hasSignal);
             }
         }
@@ -286,128 +299,89 @@ public class BlockLogicDoor
 
     @Override
     public boolean canPlaceAt(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        if (tilePos.y() >= world.getHeightBlocks() - 1) {
-            return false;
-        } else {
-            return this.isSupported(world, tilePos, world.getBlockData(tilePos)) && super.canPlaceAt(world, tilePos.up(new TilePos()));
-        }
+        return this.canPlaceAt(world, tilePos, world.getBlockData(tilePos));
     }
 
     public boolean canPlaceAt(final @NotNull World world, final @NotNull TilePosc tilePos, final int data) {
-        if (tilePos.y() >= world.getHeightBlocks() - 1) {
-            return false;
-        } else {
-            return this.isSupported(world, tilePos, data) && super.canPlaceAt(world, tilePos.up(new TilePos()));
-        }
+        if (this.isTop) return false;
+        final var topPos = tilePos.up(new TilePos());
+        if (!super.canPlaceAt(world, tilePos) || !super.canPlaceAt(world, topPos)) return false;
+        return this.isSupported(world, tilePos, data);
     }
 
+    // public boolean areBothSupported(final @NotNull World world, final @NotNull TilePosc bottomPos, final @NotNull TilePosc topPos, final int data) {
+    //     return
+    //         this.isSupported(world, bottomPos, data, true, true) &&
+    //         this.isSupported(world, topPos, data, false, true);
+    // }
+
     public boolean isSupported(final @NotNull World world, final @NotNull TilePosc tilePos, final int data) {
+        return this.isSupported(world, tilePos, data, true, true);
+    }
+
+    public boolean isSupported(
+        final @NotNull World world, final @NotNull TilePosc tilePos, final int data,
+        boolean checkBottom, boolean checkHinge
+    ) {
         if (this.isTop) return true;
-        TilePos queryPos = new TilePos();
-        final @NotNull ISupport sBelow = world.getSupport(tilePos.down(queryPos), Side.TOP);
-        final boolean opened = (data & MASK_OPENED) != 0;
+        final var queryPos = new TilePos();
         final boolean hinge = (data & MASK_HINGE) != 0;
-        final @NotNull Side side;
-        final @NotNull ISupport hingeSupport;
-        if (opened) {
-            if (hinge) {
-                switch (this.getRotation(data)) {
-                    case 0: {
-                        side = Side.WEST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
-                    case 1: {
-                        side = Side.NORTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
-                    case 2: {
-                        side = Side.EAST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
-                    case 3: {
-                        side = Side.SOUTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
-
-                }
-            } else {
-                switch (this.getRotation(data)) {
-                    case 0: {
-                        side = Side.NORTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                    case 1: {
-                        side = Side.EAST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                    case 2: {
-                        side = Side.SOUTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                    case 3: {
-                        side = Side.WEST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                }
+        final @NotNull ISupport bottomSupport = world.getSupport(tilePos.down(queryPos), Side.TOP);
+        final int rotation = this.getRotation(data);
+
+        if (checkHinge) {
+            final @NotNull Side side; {
+                final int offset = switch (data & (MASK_OPENED | MASK_HINGE)) {
+                    default -> 0;
+                    case MASK_OPENED | MASK_HINGE -> 0;
+                    case MASK_OPENED, MASK_HINGE -> 1;
+                    case 0 -> 2;
+                };
+                final int sideRotation = (rotation + offset) & MASK_ROTATION;
+                side = switch (sideRotation) {
+                    default -> Side.NONE;
+                    case 0 -> Side.WEST;
+                    case 1 -> Side.NORTH;
+                    case 2 -> Side.EAST;
+                    case 3 -> Side.SOUTH;
+                };
             }
-        } else {
-            if (hinge) {
-                switch (this.getRotation(data)) {
-                    case 0: {
-                        side = Side.NORTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
-                    case 1: {
-                        side = Side.EAST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
-                    case 2: {
-                        side = Side.SOUTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
-                    case 3: {
-                        side = Side.WEST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.right(), side);
-                    }
+            assert side != Side.NONE;
+    
+            final @NotNull ISupport hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
+            final @NotNull ISupport hingeSupported = (hinge)
+                ? PartialSupport.INSTANCE.left()
+                : PartialSupport.INSTANCE.right();
+    
+            if (hingeSupport.canSupport(hingeSupported, side)) return true;
+        }
 
-                }
-            } else {
-                switch (this.getRotation(data)) {
-                    case 0: {
-                        side = Side.EAST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                    case 1: {
-                        side = Side.SOUTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.up(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                    case 2: {
-                        side = Side.WEST;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.right(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                    case 3: {
-                        side = Side.NORTH;
-                        hingeSupport = world.getSupport(tilePos.add(side.direction(), queryPos), side.opposite());
-                        return sBelow.canSupport(PartialSupport.INSTANCE.left(), Side.BOTTOM) || sBelow.canSupport(PartialSupport.INSTANCE.down(), Side.BOTTOM) || hingeSupport.canSupport(PartialSupport.INSTANCE.left(), side);
-                    }
-                }
-            }
+        if (checkBottom) {
+            final @NotNull ISupport bottomSupportedA = switch(rotation) {
+                default -> null;
+                case 0 -> PartialSupport.INSTANCE.up();
+                case 1 -> PartialSupport.INSTANCE.right();
+                case 2 -> PartialSupport.INSTANCE.down();
+                case 3 -> PartialSupport.INSTANCE.left();
+            };
+            assert bottomSupportedA != null;
+    
+            final int bottomBRotation = (hinge)
+                ? rotation
+                : (rotation + 2) & MASK_ROTATION;
+            final @NotNull ISupport bottomSupportedB = switch (bottomBRotation) {
+                default -> null;
+                case 0 -> PartialSupport.INSTANCE.right();
+                case 1 -> PartialSupport.INSTANCE.down();
+                case 2 -> PartialSupport.INSTANCE.left();
+                case 3 -> PartialSupport.INSTANCE.up();
+            };
+            assert bottomSupportedB != null;
+
+            if (bottomSupport.canSupport(bottomSupportedA, Side.BOTTOM) ||
+                bottomSupport.canSupport(bottomSupportedB, Side.BOTTOM)) return true;
         }
+
         return false;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFarmland.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFarmland.java
index 8b3c7b905..237696e82 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFarmland.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFarmland.java
@@ -211,16 +211,6 @@ public class BlockLogicFarmland
         return true;
     }
 
-    @Override
-    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
-        final @Nullable Block<?> bBlock = world.getBlockType(thatPos);
-
-        final int thisMeta = world.getBlockData(thisPos);
-        final int otherMeta = world.getBlockData(thatPos);
-
-        return this.block == bBlock && isWet(thisMeta) == isWet(otherMeta);
-    }
-
     @Override
     public void updateTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand, final boolean isRandomTick) {
         if (rand.nextInt(2) != 0) {
@@ -254,4 +244,10 @@ public class BlockLogicFarmland
 
         return false;
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        if ((data & MASK_WET) != 0) data |= MASK_WET;
+        return data;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java
index 315461b50..4525dde8e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFence.java
@@ -18,6 +18,7 @@ import org.joml.primitives.AABBdc;
 
 import java.util.List;
 
+// TODO: metadata dependent connectors
 public class BlockLogicFence
     extends BlockLogic
     implements IPaintable {
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java
index 6a6f1d6de..11dad2ba7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGate.java
@@ -34,7 +34,8 @@ public class BlockLogicFenceGate
 
     @Override
     protected int getMatcherEquivalenceData(final int data) {
-        return data & ~MASK_DIRECTION;
+        assert (data & (MASK_POWERED | MASK_OPEN)) != MASK_POWERED : "fence gate should be opened when powered";
+        return data & ~(MASK_DIRECTION | MASK_POWERED);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFire.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFire.java
index 53b5267a0..790404ddc 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFire.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFire.java
@@ -397,4 +397,9 @@ public class BlockLogicFire
     public void onEntityCollision(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Entity entity) {
         entity.activeFireBlock = this.block;
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        return 0;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlag.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlag.java
index f6372241c..a6f8badc5 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlag.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlag.java
@@ -15,6 +15,9 @@ import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.pos.TilePosc;
+
+import java.util.Arrays;
+
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.joml.primitives.AABBdc;
@@ -84,4 +87,30 @@ public class BlockLogicFlag extends BlockLogic {
     public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) {
         return Material.PISTON_DESTROY_ON_PUSH;
     }
+
+    // TODO: pure color comparison instead of dye index comparison
+    @Override
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        if (world.getBlockType(thatPos) != this.block) return false;
+        if (!(world.getTileEntity(thisPos) instanceof TileEntityFlag thisFlag) ||
+            !(world.getTileEntity(thatPos) instanceof TileEntityFlag thatFlag))
+            return false;
+        if (thisFlag.colorHash != thatFlag.colorHash) return false;
+        if (thisFlag.colorHash != ~0) {
+            if (thisFlag.flipped != thatFlag.flipped) return false;
+            if (thisFlag.activeDyes != thatFlag.activeDyes) return false;
+            return Arrays.equals(thisFlag.flagColors, thatFlag.flagColors);
+        } else {
+            assert thatFlag.colorHash == ~0;
+            if (!Arrays.equals(thisFlag.flagColors, thatFlag.flagColors)) return false;
+
+            interface ctx { byte[] EMPTY_FLAG_COLORS = new byte[TileEntityFlag.CANVAS_WIDTH * TileEntityFlag.CANVAS_HEIGHT]; }
+            if (Arrays.equals(thisFlag.flagColors, ctx.EMPTY_FLAG_COLORS)) {
+                assert Arrays.equals(thatFlag.flagColors, ctx.EMPTY_FLAG_COLORS);
+                return true;
+            }
+            return false;
+        }
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java
index 378ebe4f0..340eaa8f8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFlower.java
@@ -74,7 +74,7 @@ public class BlockLogicFlower
     public void updateTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand, final boolean isRandomTick) {
         this.checkAlive(world, tilePos);
 
-        if (world.getGameRuleValue(GameRules.DO_SEASONAL_GROWTH) && world.getSeasonManager().getCurrentSeason() != null && (!isPermanent(world.getBlockData(tilePos))) && world.getSeasonManager().getCurrentSeason().killFlowers && this.killedByWeather && rand.nextInt(256) == 0) {
+        if (this.killedByWeather && world.getGameRuleValue(GameRules.DO_SEASONAL_GROWTH) && world.getSeasonManager().getCurrentSeason() != null && (!isPermanent(world.getBlockData(tilePos))) && world.getSeasonManager().getCurrentSeason().killFlowers && rand.nextInt(256) == 0) {
             world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
@@ -159,4 +159,9 @@ public class BlockLogicFlower
         }
         return this.canBeBonemealed;
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        return data & ~((this.killedByWeather) ? MASK_PERMANENT : 0);
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
index ebabd1f2f..f969d4b79 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
@@ -238,17 +238,8 @@ public abstract class BlockLogicFluid extends BlockLogic {
     }
 
     @Override
-    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
-        final Block<?> bBlock = world.getBlockType(thatPos);
-
-        final int thisMeta = world.getBlockData(thisPos);
-        final int otherMeta = world.getBlockData(thatPos);
-
-        if (Block.hasLogicClass(bBlock, BlockLogicFluid.class)) {
-            return this.material == bBlock.getMaterial() && thisMeta == otherMeta;
-        }
-
-        return false;
+    protected boolean isSameBlockForMatcher(@NotNull Block<?> other) {
+        return other.getLogic() instanceof BlockLogicFluid fluid && fluid.material == this.material;
     }
 
     public static boolean isStillEquivalentToFlowing(Block<?> block1, Block<?> block2) {
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidStill.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidStill.java
index 67f80c927..e4ebf706e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidStill.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidStill.java
@@ -27,11 +27,9 @@ public class BlockLogicFluidStill extends BlockLogicFluid {
 
     private void setFlowing(@NotNull World world, @NotNull TilePosc tilePos) {
         int meta = world.getBlockData(tilePos);
-        world.noNeighborUpdate = true;
         world.setBlockTypeData(tilePos, this.blockFlowing, meta);
         world.markBlocksDirty(tilePos, tilePos);
         world.scheduleBlockUpdate(tilePos, this.blockFlowing, tickDelay(world, tilePos));
-        world.noNeighborUpdate = false;
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java
index 3045ada08..4e6b54adb 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrowthRubyglass.java
@@ -63,7 +63,7 @@ public class BlockLogicGrowthRubyglass extends BlockLogic {
 		if (shape == STATE_BOTTOM) {
 			TilePos topPos = pos.add(dir, new TilePos());
 			int topMeta = world.getBlockData(topPos);
-			if (world.getBlockType(topPos) != this.block || (topMeta & SHAPE_MASK) != STATE_TOP) {
+			if ((topMeta & SHAPE_MASK) != STATE_TOP) {
 				world.setBlockTypeDataNotify(pos, this.block, STATE_BUD | dir.id);
 			}
 		}
@@ -123,6 +123,7 @@ public class BlockLogicGrowthRubyglass extends BlockLogic {
 		return false;
 	}
 
+	// TODO refactor this freak
 	@Override
 	public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
 		TilePos clickedAnchor = tilePos.add(side.direction().opposite(), new TilePos());
@@ -134,26 +135,25 @@ public class BlockLogicGrowthRubyglass extends BlockLogic {
 				TilePos growthPos = clickedAnchor.add(budDir, new TilePos());
 
 				if (!tilePos.equals(growthPos) && world.getBlockType(growthPos) == Blocks.AIR) {
-					world.setBlockTypeNotify(tilePos, Blocks.AIR);
-					world.setBlockData(clickedAnchor, STATE_BOTTOM | (data & DIRECTION_MASK));
-					world.markBlockNeedsUpdate(clickedAnchor);
-					world.setBlockTypeDataNotify(growthPos, this.block, STATE_TOP | (data & DIRECTION_MASK));
-					return;
-				}
-				else if (tilePos.equals(growthPos)) {
-					world.setBlockData(clickedAnchor, STATE_BOTTOM | (data & DIRECTION_MASK));
-					world.markBlockNeedsUpdate(clickedAnchor);
-					world.setBlockTypeDataNotify(tilePos, this.block, STATE_TOP | (data & DIRECTION_MASK));
-					return;
+					world.setBlockType(tilePos, Blocks.AIR);
+					world.markBlockNeedsUpdate(tilePos);
 				}
+				world.setBlockData(clickedAnchor, STATE_BOTTOM | (data & DIRECTION_MASK));
+				world.setBlockTypeData(growthPos, this.block, STATE_TOP | (data & DIRECTION_MASK));
+				world.markBlockNeedsUpdate(clickedAnchor);
+				world.markBlockNeedsUpdate(growthPos);
+				world.notifyBlocksInCapsuleOfNeighborChange(budDir, clickedAnchor, this.block);
+				return;
 			}
 		}
 
+		// TODO this is redundant
 		if (world.isBlockNormalCube(clickedAnchor)) {
 			world.setBlockTypeDataNotify(tilePos, this.block, STATE_BUD | side.direction().id);
 			return;
 		}
 
+		// TODO this is unreachable apparantly
 		for (Side fallback : Side.values()) {
 			TilePos fallbackAnchor = tilePos.add(fallback.direction.opposite(), new TilePos());
 			if (world.isBlockNormalCube(fallbackAnchor)) {
@@ -224,4 +224,9 @@ public class BlockLogicGrowthRubyglass extends BlockLogic {
         }
         return null;
     }
+
+	@Override
+	protected int getMatcherEquivalenceData(int data) {
+		return data & ~DIRECTION_MASK;
+	}
 }
\ No newline at end of file
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java
index 44a97bf18..5cba540b4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJarButterfly.java
@@ -150,4 +150,14 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable {
     public @NotNull ISupport getSupportConstraint(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) {
         return side.isVertical() ? PartialSupport.INSTANCE.center() : PartialSupport.INSTANCE;
     }
+
+    @Override
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        if (world.getBlockType(thatPos) != this.block) return false;
+        if (!(world.getTileEntity(thisPos) instanceof TileEntityJarButterfly thisJar) ||
+            !(world.getTileEntity(thatPos) instanceof TileEntityJarButterfly thatJar))
+            return false;
+        return thisJar.color.id() == thatJar.color.id();
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJukebox.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJukebox.java
index d21de68de..b33ba3f0a 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJukebox.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJukebox.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.block;
 
 import net.minecraft.core.block.entity.TileEntityActivator;
-import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.entity.TileEntityJukebox;
 import net.minecraft.core.block.material.Materials;
 import net.minecraft.core.entity.player.Player;
@@ -50,4 +49,21 @@ public class BlockLogicJukebox extends BlockLogic {
             jukebox.dropContents(world, tilePos.x(), tilePos.y(), tilePos.z());
         }
     }
+
+    @Override
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        if (world.getBlockType(thatPos) != this.block) return false;
+        final int thisData, thatData; {
+            thisData = world.getBlockData(thisPos);
+            thatData = world.getBlockData(thatPos);
+        }
+        if (thisData != thatData) return false;
+        if ((thisData | thatData) == 0) return true;
+
+        if (!(world.getTileEntity(thisPos) instanceof TileEntityJukebox thisJukebox) ||
+            !(world.getTileEntity(thatPos) instanceof TileEntityJukebox thatJukebox))
+            return false;
+        return thisJukebox.record == thatJukebox.record;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java
index fb83841cb..1c6969c32 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLadder.java
@@ -82,9 +82,7 @@ public class BlockLogicLadder extends BlockLogic implements ISupportable {
 
     public @Nullable Side getSideForPlacement(@NotNull World world, @NotNull TilePos tilePos, @NotNull Side clickedSide) {
         TilePosc p = tilePos;
-        if (!world.canPlaceInsideBlock(tilePos)) {
-            p = p.add(clickedSide.direction(), new TilePos());
-        }
+        if (!world.canPlaceInsideBlock(tilePos)) return null;
 
         if (canExistAt(world, p, getMetaForSide(clickedSide))) return clickedSide;
         if (canExistAt(world, p, getMetaForSide(Side.NORTH))) return Side.NORTH;
@@ -97,6 +95,7 @@ public class BlockLogicLadder extends BlockLogic implements ISupportable {
 
     public boolean canExistAt(@NotNull World world, @NotNull TilePosc tilePos, int meta) {
         Side side = getSideFromMeta(meta).opposite();
+        if (!side.isHorizontal()) return false;
         return isSupported(world, tilePos, side);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java
index c401bb588..8df6d9034 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerLeaves.java
@@ -84,4 +84,9 @@ public class BlockLogicLayerLeaves extends BlockLogicLayerSupportable {
             return meta & ~MASK_PERMANENT;
         }
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        return super.getMatcherEquivalenceData(data) & ~MASK_PERMANENT;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesBase.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesBase.java
index cb11548b1..df0b4cd1a 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesBase.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesBase.java
@@ -203,12 +203,7 @@ public class BlockLogicLeavesBase extends BlockLogic {
     }
 
     @Override
-    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
-        Block<?> bBlock = world.getBlockType(thatPos);
-
-        int thisMeta = world.getBlockData(thisPos) & ~MASK_DECAY_DATA;
-        int otherMeta = world.getBlockData(thatPos) & ~MASK_DECAY_DATA;
-
-        return this.block == bBlock && thisMeta == otherMeta;
+    protected int getMatcherEquivalenceData(int data) {
+        return data & ~MASK_DECAY_DATA;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java
index 8c0b4510f..00d53ac83 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMatcher.java
@@ -10,7 +10,6 @@ import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.enums.PlacementMode;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.LevelListener;
 import net.minecraft.core.world.World;
@@ -22,7 +21,6 @@ import org.jetbrains.annotations.Nullable;
 
 import java.util.Random;
 
-import static net.minecraft.core.block.BlockLogicFarmland.isWet;
 import static net.minecraft.core.block.BlockLogicConduit.packEventConduitData;
 
 public class BlockLogicMatcher extends BlockLogicAxisAligned {
@@ -35,12 +33,7 @@ public class BlockLogicMatcher extends BlockLogicAxisAligned {
 
     @Override
     protected boolean isSameBlockForMatcher(final @NotNull Block<?> other) {
-        return other.getLogic() instanceof BlockLogicMatcher;
-    }
-
-    @Override
-    protected int getMatcherEquivalenceData(final int data) {
-        return this.isActive ? 1 : 0;
+        return other.getLogic() instanceof BlockLogicMatcher matcher && (this.isActive == matcher.isActive);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java
index 6b3582219..6f1777a07 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java
@@ -100,4 +100,20 @@ public class BlockLogicMobSpawner extends BlockLogicMobSpawnerDeactivated {
     public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) {
         return Material.PISTON_CANT_PUSH;
     }
+
+    @Override
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        if (world.getBlockType(thatPos) != this.block) return false;
+        if (!(world.getTileEntity(thisPos) instanceof TileEntityMobSpawner thisSpawner) ||
+            !(world.getTileEntity(thatPos) instanceof TileEntityMobSpawner thatSpawner))
+            return false;
+        final @Nullable String thisId, thatId; {
+            thisId = thisSpawner.getMobId();
+            thatId = thatSpawner.getMobId();
+        }
+        if (thisId == thatId) return true;
+        if (thisId == null || thatId == null) return false;
+        return thisId.equals(thatId);
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java
index 44aa5147c..83a4f2f06 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java
@@ -26,8 +26,22 @@ public class BlockLogicNote extends BlockLogic {
     public static final int MASK_POWERED = 0b1000_0000;
 
     @Override
-    protected int getMatcherEquivalenceData(final int data) {
-        return data & MASK_POWERED;
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        if (world.getBlockType(thatPos) != this.block) return false;
+        final int thisData, thatData; {
+            thisData = world.getBlockData(thisPos);
+            thatData = world.getBlockData(thatPos);
+        }
+        if (thisData != thatData) return false; // We check note as well because it sucks otherwise
+        // // TODO instrument update
+        // final @NotNull Instrument thisInstru, thatInstru; {
+        //     final var query = new TilePos();
+        //     thisInstru = Instrument.getInstrumentFromBlock(world.getBlockType(thisPos.down(query)));
+        //     thatInstru = Instrument.getInstrumentFromBlock(world.getBlockType(thatPos.down(query)));
+        // }
+        // if (thisInstru != thatInstru) return false; // reference eq
+        return true;
     }
 
     public static final byte MAX_NOTE = 24;
@@ -37,7 +51,6 @@ public class BlockLogicNote extends BlockLogic {
         block.withEntity(null);
     }
 
-
     @Override
     public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final int data = world.getBlockData(tilePos);
@@ -46,6 +59,7 @@ public class BlockLogicNote extends BlockLogic {
         if (isPowered == hasSignal) return;
         world.setBlockData(tilePos, data ^ MASK_POWERED);
         if (hasSignal) triggerNote(world, tilePos);
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
     }
 
     @Override
@@ -76,6 +90,7 @@ public class BlockLogicNote extends BlockLogic {
         if (isPowered == hasSignal) return;
         world.setBlockData(tilePos, data ^ MASK_POWERED);
         if (hasSignal) triggerNote(world, tilePos);
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
     }
 
     @Override
@@ -88,6 +103,7 @@ public class BlockLogicNote extends BlockLogic {
         if (!world.isClientSide) {
             changePitch(world, tilePos, player.isSneaking() ? -1 : 1);
             triggerNote(world, tilePos);
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
         }
         return true;
     }
@@ -96,6 +112,7 @@ public class BlockLogicNote extends BlockLogic {
     public void onActivatorInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull TileEntityActivator activator, @NotNull Direction direction) {
         changePitch(world, tilePos, 1);
         triggerNote(world, tilePos);
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java
index cca4f6fe7..cb789a486 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java
@@ -39,15 +39,27 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
     }
 
     @Override
-    protected int getMatcherEquivalenceData(final int data) {
-        if (this.isPowered) {
-            return data & MASK_POWERED;
+    protected int getMatcherEquivalenceData(int data) {
+        final int dirMask = (this.isPowered) ? MASK_DIRECTION : MASK_DIRECTION | MASK_POWERED;
+        var railDir = RailDirection.getFromMeta(data & dirMask);
+        if (railDir.isStraight()) {
+            railDir = RailDirection.STRAIGHT_NS;
+        } else if (railDir.isSloped()) {
+            railDir = RailDirection.SLOPE_E;
+        } else if (railDir.isCurved()) {
+            assert !this.isPowered;
+            railDir = RailDirection.TURN_ES;
         }
+        data &= ~MASK_DIRECTION;
+        data |= railDir.meta & dirMask;
         return data;
     }
 
     public @NotNull RailDirection getRailDirection(@NotNull WorldSource world, @NotNull TilePosc tilePos) {
-        int meta = world.getBlockData(tilePos);
+        return getRailDirection(world.getBlockData(tilePos));
+    }
+
+    public @NotNull RailDirection getRailDirection(int meta) {
         if (this.isPowered) {
             meta &= MASK_DIRECTION;
         }
@@ -95,10 +107,11 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
 
     @Override
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
-        world.noNeighborUpdate = true; // TODO: this should just be a temporary solution. refactor rails later!
         performRailTurn(world, tilePos, true);
-        world.noNeighborUpdate = false;
         if (this.block == Blocks.RAIL_POWERED) {
+            // TODO: this should just be a temporary solution. refactor rails later!
+            // even hackier than before
+            if (world.getBlockType(tilePos) != this.block) return;
             onNeighborChanged(world, tilePos, this.block);
         }
     }
@@ -110,7 +123,7 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
         }
         int meta = world.getBlockData(tilePos);
         boolean isPoweredFlagSet = (meta & MASK_POWERED) != 0;
-        RailDirection railDirection = getRailDirection(world, tilePos);
+        RailDirection railDirection = getRailDirection(meta);
 
         if (!isSupported(world, tilePos, Side.BOTTOM)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
@@ -143,16 +156,12 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
                     isConnectedPoweredRail1(world, tilePos, false, 0);
 
             boolean changedMeta = false;
-            if (gettingPower && !isPoweredFlagSet) {
-                // Set powered bit
-                world.setBlockData(tilePos, railDirection.meta | MASK_POWERED);
-                changedMeta = true;
-            } else if (!gettingPower && isPoweredFlagSet) {
-                // Remove powered bit
-                world.setBlockData(tilePos, railDirection.meta);
+            if (gettingPower != isPoweredFlagSet) {
+                world.setBlockData(tilePos, (gettingPower) 
+                    ? railDirection.meta | MASK_POWERED
+                    : railDirection.meta);
                 changedMeta = true;
             }
-
             world.markBlockNeedsUpdate(tilePos);
 
             if (changedMeta) {
@@ -166,7 +175,7 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
                     }, this.block);
                 }
             }
-        } else if (block != null && block.isSignalSource() && new Rail(world, tilePos).getAdjacentTracks() == 3) {
+        } else if (block.isSignalSource() && new Rail(world, tilePos).getAdjacentTracks() == 3) {
             performRailTurn(world, tilePos, false);
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java
index caf9c3020..3accdf548 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRepeater.java
@@ -47,12 +47,12 @@ public class BlockLogicRepeater extends BlockLogic implements ISupportable {
 
     @Override
     protected boolean isSameBlockForMatcher(final @NotNull Block<?> other) {
-        return other.getLogic() instanceof BlockLogicRepeater;
+        return other.getLogic() instanceof BlockLogicRepeater repeater && (this.isRepeaterPowered == repeater.isRepeaterPowered);
     }
 
     @Override
     protected int getMatcherEquivalenceData(final int data) {
-        return (this.isRepeaterPowered ? 0x10 : 0) | (data & MASK_TICK_DELAY);
+        return data & MASK_TICK_DELAY;
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRope.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRope.java
index 47bae33bc..ffd78e7c0 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRope.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRope.java
@@ -86,7 +86,8 @@ public class BlockLogicRope
         if (heldItem != null && heldItem.getItem() instanceof ItemToolShears) {
             int meta = world.getBlockData(tilePos);
             int forceRope = (~meta) & MASK_ROPE_CONNECT;
-            world.setBlockDataNotify(tilePos, forceRope | (meta & ~MASK_ROPE_CONNECT));
+            world.setBlockData(tilePos, forceRope | (meta & ~MASK_ROPE_CONNECT));
+            world.markBlockNeedsUpdate(tilePos);
             heldItem.damageItem(1, player);
             if (heldItem.stackSize <= 0) {
                 player.destroyCurrentEquippedItem();
@@ -160,4 +161,10 @@ public class BlockLogicRope
     public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) {
         return new ItemStack[]{new ItemStack(Items.ROPE)};
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        // return data & ~MASK_ROPE_CONNECT;
+        return 0;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBase.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBase.java
index ec896c299..204c5b483 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBase.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBase.java
@@ -49,7 +49,7 @@ public abstract class BlockLogicSaplingBase extends BlockLogicFlower implements
         if (world.getBlockLightValue(tilePos.up(queryPos)) >= 9 && rand.nextInt(growthRate) == 0) {
             int l = world.getBlockData(tilePos);
             if ((l & 8) == 0) {
-                world.setBlockDataNotify(tilePos, l | 8);
+                world.setBlockData(tilePos, l | 8);
             } else {
                 growTree(world, tilePos, rand);
             }
@@ -68,4 +68,9 @@ public abstract class BlockLogicSaplingBase extends BlockLogicFlower implements
     }
 
     public abstract void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random);
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        return 0;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java
index 6b4afe098..55b145a16 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSign.java
@@ -41,16 +41,33 @@ public class BlockLogicSign extends BlockLogic implements IPaintable {
     }
 
     @Override
-    protected boolean isSameBlockForMatcher(final @NotNull Block<?> other) {
-        if (!(other.getLogic() instanceof BlockLogicSign otherSign)) {
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        if (world.getBlockType(thatPos) != this.block) return false;
+        if (((world.getBlockData(thisPos) ^ world.getBlockData(thatPos)) & ~MASK_SIDE) != 0) return false;
+        if (!(world.getTileEntity(thisPos) instanceof TileEntitySign thisSign) ||
+            !(world.getTileEntity(thatPos) instanceof TileEntitySign thatSign))
             return false;
+        if (thisSign.getPicture() != thatSign.getPicture()) return false;
+
+        boolean isAllBlank = true;
+        assert thisSign.signText.length == 4 && thatSign.signText.length == 4;
+        for (int i = 0; i < 4; i++) {
+            final boolean thisIsBlank, thatIsBlank; {
+                thisIsBlank = thisSign.signText[i].isEmpty() || thisSign.signText[i].isBlank();
+                thatIsBlank = thatSign.signText[i].isEmpty() || thatSign.signText[i].isBlank();
+            }
+            if (thisIsBlank != thatIsBlank) return false;
+            if (!thisIsBlank) isAllBlank = false;
         }
-        return otherSign.isFreeStanding == this.isFreeStanding;
-    }
+        if (isAllBlank) return true;
 
-    @Override
-    protected int getMatcherEquivalenceData(final int data) {
-        return 0;
+        if (thisSign.getColor() != thatSign.getColor()) return false;
+        if (thisSign.isGlowing() != thatSign.isGlowing()) return false;
+        for (int i = 0; i < 4; i++) {
+            if (!thisSign.signText[i].equals(thatSign.signText[i])) return false;
+        }
+        return true;
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java
index 3995f8013..42addc6c8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStatue.java
@@ -263,4 +263,26 @@ public class BlockLogicStatue extends BlockLogic {
         return Material.PISTON_DESTROY_ON_PUSH;
     }
 
+    @Override
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        assert world.getBlockType(thisPos) == this.block;
+        final var thatBlock = world.getBlockType(thatPos);
+        if (thatBlock != this.block) return false;
+        final var that = (BlockLogicStatue) thatBlock.getLogic();
+
+        final var query = new TilePos();
+        if (!(world.getTileEntity(this.isBottom ? thisPos : thisPos.down(query)) instanceof TileEntityStatue thisStatue) ||
+            !(world.getTileEntity(that.isBottom ? thatPos : thatPos.down(query)) instanceof TileEntityStatue thatStatue))
+            return false;
+        
+        if (thisStatue.getPose() != thatStatue.getPose()) return false;
+        
+        // we assume (but not assert) all stacks to be of size 1
+        // TODO: Item.isEquivalent(ItemStack)
+        if (!ItemStack.areItemsEqual(thisStatue.getHeldItem(), thatStatue.getHeldItem())) return false;
+        for (final var slot : HumanArmorShape.values()) {
+            if (!ItemStack.areItemsEqual(thisStatue.getItemInArmorSlot(slot), thatStatue.getItemInArmorSlot(slot))) return false;
+        }
+        return true;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSugarcane.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSugarcane.java
index 6358240cf..8af566e81 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSugarcane.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSugarcane.java
@@ -43,11 +43,10 @@ public class BlockLogicSugarcane extends BlockLogic implements IBonemealable {
             }
 
             int data = world.getBlockData(tilePos);
-            if (data >= 15) {
+            data = (data + 1) & 0xF;
+            world.setBlockData(tilePos, data);
+            if (data == 0) {
                 world.setBlockTypeNotify(up, this.block);
-                world.setBlockDataNotify(tilePos, 0);
-            } else {
-                world.setBlockDataNotify(tilePos, data + 1);
             }
         }
     }
@@ -132,4 +131,9 @@ public class BlockLogicSugarcane extends BlockLogic implements IBonemealable {
         }
         return true;
     }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        return 0;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java
index eb4e1250f..ce20f709a 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicThermalVent.java
@@ -26,6 +26,7 @@ public class BlockLogicThermalVent extends BlockLogic {
 
     @Override
     public void animationTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand) {
+        if (world.isClientSide) return;
         final int state = getVentState(world.getBlockData(tilePos));
 
         final double xPos = (double) tilePos.x() + 0.5D;
@@ -58,26 +59,32 @@ public class BlockLogicThermalVent extends BlockLogic {
     }
 
     @Override
-    public boolean isEquivalent(final @NotNull World world, final @NotNull TilePosc thisPos, final @NotNull TilePosc thatPos) {
-        return Block.hasLogicClass(world.getBlockType(thatPos), BlockLogicThermalVent.class);
+    protected boolean isSameBlockForMatcher(@NotNull Block<?> other) {
+        return Block.hasLogicClass(other, BlockLogicThermalVent.class);
+    }
+
+    @Override
+    protected int getMatcherEquivalenceData(int data) {
+        return 0;
     }
 
     @Override
     public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!hasVentBelow(world, tilePos) && getVentState(world.getBlockData(tilePos)) != DORMANT_STATE) {
-            world.setBlockDataNotify(tilePos, DORMANT_STATE);
+            world.setBlockData(tilePos, DORMANT_STATE);
         }
     }
 
     @Override
     public void updateTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand, final boolean isRandomTick) {
+        if (world.isClientSide) return;
         if (world.getBlockType(tilePos.up(new TilePos())).solid()) {
             return;
         }
 
         if (!hasVentBelow(world, tilePos)) {
             if (getVentState(world.getBlockData(tilePos)) != DORMANT_STATE) {
-                world.setBlockDataNotify(tilePos, DORMANT_STATE);
+                world.setBlockData(tilePos, DORMANT_STATE);
             }
             return;
         }
@@ -87,7 +94,7 @@ public class BlockLogicThermalVent extends BlockLogic {
             if (state < VENTING_STATE) {
                 final int buildUpRate = getBuildupRate(world, tilePos, rand);
                 state += buildUpRate;
-                world.setBlockDataNotify(tilePos, state);
+                world.setBlockData(tilePos, state);
             } else {
                 vent(world, tilePos, rand);
             }
@@ -129,12 +136,12 @@ public class BlockLogicThermalVent extends BlockLogic {
         if (!world.isClientSide) {
             alertNearbyPlayers(world, tilePos);
 
-            final List<Entity> entities = world.getEntitiesWithinAABB(Entity.class, new AABBd(tilePos.x() - 1, tilePos.y(), tilePos.z() - 1, tilePos.x() + 1, tilePos.y() + 6, tilePos.z() + 1));
+            final List<Entity> entities = world.getEntitiesWithinAABB(Entity.class, new AABBd(tilePos.x() - 1, tilePos.y(), tilePos.z() - 1, tilePos.x() + 2, tilePos.y() + 7, tilePos.z() + 2));
             for (final @NotNull Entity entity : entities) {
                 entity.fling(0, 2, 0, 1f);
             }
 
-            world.setBlockDataNotify(tilePos, DORMANT_STATE);
+            world.setBlockData(tilePos, DORMANT_STATE);
         }
     }
 
@@ -143,7 +150,7 @@ public class BlockLogicThermalVent extends BlockLogic {
         super.onPlacedByWorld(world, tilePos);
 
         if (!world.isClientSide) {
-            world.setBlockDataNotify(tilePos, hasVentBelow(world, tilePos) ? world.rand.nextInt(VENTING_STATE) : DORMANT_STATE);
+            world.setBlockData(tilePos, hasVentBelow(world, tilePos) ? world.rand.nextInt(VENTING_STATE) : DORMANT_STATE);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java
index 9c14af673..64912292e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorchRedstone.java
@@ -23,12 +23,7 @@ public class BlockLogicTorchRedstone extends BlockLogicTorch {
 
     @Override
     protected boolean isSameBlockForMatcher(final @NotNull Block<?> other) {
-        return other.getLogic() instanceof BlockLogicTorchRedstone;
-    }
-
-    @Override
-    protected int getMatcherEquivalenceData(final int data) {
-        return this.torchActive ? 1 : 0;
+        return other.getLogic() instanceof BlockLogicTorchRedstone rtorch && rtorch.torchActive == this.torchActive;
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java
index eb0b6a71b..4fc8ef0c6 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoor.java
@@ -45,7 +45,8 @@ public class BlockLogicTrapDoor extends BlockLogic implements IPaintable {
 
     @Override
     protected int getMatcherEquivalenceData(final int data) {
-        return data & ~(MASK_DIRECTION | MASK_UPPER_HALF);
+        assert (MASK_OPEN << 1) == MASK_UPPER_HALF;
+        return data & ~(MASK_DIRECTION | ((data & MASK_OPEN) << 1));
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/Blocks.java b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
index 7d1b75589..adae62878 100644
--- a/game/core/src/main/java/net/minecraft/core/block/Blocks.java
+++ b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
@@ -39,7 +39,6 @@ public final class Blocks {
     public static final int[] lightBlock = new int[blocksList.length];
     public static final boolean[] translucent = new boolean[blocksList.length];
     public static final int[] lightEmission = new int[blocksList.length];
-    public static final boolean[] neighborNotifyOnMetadataChangeDisabled = new boolean[blocksList.length];
     public static int highestBlockId = 0;
 
     public static final @NotNull Block<?> AIR = register("air", "minecraft:block/air", 0, (b) -> new BlockLogicAir(b))
@@ -58,7 +57,7 @@ public final class Blocks {
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> MARBLE = register("marble", "minecraft:block/marble", 5, (b) -> new BlockLogic(b, Materials.MARBLE))
-        .withSound(BlockSounds.STONE).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.0F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> SLATE = register("slate", "minecraft:block/slate", 6, (b) -> new BlockLogic(b, Materials.SLATE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
@@ -96,10 +95,10 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.GROWS_FLOWERS);
 
     public static final @NotNull Block<?> PILLAR_MARBLE = register("pillar.marble", "minecraft:block/pillar_marble", 20, (b) -> new BlockLogicAxisAligned(b, Materials.MARBLE))
-        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> CAPSTONE_MARBLE = register("capstone.marble", "minecraft:block/capstone_marble", 21, (b) -> new BlockLogic(b, Materials.MARBLE))
-        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> SANDSTONE = register("sandstone", "minecraft:block/sandstone", 30, (b) -> new BlockLogicSandstone(b, Materials.STONE))
@@ -129,36 +128,36 @@ public final class Blocks {
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> PLANKS_OAK = register("planks.oak", "minecraft:block/planks_oak", 50, BlockLogicPlanks::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicPlanksPainted> PLANKS_OAK_PAINTED = register("planks.oak.painted", "minecraft:block/planks_oak_painted", 51, BlockLogicPlanksPainted::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, false))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> TORCH_COAL = register("torch.coal", "minecraft:block/torch_coal", 60, BlockLogicTorch::new)
-        .withSound(BlockSounds.WOOD).withHardness(0.0F).withLightEmission(0.9375F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(0.0F).withLightEmission(0.9375F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS);
 //    public static final BlockContainer<?> candleSoulwax;
 
     public static final @NotNull Block<? extends BlockLogicLadder> LADDER_OAK = register("ladder.oak", "minecraft:block/ladder_oak", 70, BlockLogicLadder::new)
-        .withSound(BlockSounds.WOOD).withHardness(0.4F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(0.4F)
         .setBlockItem(ItemBlockLadder::new)
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<BlockLogicFence> FENCE_PLANKS_OAK = register("fence.planks.oak", "minecraft:block/fence_planks_oak", 80, BlockLogicFence::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE, BlockTags.CAN_HANG_OFF);
     public static final @NotNull Block<BlockLogicFencePainted> FENCE_PLANKS_OAK_PAINTED = register("fence.planks.oak.painted", "minecraft:block/fence_planks_oak_painted", 81, BlockLogicFencePainted::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(5F)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, false))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE, BlockTags.CAN_HANG_OFF);
 
     public static final @NotNull Block<BlockLogicFenceGate> FENCE_GATE_PLANKS_OAK = register("fencegate.planks.oak", "minecraft:block/fence_gate_planks_oak", 90, BlockLogicFenceGate::new)
-        .withSound(BlockSounds.WOOD).withHardness(2F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2F).withBlastResistance(5F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicFenceGatePainted> FENCE_GATE_PLANKS_OAK_PAINTED = register("fencegate.planks.oak.painted", "minecraft:block/fence_gate_planks_oak_painted", 91, BlockLogicFenceGatePainted::new)
-        .withSound(BlockSounds.WOOD).withHardness(2F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2F).withBlastResistance(5F)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
@@ -167,11 +166,11 @@ public final class Blocks {
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> WOOL = register("wool", "minecraft:block/wool", 110, BlockLogicWool::new)
-        .withSound(BlockSounds.CLOTH).withHardness(0.8F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.CLOTH).withHardness(0.8F)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, false))
         .withTags(BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<BlockLogicRope> ROPE = register("rope", "minecraft:block/rope", 111, BlockLogicRope::new)
-        .withSound(BlockSounds.CLOTH).withHardness(0.01F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.ROPE)
+        .withSound(BlockSounds.CLOTH).withHardness(0.01F).setStatParent(() -> Items.ROPE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS, BlockTags.CAN_HANG_OFF, BlockTags.INSTANT_PICKUP);
 
     public static final @NotNull Block<?> BRICK_CLAY = register("brick.clay", "minecraft:block/brick_clay", 120, (b) -> new BlockLogic(b, Materials.STONE))
@@ -202,13 +201,13 @@ public final class Blocks {
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_MARBLE = register("brick.marble", "minecraft:block/brick_marble", 129, (b) -> new BlockLogic(b, Materials.MARBLE))
-        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_SLATE = register("brick.slate", "minecraft:block/brick_slate", 130, (b) -> new BlockLogic(b, Materials.SLATE))
-        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_STONE = register("brick.stone", "minecraft:block/brick_stone", 131, (b) -> new BlockLogic(b, Materials.STONE))
-        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BRICK_PERMAFROST = register("brick.permafrost", "minecraft:block/brick_permafrost", 132, (b) -> new BlockLogic(b, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(1.0F)
@@ -229,121 +228,121 @@ public final class Blocks {
 
 
     public static final @NotNull Block<BlockLogicSlab> SLAB_PLANKS_OAK = register("slab.planks.oak", "minecraft:block/slab_planks_oak", 140, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlabPaintable(b, Blocks.PLANKS_OAK))
-        .withSound(BlockSounds.WOOD).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.WOOD).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_COBBLE_STONE = register("slab.cobble.stone", "minecraft:block/slab_cobble_stone", 141, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_STONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_SANDSTONE = register("slab.sandstone", "minecraft:block/slab_sandstone", 142, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.SANDSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_STONE_POLISHED = register("slab.brick.stone.polished", "minecraft:block/slab_brick_stone_polished", 143, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_STONE_POLISHED))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_STONE_POLISHED = register("slab.stone.carved", "minecraft:block/slab_stone_carved", 144, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.STONE_CARVED))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_MARBLE = register("slab.brick.marble", "minecraft:block/slab_brick_marble", 145, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_MARBLE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_CLAY = register("slab.brick.clay", "minecraft:block/slab_brick_clay", 146, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_CLAY))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_CAPSTONE_MARBLE = register("slab.capstone.marble", "minecraft:block/slab_capstone_marble", 147, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.CAPSTONE_MARBLE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_COBBLE_BASALT = register("slab.cobble.basalt", "minecraft:block/slab_cobble_basalt", 148, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_BASALT))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_COBBLE_LIMESTONE = register("slab.cobble.limestone", "minecraft:block/slab_cobble_limestone", 149, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_LIMESTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_COBBLE_GRANITE = register("slab.cobble.granite", "minecraft:block/slab_cobble_granite", 150, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_GRANITE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_BASALT = register("slab.brick.basalt", "minecraft:block/slab_brick_basalt", 151, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_BASALT))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_LIMESTONE = register("slab.brick.limestone", "minecraft:block/slab_brick_limestone", 152, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_LIMESTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_GRANITE = register("slab.brick.granite", "minecraft:block/slab_brick_granite", 153, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_GRANITE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlabPainted> SLAB_PLANKS_PAINTED = register("slab.planks.oak.painted", "minecraft:block/slab_planks_oak_painted", 154, (BlockLogicSupplier<BlockLogicSlabPainted>) b -> new BlockLogicSlabPainted(b, Blocks.PLANKS_OAK_PAINTED))
-        .withSound(BlockSounds.WOOD).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.WOOD).withLitInteriorSurface(true)
         .setBlockItem(ItemBlockSlabPainted::new)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_SLATE = register("slab.brick.slate", "minecraft:block/slab_brick_slate", 155, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_SLATE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_STONE = register("slab.brick.stone", "minecraft:block/slab_brick_stone", 156, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_STONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_GRANITE_POLISHED = register("slab.granite.carved", "minecraft:block/slab_granite_carved", 157, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.GRANITE_CARVED))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_LIMESTONE_POLISHED = register("slab.limestone.carved", "minecraft:block/slab_limestone_carved", 158, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.LIMESTONE_CARVED))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BASALT_POLISHED = register("slab.basalt.carved", "minecraft:block/slab_basalt_carved", 159, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BASALT_CARVED))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicStairs> STAIRS_PLANKS_OAK = register("stairs.planks.oak", "minecraft:block/stairs_planks_oak", 160, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairsPaintable(b, Blocks.PLANKS_OAK))
-        .withSound(BlockSounds.WOOD).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.WOOD).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_COBBLE_STONE = register("stairs.cobble.stone", "minecraft:block/stairs_cobble_stone", 161, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_STONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_STONE_POLISHED = register("stairs.brick.stone.polished", "minecraft:block/stairs_brick_stone_polished", 162, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_STONE_POLISHED))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_MARBLE = register("stairs.brick.marble", "minecraft:block/stairs_brick_marble", 163, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_MARBLE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_COBBLE_BASALT = register("stairs.cobble.basalt", "minecraft:block/stairs_cobble_basalt", 164, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_BASALT))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_COBBLE_LIMESTONE = register("stairs.cobble.limestone", "minecraft:block/stairs_cobble_limestone", 165, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_LIMESTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_COBBLE_GRANITE = register("stairs.cobble.granite", "minecraft:block/stairs_cobble_granite", 166, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_GRANITE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_BASALT = register("stairs.brick.basalt", "minecraft:block/stairs_brick_basalt", 167, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_BASALT))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_LIMESTONE = register("stairs.brick.limestone", "minecraft:block/stairs_brick_limestone", 168, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_LIMESTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_GRANITE = register("stairs.brick.granite", "minecraft:block/stairs_brick_granite", 169, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_GRANITE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_CLAY = register("stairs.brick.clay", "minecraft:block/stairs_brick_clay", 170, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_CLAY))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairsPainted> STAIRS_PLANKS_PAINTED = register("stairs.planks.oak.painted", "minecraft:block/stairs_planks_oak_painted", 171, (BlockLogicSupplier<BlockLogicStairsPainted>) b -> new BlockLogicStairsPainted(b, Blocks.PLANKS_OAK_PAINTED))
-        .withSound(BlockSounds.WOOD).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.WOOD).withLitInteriorSurface(true)
         .setBlockItem(ItemBlockStairsPainted::new)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_SLATE = register("stairs.brick.slate", "minecraft:block/stairs_brick_slate", 172, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_SLATE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_STONE = register("stairs.brick.stone", "minecraft:block/stairs_brick_stone", 173, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_STONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_SANDSTONE = register("stairs.sandstone", "minecraft:block/stairs_sandstone", 174, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.SANDSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_SANDSTONE = register("stairs.brick.sandstone", "minecraft:block/stairs_brick_sandstone", 175, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_SANDSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_COBBLE_PERMAFROST = register("stairs.cobble.permafrost", "minecraft:block/stairs_cobble_permafrost", 176, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_PERMAFROST))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_PERMAFROST = register("stairs.brick.permafrost", "minecraft:block/stairs_brick_permafrost", 177, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_PERMAFROST))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> OBSIDIAN = register("obsidian", "minecraft:block/obsidian", 180, (b) -> new BlockLogicObsidian(b))
@@ -354,7 +353,7 @@ public final class Blocks {
         .withSound(BlockSounds.GLASS).withHardness(0.3F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.EXTENDS_MOTION_SENSOR_RANGE);
     public static final @NotNull Block<?> GLASS_TINTED = register("glass.tinted", "minecraft:block/glass_tinted", 191, BlockLogicGlassTinted::new)
-        .withSound(BlockSounds.GLASS).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GLASS).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> GLASS_STEEL = register("glass.steel", "minecraft:block/glass_steel", 192, (b) -> new BlockLogicGlassSteel(b, Materials.GLASS))
         .withSound(BlockSounds.GLASS).withHardness(0.3F).withBlastResistance(2000F)
@@ -433,109 +432,109 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.NETHER_MOBS_SPAWN);
 
     public static final @NotNull Block<BlockLogicFluid> FLUID_WATER_FLOWING = register("fluid.water.flowing", "minecraft:block/fluid_water_flowing", 270, (BlockLogicSupplier<BlockLogicFluid>) b -> new BlockLogicFluidFlowing(b, Materials.WATER, new FluidWater(), Blocks.FLUID_WATER_STILL))
-        .withHardness(100F).withLitInteriorSurface(true).withLightBlock(3).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
+        .withHardness(100F).withLitInteriorSurface(true).withLightBlock(3).withDisabledStats()
         .withTags(BlockTags.IS_WATER, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<BlockLogicFluid> FLUID_WATER_STILL = register("fluid.water.still", "minecraft:block/fluid_water_still", 271, (BlockLogicSupplier<BlockLogicFluid>) b -> new BlockLogicFluidStill(b, Materials.WATER, new FluidWater(), Blocks.FLUID_WATER_FLOWING))
-        .withHardness(100F).withLitInteriorSurface(true).withLightBlock(3).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats().setStatParent(() -> FLUID_WATER_FLOWING)
+        .withHardness(100F).withLitInteriorSurface(true).withLightBlock(3).withDisabledStats().setStatParent(() -> FLUID_WATER_FLOWING)
         .withTags(BlockTags.IS_WATER, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<BlockLogicFluid> FLUID_LAVA_FLOWING = register("fluid.lava.flowing", "minecraft:block/fluid_lava_flowing", 272, (BlockLogicSupplier<BlockLogicFluid>) b -> new BlockLogicFluidFlowing(b, Materials.LAVA, new FluidLava(), Blocks.FLUID_LAVA_STILL))
-        .withHardness(0.0F).withLitInteriorSurface(true).withLightEmission(1.0F).withLightBlock(255).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
+        .withHardness(0.0F).withLitInteriorSurface(true).withLightEmission(1.0F).withLightBlock(255).withDisabledStats()
         .withTags(BlockTags.IS_LAVA, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<BlockLogicFluid> FLUID_LAVA_STILL = register("fluid.lava.still", "minecraft:block/fluid_lava_still", 273, (BlockLogicSupplier<BlockLogicFluid>) b -> new BlockLogicFluidStill(b, Materials.LAVA, new FluidLava(), Blocks.FLUID_LAVA_FLOWING))
-        .withHardness(100F).withLitInteriorSurface(true).withLightEmission(1.0F).withLightBlock(255).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats().setStatParent(() -> FLUID_LAVA_FLOWING)
+        .withHardness(100F).withLitInteriorSurface(true).withLightEmission(1.0F).withLightBlock(255).withDisabledStats().setStatParent(() -> FLUID_LAVA_FLOWING)
         .withTags(BlockTags.IS_LAVA, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
 
     public static final @NotNull Block<?> LOG_OAK = register("log.oak", "minecraft:block/log_oak", 280, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> LOG_PINE = register("log.pine", "minecraft:block/log_pine", 281, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> LOG_BIRCH = register("log.birch", "minecraft:block/log_birch", 282, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> LOG_CHERRY = register("log.cherry", "minecraft:block/log_cherry", 283, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> LOG_EUCALYPTUS = register("log.eucalyptus", "minecraft:block/log_eucalyptus", 284, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> LOG_OAK_MOSSY = register("log.oak.mossy", "minecraft:block/log_oak_mossy", 285, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE, BlockTags.GROWS_FLOWERS);
     public static final @NotNull Block<?> LOG_THORN = register("log.thorn", "minecraft:block/log_thorn", 286, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> LOG_PALM = register("log.palm", "minecraft:block/log_palm", 287, BlockLogicLog::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> LOG_PETRIFIED = register("log.petrified", "minecraft:block/log_petrified", 288, b -> new BlockLogicAxisAligned(b, Materials.STONE))
-            .withSound(BlockSounds.STONE).withHardness(8.0F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.STONE).withHardness(8.0F)
             .withTags(BlockTags.FENCES_CONNECT, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> LEAVES_OAK = register("leaves.oak", "minecraft:block/leaves_oak", 290, BlockLogicLeavesOak::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_OAK_RETRO = register("leaves.oak.retro", "minecraft:block/leaves_oak_retro", 291, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_OAK_RETRO))
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_PINE = register("leaves.pine", "minecraft:block/leaves_pine", 292, BlockLogicLeavesPine::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.pineLeaves)
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withOverrideColor(MaterialColor.pineLeaves)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_BIRCH = register("leaves.birch", "minecraft:block/leaves_birch", 293, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_BIRCH))
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.birchLeaves)
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withOverrideColor(MaterialColor.birchLeaves)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_CHERRY = register("leaves.cherry", "minecraft:block/leaves_cherry", 294, BlockLogicLeavesCherry::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.cherryLeaves)
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withOverrideColor(MaterialColor.cherryLeaves)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_EUCALYPTUS = register("leaves.eucalyptus", "minecraft:block/leaves_eucalyptus", 295, BlockLogicLeavesEucalyptus::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_SHRUB = register("leaves.shrub", "minecraft:block/leaves_shrub", 296, BlockLogicLeavesShrub::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_CHERRY_FLOWERING = register("leaves.cherry.flowering", "minecraft:block/leaves_cherry_flowering", 297, BlockLogicLeavesCherryFlowering::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.cherryLeaves)
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withOverrideColor(MaterialColor.cherryLeaves)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_CACAO = register("leaves.cacao", "minecraft:block/leaves_cacao", 298, BlockLogicLeavesCacao::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_THORN = register("leaves.thorn", "minecraft:block/leaves_thorn", 299, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_THORN))
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.thornLeaves)
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withOverrideColor(MaterialColor.thornLeaves)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
     public static final @NotNull Block<?> LEAVES_PALM = register("leaves.palm", "minecraft:block/leaves_palm", 300, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_PALM))
-        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.palmLeaves)
+        .withSound(BlockSounds.GRASS).withHardness(0.2F).withLightBlock(1).withOverrideColor(MaterialColor.palmLeaves)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
 
     public static final @NotNull Block<?> SAPLING_OAK = register("sapling.oak", "minecraft:block/sapling_oak", 310, BlockLogicSaplingOak::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_OAK_RETRO = register("sapling.oak.retro", "minecraft:block/sapling_oak_retro", 311, BlockLogicSaplingRetro::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_PINE = register("sapling.pine", "minecraft:block/sapling_pine", 312, BlockLogicSaplingPine::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_BIRCH = register("sapling.birch", "minecraft:block/sapling_birch", 313, BlockLogicSaplingBirch::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_CHERRY = register("sapling.cherry", "minecraft:block/sapling_cherry", 314, BlockLogicSaplingCherry::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_EUCALYPTUS = register("sapling.eucalyptus", "minecraft:block/sapling_eucalyptus", 315, BlockLogicSaplingEucalyptus::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_SHRUB = register("sapling.shrub", "minecraft:block/sapling_shrub", 316, BlockLogicSaplingShrub::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_CACAO = register("sapling.cacao", "minecraft:block/sapling_cacao", 317, BlockLogicSaplingCacao::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_THORN = register("sapling.thorn", "minecraft:block/sapling_thorn", 318, BlockLogicSaplingThorn::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
     public static final @NotNull Block<?> SAPLING_PALM = register("sapling.palm", "minecraft:block/sapling_palm", 319, BlockLogicSaplingPalm::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
 
     public static final @NotNull Block<?> TALLGRASS = register("tallgrass", "minecraft:block/tallgrass", 320, b -> new BlockLogicTallGrass(b).setKilledByWeather())
@@ -647,44 +646,44 @@ public final class Blocks {
 
     public static final @NotNull Block<?> ORE_REDSTONE_STONE = register("ore.redstone.stone", "minecraft:block/ore_redstone_stone", 390,
         (b) -> new BlockLogicOreRedstone(b, Blocks.STONE, Materials.STONE, false, Blocks.ORE_REDSTONE_STONE, Blocks.ORE_REDSTONE_GLOWING_STONE))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_BASALT = register("ore.redstone.basalt", "minecraft:block/ore_redstone_basalt", 391,
         (b) -> new BlockLogicOreRedstone(b, Blocks.BASALT, Materials.BASALT, false, Blocks.ORE_REDSTONE_BASALT, Blocks.ORE_REDSTONE_GLOWING_BASALT))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_LIMESTONE = register("ore.redstone.limestone", "minecraft:block/ore_redstone_limestone", 392,
         (b) -> new BlockLogicOreRedstone(b, Blocks.LIMESTONE, Materials.LIMESTONE, false, Blocks.ORE_REDSTONE_LIMESTONE, Blocks.ORE_REDSTONE_GLOWING_LIMESTONE))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_GRANITE = register("ore.redstone.granite", "minecraft:block/ore_redstone_granite", 393,
         (b) -> new BlockLogicOreRedstone(b, Blocks.GRANITE, Materials.GRANITE, false, Blocks.ORE_REDSTONE_GRANITE, Blocks.ORE_REDSTONE_GLOWING_GRANITE))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(2F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_PERMAFROST = register("ore.redstone.permafrost", "minecraft:block/ore_redstone_permafrost", 394,
         (b) -> new BlockLogicOreRedstone(b, Blocks.PERMAFROST, Materials.PERMAFROST, false, Blocks.ORE_REDSTONE_PERMAFROST, Blocks.ORE_REDSTONE_GLOWING_PERMAFROST))
-        .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(2F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(2F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> ORE_REDSTONE_GLOWING_STONE = register("ore.redstone.glowing.stone", "minecraft:block/ore_redstone_glowing_stone", 400,
         (b) -> new BlockLogicOreRedstone(b, null, Materials.STONE, true, Blocks.ORE_REDSTONE_STONE, Blocks.ORE_REDSTONE_GLOWING_STONE))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_STONE)
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).setStatParent(() -> ORE_REDSTONE_STONE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_GLOWING_BASALT = register("ore.redstone.glowing.basalt", "minecraft:block/ore_redstone_glowing_basalt", 401,
         (b) -> new BlockLogicOreRedstone(b, null, Materials.BASALT, true, Blocks.ORE_REDSTONE_BASALT, Blocks.ORE_REDSTONE_GLOWING_BASALT))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_BASALT)
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).setStatParent(() -> ORE_REDSTONE_BASALT)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_GLOWING_LIMESTONE = register("ore.redstone.glowing.limestone", "minecraft:block/ore_redstone_glowing_limestone", 402,
         (b) -> new BlockLogicOreRedstone(b, null, Materials.LIMESTONE, true, Blocks.ORE_REDSTONE_LIMESTONE, Blocks.ORE_REDSTONE_GLOWING_LIMESTONE))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_LIMESTONE)
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).setStatParent(() -> ORE_REDSTONE_LIMESTONE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_GLOWING_GRANITE = register("ore.redstone.glowing.granite", "minecraft:block/ore_redstone_glowing_granite", 403,
         (b) -> new BlockLogicOreRedstone(b, null, Materials.GRANITE, true, Blocks.ORE_REDSTONE_GRANITE, Blocks.ORE_REDSTONE_GLOWING_GRANITE))
-        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_GRANITE)
+        .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).setStatParent(() -> ORE_REDSTONE_GRANITE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> ORE_REDSTONE_GLOWING_PERMAFROST = register("ore.redstone.glowing.permafrost", "minecraft:block/ore_redstone_glowing_permafrost", 404,
         (b) -> new BlockLogicOreRedstone(b, null, Materials.PERMAFROST, true, Blocks.ORE_REDSTONE_PERMAFROST, Blocks.ORE_REDSTONE_GLOWING_PERMAFROST))
-        .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_PERMAFROST)
+        .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(5F).setStatParent(() -> ORE_REDSTONE_PERMAFROST)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> ORE_DIAMOND_STONE = register("ore.diamond.stone", "minecraft:block/ore_diamond_stone", 410, (b) -> new BlockLogicOreDiamond(b, Blocks.STONE, Materials.STONE))
@@ -748,60 +747,60 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<BlockLogicWireRedstone> WIRE_REDSTONE = register("wire.redstone", "minecraft:block/wire_redstone", 450, BlockLogicWireRedstone::new)
-        .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.DUST_REDSTONE)
+        .withSound(BlockSounds.STONE).withHardness(0.0F).withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.DUST_REDSTONE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> TORCH_REDSTONE_IDLE = register("torch.redstone.idle", "minecraft:block/torch_redstone_idle", 460, (b) -> new BlockLogicTorchRedstone(b, false))
-        .withSound(BlockSounds.WOOD).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Blocks.TORCH_REDSTONE_ACTIVE)
+        .withSound(BlockSounds.WOOD).withHardness(0.0F).withOverrideColor(MaterialColor.redstone).setStatParent(() -> Blocks.TORCH_REDSTONE_ACTIVE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> TORCH_REDSTONE_ACTIVE = register("torch.redstone.active", "minecraft:block/torch_redstone_active", 461, (b) -> new BlockLogicTorchRedstone(b, true))
-        .withSound(BlockSounds.WOOD).withHardness(0.0F).withLightEmission(0.5F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone)
+        .withSound(BlockSounds.WOOD).withHardness(0.0F).withLightEmission(0.5F).withOverrideColor(MaterialColor.redstone)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> BUTTON_STONE = register("button.stone", "minecraft:block/button_stone", 470, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_PLANKS_OAK = register("button.planks", "minecraft:block/button_planks", 471, BlockLogicButtonPlanksOak::new)
-        .withSound(BlockSounds.WOOD).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<BlockLogicButtonPainted> BUTTON_PLANKS_PAINTED = register("button.planks.painted", "minecraft:block/button_planks_painted", 472, BlockLogicButtonPainted::new)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
-        .withSound(BlockSounds.WOOD).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> LEVER_COBBLE_STONE = register("lever.cobble.stone", "minecraft:block/lever_cobble_stone", 480, BlockLogicLever::new)
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> PRESSURE_PLATE_STONE = register("pressureplate.stone", "minecraft:block/pressure_plate_stone", 490, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.STONE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_PLANKS_OAK = register("pressureplate.planks.oak", "minecraft:block/pressure_plate_planks_oak", 491, (b) -> new BlockLogicPressurePlate<>(b, Entity.class, Materials.WOOD))
-        .withSound(BlockSounds.WOOD).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_COBBLE_STONE = register("pressureplate.cobble.stone", "minecraft:block/pressure_plate_cobble_stone", 492, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.STONE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<BlockLogicPressurePlatePainted> PRESSURE_PLATE_PLANKS_OAK_PAINTED = register("pressureplate.planks.oak.painted", "minecraft:block/pressure_plate_planks_oak_painted", 493, (BlockLogicSupplier<BlockLogicPressurePlatePainted>)b -> new BlockLogicPressurePlatePainted<>(b, Entity.class, Materials.WOOD))
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
-        .withSound(BlockSounds.WOOD).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<BlockLogicMotionSensor> MOTION_SENSOR_IDLE = register("motionsensor.idle", "minecraft:block/motion_sensor_idle", 500, (BlockLogicSupplier<BlockLogicMotionSensor>)(b) -> new BlockLogicMotionSensor(b, false))
-        .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.stone)
+        .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F).withOverrideColor(MaterialColor.stone)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<BlockLogicMotionSensor> MOTION_SENSOR_ACTIVE = register("motionsensor.active", "minecraft:block/motion_sensor_active", 501, (BlockLogicSupplier<BlockLogicMotionSensor>)(b) -> new BlockLogicMotionSensor(b, true))
         .withSound(BlockSounds.STONE).withLightEmission(0.3F).withHardness(1.5F).withBlastResistance(10F).withOverrideColor(MaterialColor.stone).setStatParent(() -> MOTION_SENSOR_IDLE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<BlockLogicRepeater> REPEATER_IDLE = register("repeater.idle", "minecraft:block/repeater_idle", 510, (BlockLogicSupplier<BlockLogicRepeater>)b -> new BlockLogicRepeater(b, false))
-        .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.REPEATER)
+        .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledStats().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.REPEATER)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<BlockLogicRepeater> REPEATER_ACTIVE = register("repeater.active", "minecraft:block/repeater_active", 511, (BlockLogicSupplier<BlockLogicRepeater>)b -> new BlockLogicRepeater(b, true))
-        .withSound(BlockSounds.STONE).withHardness(0.0F).withLightEmission(0.625F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> REPEATER_IDLE)
+        .withSound(BlockSounds.STONE).withHardness(0.0F).withLightEmission(0.625F).withDisabledStats().withOverrideColor(MaterialColor.redstone).setStatParent(() -> REPEATER_IDLE)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<BlockLogicTimer> TIMER = register("timer", "minecraft:block/timer", 512, BlockLogicTimer::new)
-        .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.TIMER)
+        .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledStats().withOverrideColor(MaterialColor.redstone).setStatParent(() -> Items.TIMER)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<BlockLogicPistonBase> PISTON_BASE = register("piston.base", "minecraft:block/piston_base", 520, (BlockLogicSupplier<BlockLogicPistonBase>)b -> 
@@ -809,18 +808,18 @@ public final class Blocks {
             b, PistonCommon.TYPE_NORMAL,
             12, 0, 1, EnumDropCause.SILK_TOUCH, Double.NaN
         ))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicPistonBase> PISTON_BASE_STICKY = register("piston.base.sticky", "minecraft:block/piston_base_sticky", 521, (BlockLogicSupplier<BlockLogicPistonBase>)b -> 
         new BlockLogicPistonBase(
             b, PistonCommon.TYPE_STICKY,
             12, 12, 1, EnumDropCause.SILK_TOUCH, Double.NaN
         ))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicPistonHead> PISTON_HEAD = register("piston.head", "minecraft:block/piston_head", 522, (BlockLogicSupplier<BlockLogicPistonHead>)(b) -> new BlockLogicPistonHead(b, 4/16d, 4/16d))
-        .withSound(BlockSounds.WOOD).withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
+        .withSound(BlockSounds.WOOD).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicPistonMoving> PISTON_MOVING = register("piston.moving", "minecraft:block/piston_moving", 523, BlockLogicPistonMoving::new)
@@ -835,56 +834,56 @@ public final class Blocks {
         .withSound(BlockSounds.METAL)
         .withHardness(5F)
         .withBlastResistance(2000F)
-        .withOverrideColor(MaterialColor.steel).withDisabledNeighborNotifyOnMetadataChange()
+        .withOverrideColor(MaterialColor.steel)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicPistonHead> PISTON_HEAD_STEEL = register("piston.head.steel", "minecraft:block/piston_head_steel", 525, (BlockLogicSupplier<BlockLogicPistonHead>)(b) -> new BlockLogicPistonHead(b, 6/16d, 8/16d))
         .withSound(BlockSounds.METAL)
         .withHardness(5F)
         .withBlastResistance(2000F)
         .withOverrideColor(MaterialColor.steel)
-        .withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
+        .withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> NOTEBLOCK = register("noteblock", "minecraft:block/noteblock", 530, BlockLogicNote::new)
-        .withSound(BlockSounds.WOOD).withHardness(0.8F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(0.8F)
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<BlockLogicRail> RAIL = register("rail", "minecraft:block/rail", 540, (BlockLogicSupplier<BlockLogicRail>)b -> new BlockLogicRail(b, false))
-        .withSound(BlockSounds.METAL).withHardness(0.7F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.METAL).withHardness(0.7F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<BlockLogicRail> RAIL_POWERED = register("rail.powered", "minecraft:block/rail_powered", 541, (BlockLogicSupplier<BlockLogicRail>)b -> new BlockLogicRail(b, true))
-        .withSound(BlockSounds.METAL).withHardness(0.7F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.METAL).withHardness(0.7F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<BlockLogicRail> RAIL_DETECTOR = register("rail.detector", "minecraft:block/rail_detector", 542, (BlockLogicSupplier<BlockLogicRail>)BlockLogicRailDetector::new)
-        .withSound(BlockSounds.METAL).withHardness(0.7F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.METAL).withHardness(0.7F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> SPIKES = register("spikes", "minecraft:block/spikes", 550, (b) -> new BlockLogicSpikes(b, Materials.METAL))
-        .withSound(BlockSounds.METAL).withLightBlock(3).withHardness(2F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.METAL).withLightBlock(3).withHardness(2F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> DISPENSER_COBBLE_STONE = register("dispenser.cobble.stone", "minecraft:block/dispenser_cobble_stone", 560, BlockLogicDispenser::new)
-        .withSound(BlockSounds.STONE).withHardness(1.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> ACTIVATOR = register("activator.cobble.netherrack", "minecraft:block/activator_cobble_netherrack", 561, BlockLogicActivator::new)
-        .withSound(BlockSounds.STONE).withHardness(1.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> TRAPDOOR_PLANKS_OAK = register("trapdoor.planks.oak", "minecraft:block/trapdoor_planks_oak", 570, (b) -> new BlockLogicTrapDoor(b, Materials.WOOD))
-        .withSound(BlockSounds.WOOD).withHardness(3F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(3F)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> TRAPDOOR_IRON = register("trapdoor.iron", "minecraft:block/trapdoor_iron", 571, (b) -> new BlockLogicTrapDoor(b, Materials.METAL))
-        .withSound(BlockSounds.METAL).withHardness(5F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.iron)
+        .withSound(BlockSounds.METAL).withHardness(5F).withOverrideColor(MaterialColor.iron)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> TRAPDOOR_GLASS = register("trapdoor.glass", "minecraft:block/trapdoor_glass", 572, (b) -> new BlockLogicTrapDoor(b, Materials.GLASS))
-        .withSound(BlockSounds.GLASS).withHardness(0.3F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GLASS).withHardness(0.3F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> TRAPDOOR_PLANKS_PAINTED = register("trapdoor.planks.oak.painted", "minecraft:block/trapdoor_planks_oak_painted", 573, (b) -> new BlockLogicTrapDoorPainted(b, Materials.WOOD))
-        .withSound(BlockSounds.WOOD).withHardness(3F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(3F)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> TRAPDOOR_STEEL = register("trapdoor.steel", "minecraft:block/trapdoor_steel", 574, (b) -> new BlockLogicTrapDoor(b, Materials.STEEL))
-        .withSound(BlockSounds.METAL).withOverrideColor(MaterialColor.steel).withHardness(5F).withBlastResistance(2000F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.steel)
+        .withSound(BlockSounds.METAL).withOverrideColor(MaterialColor.steel).withHardness(5F).withBlastResistance(2000F).withOverrideColor(MaterialColor.steel)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicTNT> TNT = register("tnt", "minecraft:block/tnt", 580, BlockLogicTNT::new)
@@ -892,45 +891,45 @@ public final class Blocks {
 
     public static final @NotNull Block<BlockLogicDoor> DOOR_PLANKS_OAK_BOTTOM = register("door.planks.oak.bottom", "minecraft:block/door_planks_oak_bottom", 590,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.WOOD, false, false, () -> Items.DOOR_OAK))
-        .withSound(BlockSounds.WOOD).withHardness(3F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.DOOR_OAK)
+        .withSound(BlockSounds.WOOD).withHardness(3F).setStatParent(() -> Items.DOOR_OAK)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicDoor> DOOR_PLANKS_OAK_TOP = register("door.planks.oak.top", "minecraft:block/doors_planks_oak_top", 591,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.WOOD, true, false, () -> Items.DOOR_OAK))
-        .withSound(BlockSounds.WOOD).withHardness(3F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> DOOR_PLANKS_OAK_BOTTOM)
+        .withSound(BlockSounds.WOOD).withHardness(3F).setStatParent(() -> DOOR_PLANKS_OAK_BOTTOM)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicDoor> DOOR_IRON_BOTTOM = register("door.iron.bottom", "minecraft:block/door_iron_bottom", 592,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.METAL, false, true, () -> Items.DOOR_IRON))
-        .withSound(BlockSounds.METAL).withHardness(5F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.iron).setStatParent(() -> Items.DOOR_IRON)
+        .withSound(BlockSounds.METAL).withHardness(5F).withOverrideColor(MaterialColor.iron).setStatParent(() -> Items.DOOR_IRON)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicDoor> DOOR_IRON_TOP = register("door.iron.top", "minecraft:block/door_iron_top", 593,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.METAL, true, true, () -> Items.DOOR_IRON))
-        .withSound(BlockSounds.METAL).withHardness(5F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.iron).setStatParent(() -> DOOR_IRON_BOTTOM)
+        .withSound(BlockSounds.METAL).withHardness(5F).withOverrideColor(MaterialColor.iron).setStatParent(() -> DOOR_IRON_BOTTOM)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicDoorPainted> DOOR_PLANKS_PAINTED_BOTTOM = register("door.planks.oak.painted.bottom", "minecraft:block/door_planks_oak_painted_bottom", 594,
         (BlockLogicSupplier<BlockLogicDoorPainted>)(b) -> new BlockLogicDoorPainted(b, Materials.WOOD, false))
-        .withSound(BlockSounds.WOOD).withHardness(3F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.DOOR_OAK_PAINTED)
+        .withSound(BlockSounds.WOOD).withHardness(3F).setStatParent(() -> Items.DOOR_OAK_PAINTED)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicDoorPainted> DOOR_PLANKS_PAINTED_TOP = register("door.planks.oak.painted.top", "minecraft:block/door_planks_oak_painted_top", 595,
         (BlockLogicSupplier<BlockLogicDoorPainted>)(b) -> new BlockLogicDoorPainted(b, Materials.WOOD, true))
-        .withSound(BlockSounds.WOOD).withHardness(3F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> DOOR_PLANKS_PAINTED_BOTTOM)
+        .withSound(BlockSounds.WOOD).withHardness(3F).setStatParent(() -> DOOR_PLANKS_PAINTED_BOTTOM)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicDoor> DOOR_GLASS_BOTTOM = register("door.glass.bottom", "minecraft:block/door_glass_bottom", 596,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.GLASS, false, false, () -> Items.DOOR_GLASS))
-        .withSound(BlockSounds.GLASS).withHardness(0.3F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.DOOR_GLASS)
+        .withSound(BlockSounds.GLASS).withHardness(0.3F).setStatParent(() -> Items.DOOR_GLASS)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicDoor> DOOR_GLASS_TOP = register("door.glass.top", "minecraft:block/door_glass_top", 597,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.GLASS, true, false, () -> Items.DOOR_GLASS))
-        .withSound(BlockSounds.GLASS).withHardness(0.3F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> DOOR_GLASS_BOTTOM)
+        .withSound(BlockSounds.GLASS).withHardness(0.3F).setStatParent(() -> DOOR_GLASS_BOTTOM)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicDoor> DOOR_STEEL_BOTTOM = register("door.steel.bottom", "minecraft:block/door_steel_bottom", 598,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.STEEL, false, true, () -> Items.DOOR_STEEL))
-        .withSound(BlockSounds.METAL).withHardness(5F).withOverrideColor(MaterialColor.steel).withBlastResistance(2000F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.steel).setStatParent(() -> Items.DOOR_STEEL)
+        .withSound(BlockSounds.METAL).withHardness(5F).withOverrideColor(MaterialColor.steel).withBlastResistance(2000F).withOverrideColor(MaterialColor.steel).setStatParent(() -> Items.DOOR_STEEL)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicDoor> DOOR_STEEL_TOP = register("door.steel.top", "minecraft:block/door_steel_top", 599,
         (BlockLogicSupplier<BlockLogicDoor>)b -> new BlockLogicDoor(b, Materials.STEEL, true, true, () -> Items.DOOR_STEEL))
-        .withSound(BlockSounds.METAL).withHardness(5F).withOverrideColor(MaterialColor.steel).withBlastResistance(2000F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.steel).setStatParent(() -> DOOR_STEEL_BOTTOM)
+        .withSound(BlockSounds.METAL).withHardness(5F).withOverrideColor(MaterialColor.steel).withBlastResistance(2000F).withOverrideColor(MaterialColor.steel).setStatParent(() -> DOOR_STEEL_BOTTOM)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> MESH = register("mesh", "minecraft:block/mesh", 600, BlockLogicMesh::new)
@@ -941,10 +940,10 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
 
     public static final @NotNull Block<BlockLogicBed> BED = register("bed", "minecraft:block/bed", 610, BlockLogicBed::new)
-        .withSound(BlockSounds.WOOD).withHardness(0.2F).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).setStatParent(() -> Items.BED)
+        .withSound(BlockSounds.WOOD).withHardness(0.2F).withLitInteriorSurface(true).setStatParent(() -> Items.BED)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> SEAT = register("seat", "minecraft:block/seat", 611, BlockLogicSeat::new)
-        .withSound(BlockSounds.WOOD).withHardness(0.2F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.SEAT)
+        .withSound(BlockSounds.WOOD).withHardness(0.2F).setStatParent(() -> Items.SEAT)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> COBWEB = register("cobweb", "minecraft:block/cobweb", 620, (b) -> new BlockLogicCobweb(b, Materials.WEB))
@@ -952,7 +951,7 @@ public final class Blocks {
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_SHEARS, BlockTags.MINEABLE_BY_SWORD);
 
     public static final @NotNull Block<BlockLogicFire> FIRE = register("fire", "minecraft:block/fire", 630, BlockLogicFire::new)
-        .withSound(BlockSounds.FIRE).withHardness(0.0F).withLightEmission(1.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.FIRE).withHardness(0.0F).withLightEmission(1.0F).withDisabledStats()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<BlockLogicBrazier> BRAZIER_INACTIVE = register("brazier.inactive", "minecraft:block/brazier_inactive", 631, (BlockLogicSupplier<BlockLogicBrazier>)b -> new BlockLogicBrazier(b, false))
         .withSound(BlockSounds.METAL).withHardness(1.5F)
@@ -961,10 +960,10 @@ public final class Blocks {
         .withSound(BlockSounds.FIRE).withHardness(1.5F).withLightEmission(1.0F).setStatParent(() -> BRAZIER_INACTIVE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicFireCold> FIRE_COLD = register("fire_cold", "minecraft:block/fire_cold", 633, BlockLogicFireCold::new)
-        .withSound(BlockSounds.FIRE).withHardness(0.0F).withLightEmission(1.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.FIRE).withHardness(0.0F).withLightEmission(1.0F).withDisabledStats()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<BlockLogicFireSulfuric> FIRE_SULFURIC = register("fire_sulfuric", "minecraft:block/fire_sulfuric", 634, BlockLogicFireSulfuric::new)
-        .withSound(BlockSounds.FIRE).withHardness(0.0F).withLightEmission(1.0F).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.FIRE).withHardness(0.0F).withLightEmission(1.0F).withDisabledStats()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.SULFURIC_FIRE_OVERLAY_SOURCE);
 
     public static final @NotNull Block<?> MOBSPAWNER = register("mobspawner", "minecraft:block/mobspawner", 640, BlockLogicMobSpawner::new)
@@ -981,23 +980,23 @@ public final class Blocks {
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> FURNACE_STONE_IDLE = register("furnace.stone.idle", "minecraft:block/furnace_stone_idle", 660, (b) -> new BlockLogicFurnace(b, false))
-        .withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(3.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> FURNACE_STONE_ACTIVE = register("furnace.stone.active", "minecraft:block/furnace_stone_active", 661, (b) -> new BlockLogicFurnace(b, true))
-        .withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> FURNACE_STONE_IDLE)
+        .withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).setStatParent(() -> FURNACE_STONE_IDLE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> FURNACE_BLAST_IDLE = register("furnace.blast.idle", "minecraft:block/furnace_blast_idle", 662, (b) -> new BlockLogicFurnaceBlast(b, false))
-        .withSound(BlockSounds.METAL).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.steel)
+        .withSound(BlockSounds.METAL).withHardness(3.5F).withOverrideColor(MaterialColor.steel)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> FURNACE_BLAST_ACTIVE = register("furnace.blast.active", "minecraft:block/furnace_blast_active", 663, (b) -> new BlockLogicFurnaceBlast(b, true))
-        .withSound(BlockSounds.METAL).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.steel).setStatParent(() -> FURNACE_BLAST_IDLE)
+        .withSound(BlockSounds.METAL).withHardness(3.5F).withLightEmission(0.875F).withOverrideColor(MaterialColor.steel).setStatParent(() -> FURNACE_BLAST_IDLE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> TROMMEL_IDLE = register("trommel.idle", "minecraft:block/trommel_idle", 670, (b) -> new BlockLogicTrommel(b, Materials.STONE, false))
-        .withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(3.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<?> TROMMEL_ACTIVE = register("trommel.active", "minecraft:block/trommel_active", 671, (b) -> new BlockLogicTrommel(b, Materials.STONE, true))
-        .withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> TROMMEL_IDLE)
+        .withSound(BlockSounds.STONE).withHardness(3.5F).withLightEmission(0.875F).setStatParent(() -> TROMMEL_IDLE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     @SuppressWarnings("deprecation")
@@ -1009,29 +1008,29 @@ public final class Blocks {
         .withSound(BlockSounds.WOOD).withHardness(2.5f).withBlastResistance(5.0f).setStatParent(() -> Blocks.CHEST_PLANKS_OAK_PAINTED)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicChest> CHEST_PLANKS_OAK = register("chest.planks.oak", "minecraft:block/chest_planks_oak", 682, (BlockLogicSupplier<BlockLogicChest>)(b) -> new BlockLogicChest(b, Materials.WOOD))
-        .withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicChest> CHEST_PLANKS_OAK_PAINTED = register("chest.planks.oak.painted", "minecraft:block/chest_planks_oak_painted", 683, (BlockLogicSupplier<BlockLogicChest>)(b) -> new BlockLogicChestPainted(b, Materials.WOOD))
-        .withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.5F).withBlastResistance(5.0f)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> CROPS_WHEAT = register("crops.wheat", "minecraft:block/crops_wheat", 690, BlockLogicCropsWheat::new)
-        .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.SEEDS_WHEAT)
+        .withSound(BlockSounds.GRASS).withHardness(0.0F).setStatParent(() -> Items.SEEDS_WHEAT)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> CROPS_PUMPKIN = register("crops.pumpkin", "minecraft:block/crops_pumpkin", 691, BlockLogicCropsPumpkin::new)
-        .withSound(BlockSounds.WOOD).withHardness(0.0f).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).setStatParent(() -> Items.SEEDS_PUMPKIN)
+        .withSound(BlockSounds.WOOD).withHardness(0.0f).withLitInteriorSurface(true).setStatParent(() -> Items.SEEDS_PUMPKIN)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.OVERRIDE_STEPSOUND);
 
     public static final @NotNull Block<?> FARMLAND_DIRT = register("farmland.dirt", "minecraft:block/farmland_dirt", 700, BlockLogicFarmland::new)
-        .withSound(BlockSounds.GRAVEL).withHardness(0.6F).withLitInteriorSurface(true).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GRAVEL).withHardness(0.6F).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL);
 
     public static final @NotNull Block<BlockLogicSign> SIGN_POST_PLANKS_OAK = register("sign.post.planks.oak", "minecraft:block/sign_post_planks_oak", 710, (BlockLogicSupplier<BlockLogicSign>)(b) -> new BlockLogicSign(b, true))
-        .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.SIGN)
+        .withSound(BlockSounds.WOOD).withHardness(1.0F).setStatParent(() -> Items.SIGN)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicSign> SIGN_WALL_PLANKS_OAK = register("sign.wall.planks.oak", "minecraft:block/sign_wall_planks_oak", 711, (BlockLogicSupplier<BlockLogicSign>)(b) -> new BlockLogicSign(b, false))
-        .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> SIGN_POST_PLANKS_OAK)
+        .withSound(BlockSounds.WOOD).withHardness(1.0F).setStatParent(() -> SIGN_POST_PLANKS_OAK)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> FLAG = register("flag", "minecraft:block/flag", 712, (b) -> new BlockLogicFlag(b, Materials.WOOD))
@@ -1039,10 +1038,10 @@ public final class Blocks {
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<BlockLogicSignPainted> SIGN_POST_PLANKS_OAK_PAINTED = register("sign.post.planks.oak.painted", "minecraft:block/sign_post_planks_oak_painted", 713, (BlockLogicSupplier<BlockLogicSignPainted>)(b) -> new BlockLogicSignPainted(b, true))
-            .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.SIGN)
+            .withSound(BlockSounds.WOOD).withHardness(1.0F).setStatParent(() -> Items.SIGN)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<BlockLogicSignPainted> SIGN_WALL_PLANKS_OAK_PAINTED = register("sign.wall.planks.oak.painted", "minecraft:block/sign_wall_planks_oak_painted", 714, (BlockLogicSupplier<BlockLogicSignPainted>)(b) -> new BlockLogicSignPainted(b, false))
-            .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> SIGN_POST_PLANKS_OAK)
+            .withSound(BlockSounds.WOOD).withHardness(1.0F).setStatParent(() -> SIGN_POST_PLANKS_OAK)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<BlockLogicLayerSnow> LAYER_SNOW = register("layer.snow", "minecraft:block/layer_snow", 720, (BlockLogicSupplier<BlockLogicLayerSnow>)(b) -> new BlockLogicLayerSnow(b, Blocks.BLOCK_SNOW, Materials.TOP_SNOW))
@@ -1091,20 +1090,20 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.FENCES_CONNECT);
 
     public static final @NotNull Block<BlockLogicJukebox> JUKEBOX = register("jukebox", "minecraft:block/jukebox", 780, BlockLogicJukebox::new)
-        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> PUMPKIN = register("pumpkin", "minecraft:block/pumpkin", 790, (b) -> new BlockLogicPumpkin(b, true))
-        .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(1.0F)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> PUMPKIN_CARVED_IDLE = register("pumpkin.carved.idle", "minecraft:block/pumpkin_carved_idle", 791, (b) -> new BlockLogicPumpkin(b, false))
-        .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(1.0F)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> PUMPKIN_CARVED_ACTIVE = register("pumpkin.carved.active", "minecraft:block/pumpkin_carved_active", 792, (b) -> new BlockLogicPumpkin(b, false))
-        .withSound(BlockSounds.WOOD).withHardness(1.0F).withLightEmission(1.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(1.0F).withLightEmission(1.0F)
         .withTags(BlockTags.MINEABLE_BY_AXE);
     public static final @NotNull Block<?> PUMPKIN_REDSTONE = register("pumpkin.redstone", "minecraft:block/pumpkin_redstone", 793, BlockLogicPumpkinRedstone::new)
-        .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.WOOD).withHardness(1.0F)
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> COBBLE_NETHERRACK = register("cobble.netherrack", "minecraft:block/cobble_netherrack", 800, (b) -> new BlockLogicCobble(b, Materials.NETHERRACK, null))
@@ -1160,7 +1159,7 @@ public final class Blocks {
         .withSound(BlockSounds.CRYSTAL).withHardness(1.5F).withOverrideColor(MaterialColor.rubyglass)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.SKATEABLE, BlockTags.NETHER_MOBS_SPAWN, BlockTags.NETHER_SURFACE_BLOCK, BlockTags.CAVES_CUT_THROUGH);
     public static final @NotNull Block<BlockLogicConduit> CONDUIT = register("rubyglass.conduit", "minecraft:block/conduit", 824, (BlockLogicSupplier<BlockLogicConduit>) b -> new BlockLogicConduit(b, Materials.STONE))
-        .withSound(BlockSounds.STONE).withHardness(1.5F).withOverrideColor(MaterialColor.rubyglass).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.5F).withOverrideColor(MaterialColor.rubyglass)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> RUBYGLASS_GROWTH = register("rubyglass.growth", "minecraft:block/rubyglass_growth", 825, block -> new BlockLogicGrowthRubyglass(block, Materials.PLANT))
         .withSound(BlockSounds.CRYSTAL).withOverrideColor(MaterialColor.rubyglass)
@@ -1182,75 +1181,75 @@ public final class Blocks {
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
 
     public static final @NotNull Block<?> CAKE = register("cake", "minecraft:block/cake", 840, BlockLogicCake::new)
-        .withSound(BlockSounds.CLOTH).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.FOOD_CAKE)
+        .withSound(BlockSounds.CLOTH).withHardness(0.5F).setStatParent(() -> Items.FOOD_CAKE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<BlockLogicEdible> PUMPKIN_PIE = register("pumpkin_pie", "minecraft:block/pumpkin_pie", 841, (BlockLogicSupplier<BlockLogicEdible>)BlockLogicPiePumpkin::new)
-        .withSound(BlockSounds.CLOTH).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.paintedOrange).setStatParent(() -> Items.FOOD_PUMPKIN_PIE)
+        .withSound(BlockSounds.CLOTH).withHardness(0.5F).withOverrideColor(MaterialColor.paintedOrange).setStatParent(() -> Items.FOOD_PUMPKIN_PIE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
 
     public static final @NotNull Block<BlockLogicLamp> LAMP_IDLE = register("lamp.idle", "minecraft:block/lamp_idle", 850, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, false, false))
-        .withSound(BlockSounds.GLASS).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GLASS).withHardness(0.5F)
         .setBlockItem(ItemBlockLamp::new)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicLamp> LAMP_ACTIVE = register("lamp.active", "minecraft:block/lamp_active", 851, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, true, false))
-        .withSound(BlockSounds.GLASS).withLightEmission(0.9375F).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> LAMP_IDLE)
+        .withSound(BlockSounds.GLASS).withLightEmission(0.9375F).withHardness(0.5F).setStatParent(() -> LAMP_IDLE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicLamp> LAMP_INVERTED_IDLE = register("lamp.inverted.idle", "minecraft:block/lamp_inverted_idle", 852, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, false, true))
-        .withSound(BlockSounds.GLASS).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Blocks.LAMP_INVERTED_ACTIVE)
+        .withSound(BlockSounds.GLASS).withHardness(0.5F).setStatParent(() -> Blocks.LAMP_INVERTED_ACTIVE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicLamp> LAMP_INVERTED_ACTIVE = register("lamp.inverted.active", "minecraft:block/lamp_inverted_active", 853, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, true, true))
-        .withSound(BlockSounds.GLASS).withLightEmission(0.9375F).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.GLASS).withLightEmission(0.9375F).withHardness(0.5F)
         .setBlockItem(ItemBlockLamp::new)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> STONE_POLISHED = register("stone.polished", "minecraft:block/stone_polished", 860, (b) -> new BlockLogic(b, Materials.STONE))
-            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> GRANITE_POLISHED = register("granite.polished", "minecraft:block/granite_polished", 861, (b) -> new BlockLogic(b, Materials.GRANITE))
-            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> LIMESTONE_POLISHED = register("limestone.polished", "minecraft:block/limestone_polished", 862, (b) -> new BlockLogic(b, Materials.LIMESTONE))
-            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> BASALT_POLISHED = register("basalt.polished", "minecraft:block/basalt_polished", 863, (b) -> new BlockLogic(b, Materials.BASALT))
-            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> SLATE_POLISHED = register("slate.polished", "minecraft:block/slate_polished", 864, (b) -> new BlockLogic(b, Materials.SLATE))
-            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> PERMAFROST_POLISHED = register("permafrost.polished", "minecraft:block/permafrost_polished", 865, (b) -> new BlockLogic(b, Materials.PERMAFROST))
-            .withSound(BlockSounds.PERMAFROST).withHardness(1.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.PERMAFROST).withHardness(1.0F).withBlastResistance(10F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> NETHERRACK_POLISHED = register("netherrack.polished", "minecraft:block/netherrack_polished", 866, (b) -> new BlockLogic(b, Materials.NETHERRACK))
-            .withSound(BlockSounds.STONE).withHardness(0.4F).withDisabledNeighborNotifyOnMetadataChange()
+            .withSound(BlockSounds.STONE).withHardness(0.4F)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
     public static final @NotNull Block<?> GLOOMSTONE_POLISHED = register("gloomstone.polished", "minecraft:block/gloomstone_polished", 867, (b) -> new BlockLogic(b, Materials.GLOOMSTONE))
-        .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10.0f).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10.0f)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT);
 
     public static final @NotNull Block<?> LANTERN_FIREFLY_GREEN = register("lantern.firefly.green", "minecraft:block/lantern_firefly_green", 870,
         (b) -> new BlockLogicLanternFirefly(b, MobFireflyCluster.FireflyColor.GREEN, () -> Items.LANTERN_FIREFLY_GREEN))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.LANTERN_FIREFLY_GREEN)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).setStatParent(() -> Items.LANTERN_FIREFLY_GREEN)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> LANTERN_FIREFLY_BLUE = register("lantern.firefly.blue", "minecraft:block/lantern_firefly_blue", 871,
         (b) -> new BlockLogicLanternFirefly(b, MobFireflyCluster.FireflyColor.BLUE, () -> Items.LANTERN_FIREFLY_BLUE))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.LANTERN_FIREFLY_BLUE)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).setStatParent(() -> Items.LANTERN_FIREFLY_BLUE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> LANTERN_FIREFLY_ORANGE = register("lantern.firefly.orange", "minecraft:block/lantern_firefly_orange", 872,
         (b) -> new BlockLogicLanternFirefly(b, MobFireflyCluster.FireflyColor.ORANGE, () -> Items.LANTERN_FIREFLY_ORANGE))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.LANTERN_FIREFLY_ORANGE)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).setStatParent(() -> Items.LANTERN_FIREFLY_ORANGE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> LANTERN_FIREFLY_RED = register("lantern.firefly.red", "minecraft:block/lantern_firefly_red", 873,
         (b) -> new BlockLogicLanternFirefly(b, MobFireflyCluster.FireflyColor.RED, () -> Items.LANTERN_FIREFLY_RED))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.LANTERN_FIREFLY_RED)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).withLightEmission(0.9375F).setStatParent(() -> Items.LANTERN_FIREFLY_RED)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> JAR_GLASS = register("jar.glass", "minecraft:block/jar_glass", 874,
         (b) -> new BlockLogicJar(b, () -> Items.JAR))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.JAR)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).setStatParent(() -> Items.JAR)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
 
     public static final @NotNull Block<BlockLogicOverlayPebbles> OVERLAY_PEBBLES = register("overlay.pebbles", "minecraft:block/overlay_pebbles", 880, (BlockLogicSupplier<BlockLogicOverlayPebbles>)b -> new BlockLogicOverlayPebbles(b, Materials.DECORATION))
-        .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.AMMO_PEBBLE)
+        .withSound(BlockSounds.STONE).withHardness(0.0F).setStatParent(() -> Items.AMMO_PEBBLE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.OVERRIDE_FRICTION);
 
     public static final @NotNull Block<BlockLogicFenceThin> FENCE_CHAINLINK = register("fence.chainlink", "minecraft:block/fence_chainlink", 890, (BlockLogicSupplier<BlockLogicFenceThin>)b -> new BlockLogicFenceChainlink(b, Materials.METAL))
@@ -1264,7 +1263,7 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
 
     public static final @NotNull Block<BlockLogicBasket> BASKET = register("basket", "minecraft:block/basket", 900, (BlockLogicSupplier<BlockLogicBasket>)(b) -> new BlockLogicBasket(b, Materials.CLOTH))
-        .withSound(BlockSounds.CLOTH).withHardness(0.5F).withOverrideColor(MaterialColor.wood).setStatParent(() -> Items.BASKET).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.CLOTH).withHardness(0.5F).withOverrideColor(MaterialColor.wood).setStatParent(() -> Items.BASKET)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU);
 
     public static final @NotNull Block<?> PAPER_WALL = register("paper_wall", "minecraft:block/paper_wall", 910, (b) -> new BlockLogic(b, Materials.CLOTH))
@@ -1272,55 +1271,55 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_SHEARS, BlockTags.FENCES_CONNECT, BlockTags.CAN_HANG_OFF, BlockTags.MINEABLE_BY_AXE);
 
     public static final @NotNull Block<?> JAR_BUTTERFLY_BLUE = register("jar.butterfly.blue", "minecraft:block/jar_butterfly_blue", 920, (b) -> new BlockLogicJarButterfly(b, MobButterfly.COLOR_BLUE, () -> Items.JAR_BUTTERFLY_BLUE))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.JAR_BUTTERFLY_BLUE)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).setStatParent(() -> Items.JAR_BUTTERFLY_BLUE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> JAR_BUTTERFLY_ORANGE = register("jar.butterfly.orange", "minecraft:block/jar_butterfly_orange", 921, (b) -> new BlockLogicJarButterfly(b, MobButterfly.COLOR_ORANGE, () -> Items.JAR_BUTTERFLY_ORANGE))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.JAR_BUTTERFLY_ORANGE)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).setStatParent(() -> Items.JAR_BUTTERFLY_ORANGE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> JAR_BUTTERFLY_PINK = register("jar.butterfly.pink", "minecraft:block/jar_butterfly_pink", 922, (b) -> new BlockLogicJarButterfly(b, MobButterfly.COLOR_PINK, () -> Items.JAR_BUTTERFLY_PINK))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.JAR_BUTTERFLY_PINK)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).setStatParent(() -> Items.JAR_BUTTERFLY_PINK)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
     public static final @NotNull Block<?> JAR_BUTTERFLY_SILVER = register("jar.butterfly.silver", "minecraft:block/jar_butterfly_silver", 923, (b) -> new BlockLogicJarButterfly(b, MobButterfly.COLOR_SILVER, () -> Items.JAR_BUTTERFLY_SILVER))
-        .withSound(BlockSounds.GLASS).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.JAR_BUTTERFLY_SILVER)
+        .withSound(BlockSounds.GLASS).withHardness(0.1F).setStatParent(() -> Items.JAR_BUTTERFLY_SILVER)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
 
     public static final Block<?> SLAB_BRICK_RUBYGLASS = register("slab.brick.rubyglass", "minecraft:block/slab_brick_rubyglass", 998, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.BRICK_RUBYGLASS))
             .withSound(BlockSounds.CRYSTAL).withOverrideColor(MaterialColor.rubyglass).withLitInteriorSurface(true)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_DIAMOND = register("slab.brick.diamond", "minecraft:block/slab_brick_diamond", 999, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_DIAMOND))
-            .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+            .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_SANDSTONE = register("slab.brick.sandstone", "minecraft:block/slab_brick_sandstone", 1000, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.BRICK_SANDSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_COBBLE_PERMAFROST = register("slab.cobble.permafrost", "minecraft:block/slab_cobble_permafrost", 1001, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.COBBLE_PERMAFROST))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_PERMAFROST = register("slab.brick.permafrost", "minecraft:block/slab_brick_permafrost", 1002, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.BRICK_PERMAFROST))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_PERMAFROST_POLISHED = register("slab.permafrost.carved", "minecraft:block/slab_permafrost_carved", 1003, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.PERMAFROST_CARVED))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_IRON = register("slab.brick.iron", "minecraft:block/slab_brick_iron", 1004, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_IRON))
-        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.METAL).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_GOLD = register("slab.brick.gold", "minecraft:block/slab_brick_gold", 1005, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_GOLD))
-        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.METAL).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_STEEL = register("slab.brick.steel", "minecraft:block/slab_brick_steel", 1006, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_STEEL))
-        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.METAL).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_LAPIS = register("slab.brick.lapis", "minecraft:block/slab_brick_lapis", 1007, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_LAPIS))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_OLIVINE = register("slab.brick.olivine", "minecraft:block/slab_brick_olivine", 1008, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_OLIVINE))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_QUARTZ = register("slab.brick.quartz", "minecraft:block/slab_brick_quartz", 1009, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_QUARTZ))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicStatue> STATUE_STONE_LOWER = register("statue.stone.lower", "minecraft:block/statue_stone_lower", 1010, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_STONE))
@@ -1399,10 +1398,10 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogic> MATCHER = register("matcher", "minecraft:block/matcher", 1040, (b) -> new BlockLogicMatcher(b, false))
-        .withSound(BlockSounds.STONE).withHardness(1.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<BlockLogic> MATCHER_ACTIVE = register("matcher.active", "minecraft:block/matcher_active", 1041, (b) -> new BlockLogicMatcher(b, true))
-        .withSound(BlockSounds.STONE).withHardness(1.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> STAIRS_BRICK_RUBYGLASS = register("stairs.brick.rubyglass", "minecraft:block/stairs_brick_rubyglass", 1048, (BlockLogicSupplier<BlockLogicStairs>) b -> new BlockLogicStairs(b, Blocks.BRICK_RUBYGLASS))
@@ -1410,25 +1409,25 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_DIAMOND = register("stairs.brick.diamond", "minecraft:block/stairs_brick_diamond", 1049, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_DIAMOND))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_IRON = register("stairs.brick.iron", "minecraft:block/stairs_brick_iron", 1050, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_IRON))
-        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.METAL).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_GOLD = register("stairs.brick.gold", "minecraft:block/stairs_brick_gold", 1051, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_GOLD))
-        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.METAL).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_STEEL = register("stairs.brick.steel", "minecraft:block/stairs_brick_steel", 1052, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_STEEL))
-        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.METAL).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_LAPIS = register("stairs.brick.lapis", "minecraft:block/stairs_brick_lapis", 1053, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_LAPIS))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_OLIVINE = register("stairs.brick.olivine", "minecraft:block/stairs_brick_olivine", 1054, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_OLIVINE))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_QUARTZ = register("stairs.brick.quartz", "minecraft:block/stairs_brick_quartz", 1055, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_QUARTZ))
-        .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withSound(BlockSounds.PERMAFROST).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final @NotNull Block<?> BOULDER_MAGMATIC = register("boulder.magmatic", "minecraft:block/boulder_magmatic", 1060, BlockLogicBoulderMagmatic::new)
@@ -1439,10 +1438,10 @@ public final class Blocks {
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.SULFURIC_FIRE_OVERLAY_SOURCE);
 
     public static final @NotNull Block<BlockLogicFluid> FLUID_ACID_FLOWING = register("fluid.acid.flowing", "minecraft:block/fluid_acid_flowing", 1062, (BlockLogicSupplier<BlockLogicFluid>) b -> new BlockLogicFluidFlowing(b, Materials.ACID, new FluidAcid(), Blocks.FLUID_ACID_STILL))
-        .withHardness(100.0F).withLitInteriorSurface(true).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange()
+        .withHardness(100.0F).withLitInteriorSurface(true).withDisabledStats()
         .withTags(BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.IS_ACID);
     public static final @NotNull Block<BlockLogicFluid> FLUID_ACID_STILL = register("fluid.acid.still", "minecraft:block/fluid_acid_still", 1063, (BlockLogicSupplier<BlockLogicFluid>) b -> new BlockLogicFluidStill(b, Materials.ACID, new FluidAcid(), Blocks.FLUID_ACID_FLOWING))
-        .withHardness(100.0F).withLitInteriorSurface(true).withDisabledStats().withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> FLUID_ACID_FLOWING)
+        .withHardness(100.0F).withLitInteriorSurface(true).withDisabledStats().setStatParent(() -> FLUID_ACID_FLOWING)
         .withTags(BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.IS_ACID);
 
     public static final Block<?> EMBER = register("ember", "minecraft:block/ember", 1065, block -> new BlockLogicEmber(block, Materials.STONE))
@@ -1492,19 +1491,19 @@ public final class Blocks {
         .withSound(BlockSounds.STONE).withHardness(1.8F).withOverrideColor(MaterialColor.paintedBlack)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.NETHER_MOBS_SPAWN, BlockTags.NETHER_SURFACE_BLOCK, BlockTags.INFINITE_BURN_SULFURIC);
     public static final Block<?> SLAB_BRIMSTONE = register("slab.brimstone", "minecraft:block/slab_brimstone", 1087, block -> new BlockLogicSlab(block, BRIMSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN_SULFURIC);
     public static final Block<?> STAIRS_BRIMSTONE = register("stairs.brimstone", "minecraft:block/stairs_brimstone", 1088, block -> new BlockLogicStairs(block, BRIMSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN_SULFURIC);
     public static final Block<?> BRICK_BRIMSTONE = register("brick.brimstone", "minecraft:block/brick_brimstone", 1089, block -> new BlockLogicBrimstone(block, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.8F).withOverrideColor(MaterialColor.paintedBlack)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.NETHER_MOBS_SPAWN, BlockTags.NETHER_SURFACE_BLOCK, BlockTags.INFINITE_BURN_SULFURIC);
     public static final Block<?> SLAB_BRICK_BRIMSTONE = register("slab.brick.brimstone", "minecraft:block/slab_brick_brimstone", 1090, block -> new BlockLogicSlab(block, BRICK_BRIMSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN_SULFURIC);
     public static final Block<?> STAIRS_BRICK_BRIMSTONE = register("stairs.brick.brimstone", "minecraft:block/stairs_brick_brimstone", 1091, block -> new BlockLogicStairs(block, BRICK_BRIMSTONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
+        .withSound(BlockSounds.STONE).withLitInteriorSurface(true).withOverrideColor(MaterialColor.paintedBlack)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN_SULFURIC);
     public static final @NotNull Block<?> BRIMTHAW = register("brimthaw", "minecraft:block/brimthaw", 1092, BlockLogicBrimthaw::new)
         .withSound(BlockSounds.STONE).withHardness(1.25F).withBlastResistance(7F).withLightEmission(10).withOverrideColor(MaterialColor.paintedYellow)
@@ -1515,73 +1514,73 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.NETHER_SURFACE_BLOCK, BlockTags.NETHER_MOBS_SPAWN, BlockTags.CAVES_CUT_THROUGH, BlockTags.INFINITE_BURN_SULFURIC);
 
     public static final @NotNull Block<?> PRESSURE_PLATE_COBBLE_BASALT = register("pressureplate.cobble.basalt", "minecraft:block/pressure_plate_cobble_basalt", 1100, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.BASALT))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_COBBLE_LIMESTONE = register("pressureplate.cobble.limestone", "minecraft:block/pressure_plate_cobble_limestone", 1101, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.LIMESTONE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_COBBLE_GRANITE = register("pressureplate.cobble.granite", "minecraft:block/pressure_plate_cobble_granite", 1102, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.GRANITE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_COBBLE_PERMAFROST = register("pressureplate.cobble.permafrost", "minecraft:block/pressure_plate_cobble_permafrost", 1103, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.PERMAFROST))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_COBBLE_NETHERRACK = register("pressureplate.cobble.netherrack", "minecraft:block/pressure_plate_cobble_netherrack", 1104, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.NETHERRACK))
-        .withSound(BlockSounds.STONE).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.1F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_COBBLE_GLOOMSTONE = register("pressureplate.cobble.gloomstone", "minecraft:block/pressure_plate_cobble_gloomstone", 1105, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.GLOOMSTONE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     // 1106 and 1107 reserved for cobbled sandstone and brimstone
 
     public static final @NotNull Block<?> PRESSURE_PLATE_BASALT = register("pressureplate.basalt", "minecraft:block/pressure_plate_basalt", 1110, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.BASALT))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_LIMESTONE = register("pressureplate.limestone", "minecraft:block/pressure_plate_limestone", 1111, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.LIMESTONE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_GRANITE = register("pressureplate.granite", "minecraft:block/pressure_plate_granite", 1112, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.GRANITE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_PERMAFROST = register("pressureplate.permafrost", "minecraft:block/pressure_plate_permafrost", 1113, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.PERMAFROST))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_NETHERRACK = register("pressureplate.netherrack", "minecraft:block/pressure_plate_netherrack", 1114, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.NETHERRACK))
-        .withSound(BlockSounds.STONE).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.1F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_GLOOMSTONE = register("pressureplate.gloomstone", "minecraft:block/pressure_plate_gloomstone", 1115, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.GLOOMSTONE))
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_SANDSTONE = register("pressureplate.sandstone", "minecraft:block/pressure_plate_sandstone", 1116, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.STONE))
-        .withSound(BlockSounds.STONE).withHardness(0.4F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> PRESSURE_PLATE_BRIMSTONE = register("pressureplate.brimstone", "minecraft:block/pressure_plate_brimstone", 1117, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.STONE))
-        .withSound(BlockSounds.STONE).withHardness(0.9F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.9F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static final @NotNull Block<?> BUTTON_BASALT = register("button.basalt", "minecraft:block/button_basalt", 1120, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_LIMESTONE = register("button.limestone", "minecraft:block/button_limestone", 1121, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_GRANITE = register("button.granite", "minecraft:block/button_granite", 1122, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_PERMAFROST = register("button.permafrost", "minecraft:block/button_permafrost", 1123, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_NETHERRACK = register("button.netherrack", "minecraft:block/button_netherrack", 1124, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.1F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.1F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_GLOOMSTONE = register("button.gloomstone", "minecraft:block/button_gloomstone", 1125, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.5F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_SANDSTONE = register("button.sandstone", "minecraft:block/button_sandstone", 1126, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.4F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
     public static final @NotNull Block<?> BUTTON_BRIMSTONE = register("button.brimstone", "minecraft:block/button_brimstone", 1127, BlockLogicButton::new)
-        .withSound(BlockSounds.STONE).withHardness(0.9F).withDisabledNeighborNotifyOnMetadataChange()
+        .withSound(BlockSounds.STONE).withHardness(0.9F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
 
     public static <T extends BlockLogic> Block<T> register(String key, String namespaceId, int id, BlockLogicSupplier<T> logicSupplier) {
@@ -1607,7 +1606,6 @@ public final class Blocks {
             Arrays.fill(Blocks.isEntityTile, false);
             Arrays.fill(Blocks.lightEmission, 0);
             Arrays.fill(Blocks.lightBlock, 0);
-            Arrays.fill(Blocks.neighborNotifyOnMetadataChangeDisabled, false);
             Arrays.fill(Blocks.shouldTick, false);
         }
         translucent[0] = true;
@@ -1622,7 +1620,6 @@ public final class Blocks {
         Blocks.translucent[container.id()] = !container.getMaterial().blocksLight();
         Blocks.isEntityTile[container.id()] = container.isEntityTile;
         Blocks.lightEmission[container.id()] = container.emission;
-        Blocks.neighborNotifyOnMetadataChangeDisabled[container.id()] = container.disabledNeighborMetaNotify;
         Blocks.shouldTick[container.id()] = container.shouldTick;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java
index f6be2916f..dc471bfe8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntity.java
@@ -188,4 +188,8 @@ public abstract class TileEntity implements ICarriable
         return new CarriedBlock(holder, currentBlock, currentMeta, this);
     }
 
+    public void notifyBlocksOfNeighborChange() {
+        if (this.worldObj == null) return;
+        this.worldObj.notifyBlocksOfNeighborChange(this.tilePos, this.getBlock()); 
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java
index 3f44be8fb..8ebffe931 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java
@@ -6,6 +6,7 @@ import java.util.UUID;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.tags.ListTag;
 
+import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
@@ -68,7 +69,9 @@ public class TileEntityFlag extends TileEntity
     }
 
     public void setFlipped(boolean flag) {
+        if (this.flipped == flag) return;
         this.flipped = flag;
+        this.notifyBlocksOfNeighborChange();
     }
 
     public boolean getFlipped() {
@@ -129,7 +132,7 @@ public class TileEntityFlag extends TileEntity
                 items[slot] = ItemStack.readItemStackFromNbt(compound);
             }
         }
-        itemsChanges();
+        itemsChanged();
     }
 
     public void copyFlagNBT(CompoundTag tag) {
@@ -198,7 +201,7 @@ public class TileEntityFlag extends TileEntity
             {
                 ItemStack stack = items[slot];
                 items[slot] = null;
-                itemsChanges();
+                itemsChanged();
                 setChanged();
                 return stack;
             }
@@ -209,7 +212,7 @@ public class TileEntityFlag extends TileEntity
                 {
                     items[slot] = null;
                 }
-                itemsChanges();
+                itemsChanged();
                 setChanged();
                 return splitStack;
             }
@@ -230,11 +233,12 @@ public class TileEntityFlag extends TileEntity
     {
         slot -= 36; // This seems so wrong and will almost certainly cause an issue at some point
         items[slot] = stack;
-        itemsChanges();
+        itemsChanged();
         setChanged();
+        this.notifyBlocksOfNeighborChange();
     }
 
-    private void itemsChanges() {
+    private void itemsChanged() {
         activeDyes = 0;
         for (int i = 0; i < items.length; i++) {
             ItemStack s = items[i];
@@ -251,6 +255,7 @@ public class TileEntityFlag extends TileEntity
             colorHash ^= flagColors[i] << (8 * (i & 0b11));
         }
         isDirty = true;
+        this.notifyBlocksOfNeighborChange();
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
index 557c0796f..2d8719ed7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
@@ -85,6 +85,7 @@ public class TileEntityMeshGold extends TileEntityMesh {
         }
         filterItem = null;
         setChanged();
+        this.notifyBlocksOfNeighborChange();
         return success | !wasNull;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMobSpawner.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMobSpawner.java
index 923f9ec7b..b6f43313c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMobSpawner.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMobSpawner.java
@@ -45,6 +45,7 @@ public class TileEntityMobSpawner extends TileEntity {
         } catch (Exception e) {
             LOGGER.error("Failed to convert legacy mobspawner id!", e);
         }
+        this.notifyBlocksOfNeighborChange();
     }
 
     public boolean anyPlayerInRange() {
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java
index fb64b5fa6..d3f7f5568 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySign.java
@@ -70,7 +70,12 @@ public class TileEntitySign extends TileEntity
             this.owner = ownerUUID;
         }
     }
-    
+
+    @Override
+    public void setChanged() {
+        super.setChanged();
+    }
+
     public boolean isEditableBy(Player player)
     {
         return player.uuid.equals(owner) && !locked;
@@ -87,13 +92,8 @@ public class TileEntitySign extends TileEntity
 
     public void setPicture(@Nullable EnumSignPicture picture)
     {
-        if (picture == null)
-        {
-            selectedPicture = 0;
-            return;
-        }
-
-        selectedPicture = picture.getId();
+        this.selectedPicture = (picture == null) ? 0 : picture.getId();
+        this.notifyBlocksOfNeighborChange();
     }
     
     public TextFormatting getColor()
@@ -106,6 +106,7 @@ public class TileEntitySign extends TileEntity
     public void setColor(TextFormatting color)
     {
         selectedColor = color.id;
+        this.notifyBlocksOfNeighborChange();
     }
 
     public boolean isGlowing() {
@@ -114,6 +115,7 @@ public class TileEntitySign extends TileEntity
 
     public void setGlowing(boolean glowing) {
         this.glowing = glowing;
+        this.notifyBlocksOfNeighborChange();
     }
 
     public boolean isLocked() {
@@ -122,6 +124,7 @@ public class TileEntitySign extends TileEntity
 
     public void setLocked(boolean locked) {
         this.locked = locked;
+        this.notifyBlocksOfNeighborChange();
     }
 
     public void finalizeEditor(@NotNull Player editor) {
@@ -132,6 +135,7 @@ public class TileEntitySign extends TileEntity
         if (!allowColorCode) for(int i = 0; i < 4; i++) {
             signText[i] = TextFormatting.removeAllColorFormatting(signText[i]);
         }
+        this.notifyBlocksOfNeighborChange();
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityStatue.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityStatue.java
index 086a2a629..9489ce6a2 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityStatue.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityStatue.java
@@ -125,6 +125,7 @@ public class TileEntityStatue
     public void setPose(final @NotNull Pose pose) {
         this.pose = pose;
         setChanged();
+        this.notifyBlocksOfNeighborChange();
     }
 
     public void nextPose() {
@@ -140,6 +141,7 @@ public class TileEntityStatue
     public void setItemInArmorSlot(final @NotNull HumanArmorShape slot, final @Nullable ItemStack item) {
         this.armorPieces[slot.getSlotIndex()] = item;
         setChanged();
+        this.notifyBlocksOfNeighborChange();
     }
 
     @Override
@@ -163,6 +165,7 @@ public class TileEntityStatue
     @Override
     public void setHeldItem(@Nullable ItemStack item) {
         this.heldItem = item;
+        this.notifyBlocksOfNeighborChange();
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java
index 63372dce4..fc2e937fc 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java
@@ -134,16 +134,12 @@ public class BlockLogicPistonMoving extends BlockLogic {
     }
 
     @Override
-    public @NotNull MatcherSnapshot resolveForMatcher(@NotNull World world, @NotNull TilePosc tilePos) {
-        if (world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving) {
-            final Block<?> block = moving.movingBlock();
-            return new MatcherSnapshot(block, moving.movingBlockData(), block.getLogic());
-        }
-        return super.resolveForMatcher(world, tilePos);
+    public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) {
+        return Material.PISTON_CANT_PUSH;
     }
 
     @Override
-    public int getPistonPushReaction(@NotNull World world, @NotNull TilePosc tilePos) {
-        return Material.PISTON_CANT_PUSH;
+    public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
+        return false;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java b/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java
index 73777cce1..b10687c05 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemDoor.java
@@ -2,11 +2,8 @@ package net.minecraft.core.item;
 
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicDoor;
-import net.minecraft.core.block.entity.TileEntityActivator;
-import net.minecraft.core.block.support.ISupport;
 import net.minecraft.core.block.support.PartialSupport;
 import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.enums.EnumBlockSoundEffectType;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.util.helper.Side;
@@ -16,8 +13,6 @@ import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.Random;
-
 public class ItemDoor extends ItemPlaceablePair {
     public ItemDoor(@NotNull String name, @NotNull String namespaceId, int id, @NotNull Block<? extends BlockLogicDoor> doorBlockBottom, @NotNull Block<? extends BlockLogicDoor> doorBlockTop) {
         super(name, namespaceId, id, doorBlockBottom, doorBlockTop);
@@ -86,8 +81,6 @@ public class ItemDoor extends ItemPlaceablePair {
     @Override
     public boolean canPlaceDirectlyAtPosition(@NotNull ItemStack selfStack, @NotNull World world,
             @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        return 
-            IPlaceable.canPlaceBlockDirectlyAtPosition(this.blockA, world, blockPos, side) &&
-            IPlaceable.canPlaceBlockDirectlyAtPosition(this.blockA, world, blockPos, side);
+        return world.canPlaceInsideBlock(blockPos) && world.canPlaceInsideBlock(blockPos.up(new TilePos()));
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPlaceablePair.java b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceablePair.java
index 0b2c38152..b3ca78b96 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemPlaceablePair.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceablePair.java
@@ -109,9 +109,9 @@ public abstract class ItemPlaceablePair extends Item implements IPlaceable {
         final boolean isAIdentical, isBIdentical;
 
         prevBlockA = world.getBlockType(posA);
-        prevDataA = world.getBlockData(posA);
-
         prevBlockB = world.getBlockType(posB);
+
+        prevDataA = world.getBlockData(posA);
         prevDataB = world.getBlockData(posB);
         
         isAIdentical = prevBlockA == this.blockA && prevDataA == dataA;
@@ -147,8 +147,8 @@ public abstract class ItemPlaceablePair extends Item implements IPlaceable {
         if (isAIdentical != isBIdentical) {
             if (isAIdentical) world.notifyBlocksOfNeighborChange(posB, this.blockB);
             else world.notifyBlocksOfNeighborChange(posA, this.blockA);
-        } else if (isAIdentical) {
-            assert isBIdentical;
+        } else if (!isAIdentical) {
+            assert !isBIdentical;
             world.notifyBlocksOfNeighborChanges(new TilePosc[] { posA, posB }, null);
         }
         world.playBlockSoundEffect(
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemStack.java b/game/core/src/main/java/net/minecraft/core/item/ItemStack.java
index 998e08a73..7cda51a62 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemStack.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemStack.java
@@ -369,27 +369,29 @@ public final class ItemStack {
     }
 
     public static boolean areItemStacksEqual(@Nullable ItemStack stack1, @Nullable ItemStack stack2) {
-        if(stack1 == null && stack2 == null) {
-            return true;
-        }
-        if(stack1 == null || stack2 == null) {
-            return false;
-        }
-        return stack1.isItemStackEqual(stack2);
+        if (stack1 == stack2) return true;
+        if (stack1 == null || stack2 == null) return false;
+        return stack1.stackSize == stack2.stackSize &&
+            stack1.itemID == stack2.itemID && stack1.metadata == stack2.metadata;
+    }
+    
+    public boolean isItemStackEqual(@NotNull ItemStack itemstack) {
+        if (this == itemstack) return true;
+        if (itemstack == null) return false;
+        return this.stackSize == itemstack.stackSize &&
+            this.itemID == itemstack.itemID && this.metadata == itemstack.metadata;
     }
 
-    private boolean isItemStackEqual(@NotNull ItemStack itemstack) {
-        if(this.stackSize != itemstack.stackSize) {
-            return false;
-        }
-        if(this.itemID != itemstack.itemID) {
-            return false;
-        }
-        return this.metadata == itemstack.metadata;
+    public static boolean areItemsEqual(@Nullable ItemStack stack1, @Nullable ItemStack stack2) {
+        if (stack1 == stack2) return true;
+        if (stack1 == null || stack2 == null) return false;
+        return stack1.itemID == stack2.itemID && stack1.metadata == stack2.metadata;
     }
 
     public boolean isItemEqual(@Nullable ItemStack itemstack) {
-        return itemstack != null && this.itemID == itemstack.itemID && this.metadata == itemstack.metadata;
+        if (this == itemstack) return true;
+        if (itemstack == null) return false;
+        return this.itemID == itemstack.itemID && this.metadata == itemstack.metadata;
     }
 
     public @NotNull String getItemKey() {
diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java
index 4ba690e00..7c27f8209 100644
--- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java
+++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLadder.java
@@ -27,14 +27,16 @@ public class ItemBlockLadder<T extends BlockLogicLadder> extends ItemBlock<T> {
         final TilePos bp = new TilePos(blockPos);
         final @NotNull BlockLogicLadder ladder = this.block.getLogic();
 
-        final Side pside;
+        final @NotNull Side pside;
         if ((player != null && player.isSneaking()) || world.getBlockType(bp) != this.block) {
             if (super.shouldShiftOutOf(selfStack, world, player, bp, side, xHit, yHit)) bp.add(side.direction());
             pside = ladder.getSideForPlacement(world, bp, side);
+            if (pside == null) return false;
         } else {
             xHit = 0.5;
             yHit = 0.5;
             pside = ladder.getSideFromMeta(world.getBlockData(bp));
+            if (pside == Side.NONE) return false;
             while (world.getBlockType(bp) == this.block && ladder.getSideFromMeta(world.getBlockData(bp)) == pside) {
                 bp.down();
             }
diff --git a/game/core/src/main/java/net/minecraft/core/world/World.java b/game/core/src/main/java/net/minecraft/core/world/World.java
index d69e43401..0e2a2d058 100644
--- a/game/core/src/main/java/net/minecraft/core/world/World.java
+++ b/game/core/src/main/java/net/minecraft/core/world/World.java
@@ -708,17 +708,12 @@ public abstract class World implements MutableWorldSource {
     }
 
     public boolean setBlockDataNotify(final @NotNull TilePosc tilePos, final int data) {
-        if (this.setBlockData(tilePos, data)) {
-            this.markBlockNeedsUpdate(tilePos);
-
-            final @NotNull Block<?> block = this.getBlockType(tilePos);
-            if (block.neighborNotifyOnDataChangeDisabled()) {
-                this.notifyBlocksOfNeighborChange(tilePos, block);
-                return true;
-            }
-        }
+        if (!this.setBlockData(tilePos, data)) return false;
+        this.markBlockNeedsUpdate(tilePos);
 
-        return false;
+        final @NotNull Block<?> block = this.getBlockType(tilePos);
+        this.notifyBlocksOfNeighborChange(tilePos, block);
+        return true;
     }
 
     @Deprecated
