diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height3.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height3.json
index c70e1c9c0..89df3d516 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/layer/height3.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height3.json
@@ -17,7 +17,7 @@
 			"faces": {
 				"north": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "north"},
 				"east": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "east"},
-				"south": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "south"},
+				"south": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "south"},
 				"west": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "west"},
 				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
 				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
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 bd75af502..32cf8f1b6 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
@@ -11,6 +11,7 @@ import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.enums.EnumSleepStatus;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
@@ -111,23 +112,50 @@ public class BlockLogicBed
 
     @Override
     public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
-        this.removeOtherHalf(world, tilePos);
+        final var state = new State(world, tilePos);
+        if (!state.hasOtherHalf(world, tilePos)) {
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
+        }
     }
 
     @Override
     public void onRemoved(final @NotNull World world, final @NotNull TilePosc tilePos, final int data) {
-        this.removeOtherHalf(world, tilePos);
+        final var state = new State(data, world, tilePos);
+        if (state.hasOtherHalf(world, tilePos)) {
+            // eventhough onNeighborChanged would normally be able to handle the removal of
+            // the other half, however piston will break this half without emitting neighbor
+            // update untill it finishes extending, destroying the other half before which
+            // would result in a dupe.
+            world.setBlockTypeNotify(state.otherPos(tilePos), Blocks.AIR);
+        }
     }
 
-    protected void removeOtherHalf(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        final int data = world.getBlockData(tilePos);
-        final int direction = getDirection(data);
-        if (isBlockHeadOfBed(data)) {
-            if (world.getBlockType(tilePos.sub(headBlockToFootBlockMap[direction].getDirection(), new TilePos())) != this.block) {
-                world.setBlockTypeNotify(tilePos, Blocks.AIR);
-            }
-        } else if (world.getBlockType(tilePos.add(headBlockToFootBlockMap[direction].getDirection(), new TilePos())) != this.block) {
-            world.setBlockTypeNotify(tilePos, Blocks.AIR);
+    protected static class State {
+        final boolean isHead;
+        final @NotNull Direction h2fDir;
+
+        public State(int data, final @NotNull World world, @NotNull TilePosc tilePos) {
+            isHead = isBlockHeadOfBed(data);
+            h2fDir = headBlockToFootBlockMap[getDirection(data)].getDirection();
+        }
+
+        public State(final @NotNull World world, @NotNull TilePosc tilePos) {
+            this(world.getBlockData(tilePos), world, tilePos);
+        }    
+
+        public @NotNull TilePos otherPos(@NotNull TilePosc tilePos) {
+            return (isHead)
+                ? tilePos.sub(h2fDir, new TilePos())
+                : tilePos.add(h2fDir, new TilePos());
+        }
+
+        public boolean hasOtherHalf(final @NotNull World world, @NotNull TilePosc tilePos) {
+            final var otherPos = otherPos(tilePos);
+            if (!(world.getBlockType(otherPos).getLogic() instanceof BlockLogicBed)) return false;
+            final var otherState = new State(world, otherPos);
+            if (this.isHead == otherState.isHead) return false;
+            if (this.h2fDir != otherState.h2fDir) return false;
+            return true;
         }
     }
 
@@ -141,12 +169,12 @@ public class BlockLogicBed
         return Material.PISTON_DESTROY_ON_PUSH;
     }
 
-    public static final int MASK_IS_FOOT = 0b0000_1000;
+    public static final int MASK_IS_HEAD = 0b0000_1000;
     public static final int MASK_IS_OCCUPIED = 0b0000_0100;
     public static final int MASK_DIRECTION = 0b0000_0011;
 
     public static boolean isBlockHeadOfBed(final int meta) {
-        return (meta & MASK_IS_FOOT) != 0;
+        return (meta & MASK_IS_HEAD) != 0;
     }
 
     public static boolean isBedOccupied(final int meta) {
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java
index 025325c56..223ca8dbc 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDispenser.java
@@ -83,7 +83,9 @@ public class BlockLogicDispenser extends BlockLogicVeryRotatable {
                 world.playBlockEvent(tilePos, LevelListener.EVENT_DISPENSER_PROJECTILE, 0);
             } else {
                 if (itemStack.consumeItem(null)) {
-                    final @NotNull EntityItem item = new EntityItem(world, pos.x(), pos.y() + (direction == Direction.UP ? 0.25d : -0.3D), pos.z(), new ItemStack(itemStack.getItem()));
+                    final var newStack = itemStack.copy();
+                    newStack.stackSize = 1;
+                    final @NotNull EntityItem item = new EntityItem(world, pos.x(), pos.y() + (direction == Direction.UP ? 0.25d : -0.3D), pos.z(), newStack);
                     final double randOffset = random.nextDouble() * 0.1D + 0.2D;
                     item.xd = (double) xOffset * randOffset;
                     item.yd = (double) yOffset + (direction == Direction.UP ? -0.65D : 0.2D);
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 b49460db6..15de385de 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
@@ -203,21 +203,35 @@ public class BlockLogicStatue extends BlockLogic {
                 world.dropItem(tilePos, stack);
             }
         }
+        // Piston does not emit neighbor update when begin extending.
+        // By removing the other half first, this fixes a dupe.
+        // This is intentionally setBlockType instead of setBlockTypeNotify!
+        removeOtherHalf(world, tilePos);
     }
-
+    
     @Override
     public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
-        final Block<?> otherBlock;
-        if (!this.isBottom) {
-            otherBlock = world.getBlockType(tilePos.down(new TilePos()));
-        } else {
-            otherBlock = world.getBlockType(tilePos.up(new TilePos()));
-        }
-        if (!(otherBlock.getLogic() instanceof BlockLogicStatue)) {
+        if (!isOtherHalf(world, getOtherHalfPos(tilePos))) {
             world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
+    private void removeOtherHalf(@NotNull World world, @NotNull TilePosc tilePos) {
+        final var otherPos = getOtherHalfPos(tilePos);
+        if (isOtherHalf(world, otherPos)) {
+            world.setBlockTypeNotify(otherPos, Blocks.AIR);
+        }    
+    }
+
+    private boolean isOtherHalf(@NotNull World world, @NotNull TilePosc tilePos) {
+        return world.getBlockType(tilePos).getLogic() instanceof BlockLogicStatue other
+            && (other.isBottom != this.isBottom);
+    }
+
+    private @NotNull TilePos getOtherHalfPos(@NotNull TilePosc tilePos) {
+        return (this.isBottom) ? tilePos.up(new TilePos()) : tilePos.down(new TilePos());
+    }
+
     @Override
     public @NotNull ItemStack @Nullable [] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, @NotNull TilePosc tilePos, int data, @Nullable TileEntity tileEntity) {
         if (this.droppedItem == null) return null;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java
index 48f899f66..ecc469711 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicWireRedstone.java
@@ -23,6 +23,8 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Random;
 import java.util.Set;
+import java.util.function.Predicate;
+import java.util.logging.Logger;
 
 public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
     public static final int SIGNAL_MIN = 0;
@@ -73,6 +75,14 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
         }
     }
 
+    private void transmutate(Predicate<Block<?>> condition, @NotNull World world, @NotNull TilePosc curPos, int data) {
+        final @NotNull Block<?> block = world.getBlockType(curPos);
+        if (!condition.test(block)) return;
+        if (world.setBlockData(curPos, data)) {
+            world.markBlockNeedsUpdate(curPos);
+        }
+    }
+
     private void updatePowerStrength(@NotNull World world, @NotNull TilePosc curPos, @NotNull TilePosc lastPos) {
         int strength = world.getBlockData(curPos);
         int newStrength = 0;
@@ -114,13 +124,10 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
             }
         }
         if (strength != newStrength) {
-            final @NotNull Block<?> block = world.getBlockType(curPos);
-            if (block == this.block || block == Blocks.FLUID_LAVA_STILL || block == Blocks.FLUID_LAVA_FLOWING) { // Intentionally keeping lava transmutation, do not delete carelessly
-                world.noNeighborUpdate = true;                                                                   //                                                             only carefully
-                world.setBlockDataNotify(curPos, newStrength | (world.getBlockData(curPos) & MASK_DIRECTION));
-                world.markBlocksDirty(curPos, curPos);
-                world.noNeighborUpdate = false;
-            }
+            transmutate(
+                b -> b == this.block || b == Blocks.FLUID_LAVA_STILL || b == Blocks.FLUID_LAVA_FLOWING,
+                world, curPos, newStrength | (world.getBlockData(curPos) & MASK_DIRECTION)
+            );
             for (int i = 0; i < 4; i++) {
                 int checkX = curPos.x();
                 int checkY = curPos.y() - 1;
@@ -225,7 +232,11 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
         TilePos queryPos = new TilePos();
         world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
         world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
-//        updatePowerStrength(world, x, y, z);
+        transmutate(
+            b -> b == this.block || b == Blocks.FLUID_LAVA_STILL || b == Blocks.FLUID_LAVA_FLOWING,
+            world, tilePos, data
+        );
+        // updatePowerStrength(world, x, y, z);
         world.getWireHandler().onWireRemoved(tilePos, new BlockState(this.block, world.getBlockData(tilePos)));
         checkCornerChangeAt(world, tilePos.west(queryPos));
         checkCornerChangeAt(world, tilePos.east(queryPos));
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobSkeleton.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobSkeleton.java
index 0d0d425ec..21a1d54af 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobSkeleton.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobSkeleton.java
@@ -46,7 +46,7 @@ public class MobSkeleton extends MobMonsterArmored<HumanArmorShape>
     @Override
 	protected String getDeathSound()
     {
-        return "mob.skeletonhurt";
+        return "mob.skeletondeath";
     }
     @Override
     protected void defineSynchedData()
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemBed.java b/game/core/src/main/java/net/minecraft/core/item/ItemBed.java
index 9c4a28593..22efccf38 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemBed.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemBed.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.item;
 
+import net.minecraft.core.block.BlockLogicBed;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.EnumBlockSoundEffectType;
@@ -28,8 +29,10 @@ public class ItemBed extends Item {
         if (world.isAirBlock(pos) && world.isAirBlock(pos2) && world.canPlaceOnSurfaceOfBlock(pos.down(new TilePos())) && world.canPlaceOnSurfaceOfBlock(pos2.down(new TilePos()))) {
             if (world.canBlockIdBePlacedAt(Blocks.BED.id(), pos, false, side) && selfStack.consumeItem(player)) {
                 world.playBlockSoundEffect(player, pos.x() + 0.5F, pos.y() + 0.5F, pos.z() + 0.5F, Blocks.BED, EnumBlockSoundEffectType.PLACE);
-                world.setBlockTypeDataNotify(pos, Blocks.BED, dir.getHorizontalIndex());
-                world.setBlockTypeDataNotify(pos2, Blocks.BED, dir.getHorizontalIndex() | 0b1000);
+                world.setBlockTypeData(pos, Blocks.BED, dir.getHorizontalIndex());
+                world.setBlockTypeData(pos2, Blocks.BED, dir.getHorizontalIndex() | BlockLogicBed.MASK_IS_HEAD);
+                world.notifyBlockChange(pos, Blocks.BED);
+                world.notifyBlockChange(pos2, Blocks.BED);
                 return true;
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java b/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java
index ed98f02db..9418e8ead 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemBucket.java
@@ -65,8 +65,11 @@ public class ItemBucket extends Item {
             if (this.blockToPlace == Blocks.FLUID_WATER_FLOWING) {
                 world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, rayCastPos.x + 0.5F, rayCastPos.y + 0.5F, rayCastPos.z + 0.5F, "liquid.splash", 0.5f, 1.0f);
             }
+            final var replacedBlock = world.getBlockType(rayCastPos);
+            final var replacedMeta = world.getBlockData(rayCastPos);
             world.setBlockTypeNotify(rayCastPos, this.blockToPlace);
-            world.getBlockType(rayCastPos).dropWithCause(world, EnumDropCause.WORLD, rayCastPos, world.getBlockData(rayCastPos), null, null);
+            replacedBlock.dropWithCause(world, EnumDropCause.WORLD, rayCastPos, replacedMeta, null, null);
+                // is this being called afterwards intentional? 
 
             player.swingItem();
             if (player.getGamemode().hasBlockConsumption()) {
