diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelComparer.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelComparer.java
new file mode 100644
index 000000000..03b192444
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelComparer.java
@@ -0,0 +1,52 @@
+package net.minecraft.client.render.block.model;
+
+import net.minecraft.client.render.texture.stitcher.IconCoordinate;
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.BlockLogic;
+import net.minecraft.core.block.BlockLogicActivator;
+import net.minecraft.core.block.BlockLogicVeryRotatable;
+import net.minecraft.core.block.material.Material;
+import net.minecraft.core.util.helper.Axis;
+import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.world.WorldSource;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Random;
+
+public class BlockModelComparer<T extends BlockLogic> extends BlockModelVeryRotatable<T> {
+    public IconCoordinate[] frontVariants;
+    public IconCoordinate[] frontOverlayVariants;
+    public final Random random = new Random();
+
+    public BlockModelComparer(Block<T> block, boolean isPowered) {
+        super(block);
+        frontVariants = new IconCoordinate[4];
+        frontOverlayVariants = new IconCoordinate[frontVariants.length];
+        for (int i = 0; i < frontVariants.length; i++) {
+            frontVariants[i] = TextureRegistry.getTexture("minecraft:block/comparer/front" + (isPowered ? "_active" : "") + i);
+            frontOverlayVariants[i] = TextureRegistry.getTexture("minecraft:block/comparer/front" + (isPowered ? "_active" : "") + "_overlay" + i);
+        }
+    }
+
+    @Override
+    public @Nullable IconCoordinate getBlockTexture(WorldSource blockAccess, int x, int y, int z, Side side) {
+        Side rotated = getRotatedSide(side, blockAccess.getBlockMetadata(x, y, z));
+        if (rotated.getAxis() == Axis.Z) {
+            random.setSeed(x * 374761393 + y * 668265263 + z * 968290493);
+            return frontVariants[random.nextInt(frontVariants.length)];
+        }
+        return super.getBlockTexture(blockAccess, x, y, z, side);
+    }
+
+    @Override
+    public @Nullable IconCoordinate getBlockOverbrightTexture(WorldSource blockAccess, int x, int y, int z, @NotNull Side side) {
+        Side rotated = getRotatedSide(side, blockAccess.getBlockMetadata(x, y, z));
+        if (rotated.getAxis() == Axis.Z) {
+            random.setSeed(x * 374761393 + y * 668265263 + z * 968290493);
+            return frontOverlayVariants[random.nextInt(frontVariants.length)];
+        }
+        return super.getBlockOverbrightTexture(blockAccess, x, y, z, side);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
index 60b10cab3..8655dc88c 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
@@ -808,6 +808,16 @@ public final class BlockModelDispatcher
         addDispatch(new BlockModelEmpty<>(Blocks.STATUE_PIGMAN_LOWER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/marble"));
         addDispatch(new BlockModelEmpty<>(Blocks.STATUE_PIGMAN_UPPER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/marble"));
 
+        addDispatch(new BlockModelComparer<>(Blocks.COMPARER, false)
+            .setTex(BLOCK_TEXTURES, "minecraft:block/comparer/side", Side.TOP, Side.BOTTOM, Side.EAST, Side.WEST)
+            .setTex(BLOCK_TEXTURES, "minecraft:block/comparer/front0", Side.NORTH, Side.SOUTH)
+            .setTex(OVERBRIGHT_TEXTURES, "minecraft:block/comparer/front_overlay0", Side.NORTH, Side.SOUTH));
+
+        addDispatch(new BlockModelComparer<>(Blocks.COMPARER_ACTIVE, true)
+            .setTex(BLOCK_TEXTURES, "minecraft:block/comparer/side_active", Side.TOP, Side.BOTTOM, Side.EAST, Side.WEST)
+            .setTex(BLOCK_TEXTURES, "minecraft:block/comparer/front0", Side.NORTH, Side.SOUTH)
+            .setTex(OVERBRIGHT_TEXTURES, "minecraft:block/comparer/front_active_overlay0", Side.NORTH, Side.SOUTH)
+            .setTex(OVERBRIGHT_TEXTURES, "minecraft:block/comparer/side_active_overlay", Side.WEST, Side.EAST, Side.BOTTOM, Side.TOP));
     }
 }
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java
index 265a7febd..9613b9034 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelVeryRotatable.java
@@ -33,6 +33,11 @@ public class BlockModelVeryRotatable<T extends BlockLogic> extends BlockModelSta
         if (dir == Direction.DOWN || dir == Direction.UP) {
             renderBlocks.uvRotateSouth = 1;
             renderBlocks.uvRotateNorth = 2;
+            renderBlocks.uvRotateEast = 1;
+            renderBlocks.uvRotateWest = 2;
+        } else if (dir == Direction.NORTH || dir == Direction.SOUTH) {
+            renderBlocks.uvRotateTop = 1;
+            renderBlocks.uvRotateBottom = 1;
         }
         final boolean result = super.render(tessellator, worldSource, x, y, z);
         renderBlocks.resetRenderBlocks();
@@ -43,7 +48,10 @@ public class BlockModelVeryRotatable<T extends BlockLogic> extends BlockModelSta
 
     @Override
     public void renderStandalone(@NotNull Tessellator tessellator, int metadata, float brightness, float alpha, @Nullable Integer lightmapCoordinate) {
+        renderBlocks.uvRotateTop = 1;
+        renderBlocks.uvRotateBottom = 1;
         super.renderStandalone(tessellator, 3, brightness, alpha, lightmapCoordinate);
+        renderBlocks.resetRenderBlocks();
     }
 
     @Override
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front0.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front0.png
new file mode 100644
index 000000000..c8359ceb0
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front0.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front0.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front0.png.mcmeta
new file mode 100644
index 000000000..6c67b115b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front0.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 80
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front1.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front1.png
new file mode 100644
index 000000000..ae6babd8e
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front1.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front1.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front1.png.mcmeta
new file mode 100644
index 000000000..fe63ba1cc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front1.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 90
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front2.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front2.png
new file mode 100644
index 000000000..4e9f25c1e
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front2.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front2.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front2.png.mcmeta
new file mode 100644
index 000000000..0c408636c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front2.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 60
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front3.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front3.png
new file mode 100644
index 000000000..7eb1cdce0
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front3.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front3.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front3.png.mcmeta
new file mode 100644
index 000000000..893e25fb8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front3.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 100
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active0.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active0.png
new file mode 100644
index 000000000..672cfd148
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active0.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active0.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active0.png.mcmeta
new file mode 100644
index 000000000..6c67b115b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active0.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 80
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active1.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active1.png
new file mode 100644
index 000000000..f95722d49
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active1.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active1.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active1.png.mcmeta
new file mode 100644
index 000000000..fe63ba1cc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active1.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 90
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active2.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active2.png
new file mode 100644
index 000000000..bf9c77c46
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active2.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active2.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active2.png.mcmeta
new file mode 100644
index 000000000..0c408636c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active2.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 60
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active3.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active3.png
new file mode 100644
index 000000000..041ee079c
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active3.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active3.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active3.png.mcmeta
new file mode 100644
index 000000000..893e25fb8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active3.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 100
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay0.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay0.png
new file mode 100644
index 000000000..f62911909
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay0.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay0.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay0.png.mcmeta
new file mode 100644
index 000000000..6c67b115b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay0.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 80
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay1.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay1.png
new file mode 100644
index 000000000..6d477d754
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay1.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay1.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay1.png.mcmeta
new file mode 100644
index 000000000..fe63ba1cc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay1.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 90
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay2.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay2.png
new file mode 100644
index 000000000..3fd4a6669
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay2.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay2.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay2.png.mcmeta
new file mode 100644
index 000000000..0c408636c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay2.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 60
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay3.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay3.png
new file mode 100644
index 000000000..d7b0810b4
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay3.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay3.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay3.png.mcmeta
new file mode 100644
index 000000000..893e25fb8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_active_overlay3.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 100
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay0.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay0.png
new file mode 100644
index 000000000..7b76571a3
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay0.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay0.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay0.png.mcmeta
new file mode 100644
index 000000000..6c67b115b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay0.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 80
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay1.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay1.png
new file mode 100644
index 000000000..897ab8fcc
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay1.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay1.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay1.png.mcmeta
new file mode 100644
index 000000000..fe63ba1cc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay1.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 90
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay2.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay2.png
new file mode 100644
index 000000000..90df1efad
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay2.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay2.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay2.png.mcmeta
new file mode 100644
index 000000000..0c408636c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay2.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 60
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay3.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay3.png
new file mode 100644
index 000000000..d8b6bacfa
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay3.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay3.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay3.png.mcmeta
new file mode 100644
index 000000000..893e25fb8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/front_overlay3.png.mcmeta
@@ -0,0 +1,16 @@
+{
+    "animation": {
+        "frametime": 2,
+        "frames": [
+            0,
+            1,
+            2,
+            3,
+            4,
+            {
+                "index": 5,
+                "time": 100
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side.png
new file mode 100644
index 000000000..b730e6606
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side_active.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side_active.png
new file mode 100644
index 000000000..3f609bc16
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side_active.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side_active_overlay.png b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side_active_overlay.png
new file mode 100644
index 000000000..e2741db32
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/comparer/side_active_overlay.png differ
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicComparer.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicComparer.java
new file mode 100644
index 000000000..6c7ae8aab
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicComparer.java
@@ -0,0 +1,135 @@
+package net.minecraft.core.block;
+
+import net.minecraft.core.block.entity.TileEntity;
+import net.minecraft.core.block.material.Material;
+import net.minecraft.core.entity.Mob;
+import net.minecraft.core.enums.EnumDropCause;
+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.WorldSource;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Random;
+
+public class BlockLogicComparer extends BlockLogicVeryRotatable {
+    public final boolean isActive;
+    public BlockLogicComparer(Block<?> block, boolean isActive) {
+        super(block, Material.stone);
+        this.isActive = isActive;
+    }
+
+    @Override
+    public int tickDelay() {
+        return 4;
+    }
+
+    @Override
+    public void updateTick(World world, int x, int y, int z, Random rand) {
+        updateState(world, x, y, z);
+    }
+
+    @Override
+    public void onBlockPlacedByMob(World world, int x, int y, int z, @NotNull Side side, Mob mob, double xPlaced, double yPlaced) {
+        super.onBlockPlacedByMob(world, x, y, z, side, mob, xPlaced, yPlaced);
+        world.scheduleBlockUpdate(x, y, z, id(), tickDelay());
+    }
+
+    @Override
+    public void onBlockPlacedByWorld(World world, int x, int y, int z) {
+        super.onBlockPlacedByWorld(world, x, y, z);
+        world.scheduleBlockUpdate(x, y, z, id(), tickDelay());
+    }
+
+    @Override
+    public void onBlockPlacedOnSide(World world, int x, int y, int z, @NotNull Side side, double xPlaced, double yPlaced) {
+        super.onBlockPlacedOnSide(world, x, y, z, side, xPlaced, yPlaced);
+        world.scheduleBlockUpdate(x, y, z, id(), tickDelay());
+    }
+
+    @Override
+    public void onNeighborBlockChange(World world, int x, int y, int z, int blockId) {
+        world.scheduleBlockUpdate(x, y, z, id(), tickDelay());
+    }
+
+    public void updateState(World world, int x, int y, int z) {
+        Direction dir = BlockLogicVeryRotatable.metaToDirection(world.getBlockMetadata(x, y, z) & BlockLogicVeryRotatable.MASK_DIRECTION);
+
+        int fx = x + dir.getOffsetX();
+        int fy = y + dir.getOffsetY();
+        int fz = z + dir.getOffsetZ();
+
+        int bx = x + dir.getOpposite().getOffsetX();
+        int by = y + dir.getOpposite().getOffsetY();
+        int bz = z + dir.getOpposite().getOffsetZ();
+
+        Block<?> fBlock = world.getBlock(fx, fy, fz);
+        Block<?> bBlock = world.getBlock(bx, by, bz);
+
+        int fMeta = world.getBlockMetadata(fx, fy, fz);
+        int bMeta = world.getBlockMetadata(bx, by, bz);
+
+        boolean backMatchesFront = fBlock == bBlock && fMeta == bMeta;
+
+        if (!isActive && backMatchesFront) {
+            world.setBlockAndMetadataWithNotify(x, y, z, Blocks.COMPARER_ACTIVE.id(), world.getBlockMetadata(x, y, z));
+        } else if (isActive && !backMatchesFront) {
+            world.setBlockAndMetadataWithNotify(x, y, z, Blocks.COMPARER.id(), world.getBlockMetadata(x, y, z));
+        }
+    }
+
+    @Override
+    public void animationTick(World world, int x, int y, int z, Random rand)
+    {
+        if(!this.isActive) {
+            return;
+        }
+        Random random = world.rand;
+
+        final int redstoneBrightness = 10;
+
+        double d = 0.0625;
+        for (int i = 0; i < 6; i++) {
+            double px = (double) x + random.nextFloat();
+            double py = (double) y + random.nextFloat();
+            double pz = (double) z + random.nextFloat();
+
+            if (i == 0 && !world.isBlockOpaqueCube(x, y + 1, z)) py = (y + 1) + d;
+            if (i == 1 && !world.isBlockOpaqueCube(x, y - 1, z)) py = (y + 0) - d;
+            if (i == 2 && !world.isBlockOpaqueCube(x, y, z + 1)) pz = (z + 1) + d;
+            if (i == 3 && !world.isBlockOpaqueCube(x, y, z - 1)) pz = (z + 0) - d;
+            if (i == 4 && !world.isBlockOpaqueCube(x + 1, y, z)) px = (x + 1) + d;
+            if (i == 5 && !world.isBlockOpaqueCube(x - 1, y, z)) px = (x + 0) - d;
+
+            if (px < x || px > (x + 1) || py < 0.0D || py > (y + 1) || pz < z || pz > (z + 1)) {
+                world.spawnParticle("reddust", px, py, pz, 0, 0, 0, redstoneBrightness);
+            }
+        }
+    }
+
+    @Override
+    public boolean isSignalSource() {
+        return true;
+    }
+
+    @Override
+    public boolean getDirectSignal(World world, int x, int y, int z, Side side)
+    {
+        return false;
+    }
+    @Override
+    public boolean getSignal(WorldSource worldSource, int x, int y, int z, Side side)
+    {
+        return isActive && (BlockLogicVeryRotatable.metaToDirection(worldSource.getBlockMetadata(x, y, z)).getAxis() != side.getAxis());
+    }
+
+    @Override
+    public ItemStack[] getBreakResult(World world, EnumDropCause dropCause, int meta, TileEntity tileEntity) {
+        if (dropCause == EnumDropCause.IMPROPER_TOOL) {
+            return null;
+        }
+        return new ItemStack[]{new ItemStack(Blocks.COMPARER)};
+    }
+
+}
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java
index 2c0bcdb7c..6efbb4e19 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMotionSensor.java
@@ -78,15 +78,5 @@ public class BlockLogicMotionSensor extends BlockLogicVeryRotatable
         }
         return new ItemStack[]{new ItemStack(Blocks.MOTION_SENSOR_IDLE)};
     }
-    
-    public static Direction getFacingDirection(int meta) {
-    	if(meta == 0) return Direction.DOWN;
-    	if(meta == 1) return Direction.UP;
-    	if(meta == 2) return Direction.NORTH;
-    	if(meta == 3) return Direction.SOUTH;
-    	if(meta == 4) return Direction.WEST;
-    	if(meta == 5) return Direction.EAST;
-    	return Direction.NONE;
-    }
 
 }
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 22f21038a..643c5094e 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
@@ -381,6 +381,9 @@ public class BlockLogicWireRedstone extends BlockLogic {
             if (side == Side.NONE || side.isVertical()) return false;
             return Side.getSideById(worldSource.getBlockMetadata(x, y, z)).getOpposite() == side;
         }
+        if (block == Blocks.COMPARER || block == Blocks.COMPARER_ACTIVE) {
+            return BlockLogicVeryRotatable.metaToDirection(worldSource.getBlockMetadata(x, y, z)).getAxis() != side.getAxis();
+        }
         if (block == Blocks.REPEATER_IDLE || block == Blocks.REPEATER_ACTIVE) {
             final Side direction = BlockLogicRepeater.getSideFromMeta(worldSource.getBlockMetadata(x, y, z));
             return side == direction || side == direction.getOpposite();
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 326bf32cc..72b392279 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
@@ -31,7 +31,6 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -1286,6 +1285,14 @@ public final class Blocks {
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
 
+    public static final Block<BlockLogic> COMPARER = register("comparer", "minecraft:block/comparer", 1040, (b) -> new BlockLogicComparer(b, false))
+        .withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+
+    public static final Block<BlockLogic> COMPARER_ACTIVE = register("comparer.active", "minecraft:block/comparer_active", 1041, (b) -> new BlockLogicComparer(b, true))
+        .withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
+
     public static <T extends BlockLogic> Block<T> register(String key, String namespaceId, int id, BlockLogicSupplier<T> logicSupplier) {
         Block<T> container = new Block<>(id, key, namespaceId, logicSupplier);
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java
index a3baf4a3d..895fa8e4d 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySensor.java
@@ -4,6 +4,7 @@ import java.util.List;
 
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.achievement.Achievements;
+import net.minecraft.core.block.BlockLogicVeryRotatable;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.BlockLogicMotionSensor;
 import net.minecraft.core.block.tag.BlockTags;
@@ -72,7 +73,7 @@ public class TileEntitySensor extends TileEntity {
 		int meta = worldObj.getBlockMetadata(x, y, z);
 		
 		boolean shouldBeActive = false;
-		Direction facing = BlockLogicMotionSensor.getFacingDirection(meta);
+		Direction facing = BlockLogicVeryRotatable.metaToDirection(meta);
 		int effectiveRange = getSightRange(worldObj, x, y, z, facing);
 		if(effectiveRange > 0) {
 			AABB detectionBox = getDetectionBox(x, y, z, facing, effectiveRange);
@@ -119,7 +120,7 @@ public class TileEntitySensor extends TileEntity {
 		int meta = carriedBlock.metadata;
 
 		boolean shouldBeActive = false;
-		Direction facing = BlockLogicMotionSensor.getFacingDirection(meta);
+		Direction facing = BlockLogicVeryRotatable.metaToDirection(meta);
 		int effectiveRange = getSightRange(world, holder.x, holder.y, holder.z, facing);
 		if(effectiveRange > 0) {
 			AABB detectionBox = getDetectionBox(holder.x, holder.y, holder.z, facing, effectiveRange);
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 6e19cbfc2..9b719eaf8 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
@@ -2691,7 +2691,7 @@ public class World implements WorldSource {
 
     public boolean getSignal(int x, int y, int z, Side side) {
         Block<?> block = getBlock(x, y, z);
-        if(isBlockNormalCube(x, y, z) && block != Blocks.BLOCK_REDSTONE  && block != Blocks.PUMPKIN_REDSTONE) {
+        if(isBlockNormalCube(x, y, z) && block != Blocks.BLOCK_REDSTONE  && block != Blocks.PUMPKIN_REDSTONE && block != Blocks.COMPARER_ACTIVE) {
             return hasDirectSignal(x, y, z);
         }
         if(block == null) {
diff --git a/game/core/src/main/resources/lang/en_US/tile.lang b/game/core/src/main/resources/lang/en_US/tile.lang
index 14952b2b0..ea25c034b 100644
--- a/game/core/src/main/resources/lang/en_US/tile.lang
+++ b/game/core/src/main/resources/lang/en_US/tile.lang
@@ -1416,3 +1416,8 @@ tile.statue.pigman.lower.name=Pigman Statue (Lower)
 tile.statue.pigman.lower.desc=
 tile.statue.pigman.upper.name=Pigman Statue (Upper)
 tile.statue.pigman.upper.desc=
+
+tile.comparer.name=Comparer
+tile.comparer.desc=Compares the block infront to the block behind.
+tile.comparer.active.name=Comparer
+tile.comparer.desc=Compares the block infront to the block behind.
\ No newline at end of file
diff --git a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
index 0e40ec441..69bc0014e 100644
--- a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
+++ b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
@@ -1317,6 +1317,17 @@ class WorkbenchGenerator {
             .addInput('X', Items.DUST_REDSTONE)
             .addInput('Y', "minecraft:cobblestones")
             .create("spikes", new ItemStack(Blocks.SPIKES, 4));
+
+        RecipeBuilder.Shaped(CORE_NAMESPACE)
+            .setShape(
+                "###",
+                "QRQ",
+                "###"
+            )
+            .addInput('#', "minecraft:cobblestones")
+            .addInput('Q', Items.QUARTZ)
+            .addInput('R', Items.DUST_REDSTONE)
+            .create("comparer", new ItemStack(Blocks.COMPARER, 1));
     }
 
     private static void generateScrapRecipes() {
