diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/WorldRenderExtensions.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/WorldRenderExtensions.java
deleted file mode 100644
index a104747b7..000000000
--- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/WorldRenderExtensions.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.fabricmc.fabric.test.renderer;
-
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.World;
-
-/**
- * Extension interface for a world to notify the world that a block needs to be re-rendered.
- */
-public interface WorldRenderExtensions {
-	static void scheduleBlockRerender(World world, BlockPos pos) {
-		((WorldRenderExtensions) world).scheduleBlockRerender(pos);
-	}
-
-	void scheduleBlockRerender(BlockPos pos);
-}
diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/mixin/ClientWorldMixin.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/mixin/ClientWorldMixin.java
deleted file mode 100644
index 6d8c5febf..000000000
--- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/mixin/ClientWorldMixin.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.fabricmc.fabric.test.renderer.mixin;
-
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-
-import net.minecraft.client.render.WorldRenderer;
-import net.minecraft.client.world.ClientWorld;
-import net.minecraft.util.math.BlockPos;
-
-@Mixin(ClientWorld.class)
-abstract class ClientWorldMixin extends WorldMixin {
-	@Shadow
-	@Final
-	private WorldRenderer worldRenderer;
-
-	@Override
-	public void scheduleBlockRerender(BlockPos pos) {
-		// Update the block at the position to trigger chunk re-render.
-		this.worldRenderer.updateBlock(null, pos, null, null, 0);
-	}
-}
diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/mixin/WorldMixin.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/mixin/WorldMixin.java
deleted file mode 100644
index 03903b9fb..000000000
--- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/mixin/WorldMixin.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.fabricmc.fabric.test.renderer.mixin;
-
-import org.spongepowered.asm.mixin.Mixin;
-
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.World;
-
-import net.fabricmc.fabric.test.renderer.WorldRenderExtensions;
-
-@Mixin(World.class)
-abstract class WorldMixin implements WorldRenderExtensions {
-	@Override
-	public void scheduleBlockRerender(BlockPos pos) {
-		// Do nothing, the client world will do things here
-	}
-}
diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlock.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlock.java
index 8dd4a6542..74e5dfafe 100644
--- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlock.java
+++ b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlock.java
@@ -49,25 +49,22 @@ public final class FrameBlock extends Block implements BlockEntityProvider, Fabr
 
 	@Override
 	public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
-		if (world.isClient()) {
-			return ActionResult.PASS;
-		}
-
-		BlockEntity blockEntity = world.getBlockEntity(pos);
-
-		if (blockEntity instanceof FrameBlockEntity) {
+		if (world.getBlockEntity(pos) instanceof FrameBlockEntity frame) {
 			ItemStack stack = player.getStackInHand(hand);
 			Block handBlock = Block.getBlockFromItem(stack.getItem());
 
 			@Nullable
-			Block currentBlock = ((FrameBlockEntity) blockEntity).getBlock();
+			Block currentBlock = frame.getBlock();
 
 			if (stack.isEmpty()) {
 				// Try to remove if the stack in hand is empty
 				if (currentBlock != null) {
-					player.getInventory().offerOrDrop(new ItemStack(currentBlock));
-					((FrameBlockEntity) blockEntity).setBlock(null);
-					return ActionResult.SUCCESS;
+					if (!world.isClient()) {
+						player.getInventory().offerOrDrop(new ItemStack(currentBlock));
+						frame.setBlock(null);
+					}
+
+					return ActionResult.success(world.isClient());
 				}
 
 				return ActionResult.PASS;
@@ -83,12 +80,17 @@ public final class FrameBlock extends Block implements BlockEntityProvider, Fabr
 				return ActionResult.FAIL;
 			}
 
-			if (currentBlock != null) {
-				player.getInventory().offerOrDrop(new ItemStack(currentBlock));
+			stack.decrement(1);
+
+			if (!world.isClient()) {
+				if (currentBlock != null) {
+					player.getInventory().offerOrDrop(new ItemStack(currentBlock));
+				}
+
+				frame.setBlock(handBlock);
 			}
 
-			((FrameBlockEntity) blockEntity).setBlock(handBlock);
-			return ActionResult.SUCCESS;
+			return ActionResult.success(world.isClient());
 		}
 
 		return ActionResult.FAIL;
diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlockEntity.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlockEntity.java
index ec72f2304..ccbfa90aa 100644
--- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlockEntity.java
+++ b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/FrameBlockEntity.java
@@ -30,7 +30,6 @@ import net.minecraft.registry.Registries;
 
 import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity;
 import net.fabricmc.fabric.api.util.NbtType;
-import net.fabricmc.fabric.test.renderer.WorldRenderExtensions;
 
 public final class FrameBlockEntity extends BlockEntity implements RenderAttachmentBlockEntity {
 	@Nullable
@@ -51,7 +50,8 @@ public final class FrameBlockEntity extends BlockEntity implements RenderAttachm
 		}
 
 		if (this.getWorld() != null && this.getWorld().isClient()) {
-			WorldRenderExtensions.scheduleBlockRerender(this.getWorld(), this.getPos());
+			// This call forces a chunk remesh.
+			world.updateListeners(pos, null, null, 0);
 		}
 	}
 
@@ -59,6 +59,9 @@ public final class FrameBlockEntity extends BlockEntity implements RenderAttachm
 	public void writeNbt(NbtCompound tag) {
 		if (this.block != null) {
 			tag.putString("block", Registries.BLOCK.getId(this.block).toString());
+		} else {
+			// Always need something in the tag, otherwise S2C syncing will never apply the packet.
+			tag.putInt("block", -1);
 		}
 	}
 
diff --git a/fabric-renderer-api-v1/src/testmod/resources/fabric-renderer-api-v1-testmod.mixins.json b/fabric-renderer-api-v1/src/testmod/resources/fabric-renderer-api-v1-testmod.mixins.json
deleted file mode 100644
index 660d647f8..000000000
--- a/fabric-renderer-api-v1/src/testmod/resources/fabric-renderer-api-v1-testmod.mixins.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "required": true,
-  "package": "net.fabricmc.fabric.test.renderer.mixin",
-  "compatibilityLevel": "JAVA_16",
-  "mixins": [
-    "WorldMixin"
-  ],
-  "client": [
-    "ClientWorldMixin"
-  ],
-  "injectors": {
-    "defaultRequire": 1
-  }
-}
diff --git a/fabric-renderer-api-v1/src/testmod/resources/fabric.mod.json b/fabric-renderer-api-v1/src/testmod/resources/fabric.mod.json
index 45037a1a9..1fd965e71 100644
--- a/fabric-renderer-api-v1/src/testmod/resources/fabric.mod.json
+++ b/fabric-renderer-api-v1/src/testmod/resources/fabric.mod.json
@@ -16,8 +16,5 @@
     "client": [
       "net.fabricmc.fabric.test.renderer.simple.client.RendererClientTest"
     ]
-  },
-  "mixins": [
-    "fabric-renderer-api-v1-testmod.mixins.json"
-  ]
+  }
 }