diff --git a/game/client/src/main/java/net/minecraft/client/Minecraft.java b/game/client/src/main/java/net/minecraft/client/Minecraft.java
index 1f6cfda0a..a12f7f9d2 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -32,6 +32,8 @@ import net.minecraft.client.gui.server.ScreenSelectServer;
 import net.minecraft.client.gui.toasts.GuiElementToastsHud;
 import net.minecraft.client.holiday.Holidays;
 import net.minecraft.client.player.controller.PlayerControllerSP;
+import net.minecraft.client.render.EntityRendererDispatcher;
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.renderer.CompareFunc;
 import net.minecraft.client.render.renderer.CullFace;
 import net.minecraft.client.render.renderer.GLRenderer;
@@ -91,6 +93,7 @@ import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.util.helper.LoggedPrintStream;
 import net.minecraft.core.util.helper.UUIDHelper;
 import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.save.SaveFormatBase;
 import net.minecraft.core.world.settings.WorldConfiguration;
 import net.minecraft.core.world.type.WorldType;
@@ -218,7 +221,7 @@ public class Minecraft
     public static boolean doPartialTick = true;
     public static EnumGPUVendor GPU_VENDOR = EnumGPUVendor.UNKNOWN;
     private static @NotNull Minecraft INSTANCE;
-    public PlayerController playerController;
+    public @Nullable PlayerController playerController = null;
     public boolean hasCrashed;
     public UnexpectedThrowable lastCrash;
     public final Timer timer;
@@ -280,7 +283,7 @@ public class Minecraft
     public final ScreenshotHelper screenshotHelper = new ScreenshotHelper(this);
     private boolean f3Press = false;
     public Thread rpcThread = null;
-    public PostProcessingManager ppm = new PostProcessingManager(this);
+    public final @NotNull PostProcessingManager ppm = new PostProcessingManager(this);
     private long lastFocusTime;
     public @NotNull GameWindow gameWindow;
     public ClientSkinVariantList skinVariantList = new ClientSkinVariantList(this);
@@ -1226,24 +1229,24 @@ public class Minecraft
         }
     }
 
-    private void mineBlocks(int mouseButton, boolean leftClickDown) {
-        if (leftClickDown && this.objectMouseOver != null && this.objectMouseOver instanceof HitResult.Tile hitTile && mouseButton == 0) {
-            int blockX = hitTile.tilePos.x();
-            int blockY = hitTile.tilePos.y();
-            int blockZ = hitTile.tilePos.z();
-            Side side = hitTile.side;
-            double xPlaced;
-            double yPlaced = hitTile.location.y() - hitTile.tilePos.y();
-            if (side.getAxis() == Axis.X) {
+    private void mineBlocks(final boolean leftClickDown) {
+        final @NotNull PlayerController playerController = Objects.requireNonNull(this.playerController);
+
+        if (leftClickDown && this.objectMouseOver instanceof final @NotNull HitResult.Tile hitTile) {
+            final double xPlaced;
+            if (hitTile.side.getAxis() == Axis.X) {
                 xPlaced = hitTile.location.x() - hitTile.tilePos.x();
-            } else if (side.getAxis() == Axis.Z) {
+            } else if (hitTile.side.getAxis() == Axis.Z) {
                 xPlaced = hitTile.location.z() - hitTile.tilePos.z();
             } else {
                 xPlaced = hitTile.location.x() - hitTile.tilePos.x();
             }
-            this.playerController.continueDestroyBlock(blockX, blockY, blockZ, hitTile.side, xPlaced, yPlaced);
+
+            final double yPlaced = hitTile.location.y() - hitTile.tilePos.y();
+
+            playerController.continueDestroyBlock(hitTile.tilePos, hitTile.side, xPlaced, yPlaced);
         } else {
-            this.playerController.stopDestroyBlock(leftClickDown);
+            playerController.stopDestroyBlock();
         }
     }
 
@@ -1266,9 +1269,11 @@ public class Minecraft
                     if (cube == null) {
                         break bridge;
                     }
-                    int blockX = MathHelper.floor(this.thePlayer.x);
-                    int blockY = MathHelper.floor(this.thePlayer.y - this.thePlayer.heightOffset - 0.25);
-                    int blockZ = MathHelper.floor(this.thePlayer.z);
+                    final @NotNull TilePos tilePos = new TilePos(
+                        MathHelper.floor(this.thePlayer.x),
+                        MathHelper.floor(this.thePlayer.y - this.thePlayer.heightOffset - 0.25),
+                        MathHelper.floor(this.thePlayer.z)
+                    );
 
                     Direction playerDirection = Direction.getHorizontalDirection(this.thePlayer);
                     if (playerDirection.isVertical()) break bridge;
@@ -1281,11 +1286,11 @@ public class Minecraft
                     if (stack == null) {
                         break bridge;
                     }
-                    if (this.playerController.placeItemStackOnTile(this.thePlayer, this.currentWorld, stack, blockX, blockY, blockZ, side, xPlaced, yPlaced)) {
+                    if (this.playerController.placeItemStackOnTile(this.thePlayer, this.currentWorld, stack, tilePos, side, xPlaced, yPlaced)) {
                         this.playerController.swingItem(true);
                     }
                     if (stack.stackSize <= 0) {
-                        this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.getCurrentSlot()] = null;
+                        this.thePlayer.inventory.setCurrentItem(null);
                     } else if (stack.stackSize != numItemsInStack) {
                         this.worldRenderer.itemRenderer.updateEquippedItem();
                     }
@@ -1305,29 +1310,25 @@ public class Minecraft
                 }
             }
         } else if (this.objectMouseOver instanceof HitResult.Tile hitTile) {
-            int blockX = hitTile.tilePos.x();
-            int blockY = hitTile.tilePos.y();
-            int blockZ = hitTile.tilePos.z();
-            Side side = hitTile.side;
             double xPlaced;
             double yPlaced = hitTile.location.y() - hitTile.tilePos.y();
-            if (side.getAxis() == Axis.X) {
+            if (hitTile.side.getAxis() == Axis.X) {
                 xPlaced = hitTile.location.x() - hitTile.tilePos.x();
-            } else if (side.getAxis() == Axis.Z) {
+            } else if (hitTile.side.getAxis() == Axis.Z) {
                 xPlaced = hitTile.location.z() - hitTile.tilePos.z();
             } else {
                 xPlaced = hitTile.location.x() - hitTile.tilePos.x();
             }
 
             if (clickType == 0) {
-                this.playerController.startDestroyBlock(blockX, blockY, blockZ, hitTile.side, xPlaced, yPlaced, repeat);
+                this.playerController.startDestroyBlock(hitTile.tilePos, hitTile.side, xPlaced, yPlaced, repeat);
                 if (this.thePlayer.getHeldObject() == null) {
                     this.playerController.swingItem(true);
                 }
             } else {
                 ItemStack stack = this.thePlayer.inventory.getCurrentItem();
                 int numItemsInStack = stack == null ? 0 : stack.stackSize;
-                if (this.playerController.useOrPlaceItemStackOnTile(this.thePlayer, this.currentWorld, stack, blockX, blockY, blockZ, side, xPlaced, yPlaced)) {
+                if (this.playerController.useOrPlaceItemStackOnTile(this.thePlayer, this.currentWorld, stack, hitTile.tilePos, hitTile.side, xPlaced, yPlaced)) {
                     flag = false;
                     this.playerController.swingItem(true);
                 }
@@ -1611,7 +1612,7 @@ public class Minecraft
                 if (placeBlockPressed && (float) (this.ticksRan - this.mouseTicksRan) >= this.timer.ticksPerSecond / 5F && this.inGameHasFocus)
                     clickMouse(1, this.gameSettings.autoHit.value, true);
             }
-            mineBlocks(0, this.currentScreen == null && breakBlockPressed && this.inGameHasFocus);
+            mineBlocks(this.currentScreen == null && breakBlockPressed && this.inGameHasFocus);
         }
         InputHandler.poll();
         if (this.controllerInput != null) {
@@ -2203,7 +2204,6 @@ public class Minecraft
             Colorizers.update(true);
         }
         if (world != null) {
-            this.playerController.initWorld(world);
             if (!isMultiplayerWorld()) {
                 if (player == null) {
                     this.thePlayer = null;
@@ -2218,13 +2218,11 @@ public class Minecraft
             if (this.thePlayer == null) {
                 this.thePlayer = (PlayerLocal) this.playerController.createPlayer(world);
                 this.thePlayer.resetPos();
-                this.playerController.initPlayer(this.thePlayer);
             }
             this.thePlayer.input = new PlayerInput(this);
             if (this.particleEngine != null) {
                 this.particleEngine.setWorld(world);
             }
-            this.playerController.adjustPlayer(this.thePlayer);
             IChunkProvider ichunkprovider = world.getChunkProvider();
             int i = MathHelper.floor_float((int) this.thePlayer.x) >> 4;
             int j = MathHelper.floor_float((int) this.thePlayer.z) >> 4;
@@ -2247,6 +2245,12 @@ public class Minecraft
             this.loadingScreen.progressStop();
         }
         this.worldRenderer.lightmapHelper.setup();
+
+        Colorizers.reload();
+        BlockColorDispatcher.getInstance().onWorldChanged(this.currentWorld);
+        EntityRendererDispatcher.instance.onWorldChanged(this.currentWorld);
+        TileEntityRenderDispatcher.instance.onWorldChanged(this.currentWorld);
+        BlockModelDispatcher.getInstance().onWorldChanged(this.currentWorld);
     }
 
     private void convertSaveVersion(int fromVersion, String worldDirName) {
@@ -2403,12 +2407,10 @@ public class Minecraft
             this.thePlayer.moveTo((float) bedSpawnCoordinates.x + 0.5F, (float) bedSpawnCoordinates.y + 0.1F, (float) bedSpawnCoordinates.z + 0.5F, 0.0F, 0.0F);
         }
         this.thePlayer.setLastDeathPoint(lastDeathCoordinates);
-        this.playerController.initPlayer(this.thePlayer);
         this.currentWorld.spawnPlayerWithLoadedChunks(this.thePlayer, true);
         this.thePlayer.input = new PlayerInput(this);
         this.thePlayer.id = j;
         this.thePlayer.animate4();
-        this.playerController.adjustPlayer(this.thePlayer);
         prepareLevel("Respawning");
         if (this.currentScreen instanceof ScreenGameOver) {
             displayScreen(null);
diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
index 522cbf632..edfbae4ec 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
@@ -103,10 +103,10 @@ public class PlayerLocal extends Player {
         this.gamemode = gamemode;
 
         MenuInventory newContainer = gamemode.getInventoryMenu(this.inventory);
-        if (this.craftingInventory == this.inventorySlots) {
-            this.craftingInventory = newContainer;
+        if (this.containerMenu == this.inventoryMenu) {
+            this.containerMenu = newContainer;
         }
-        this.inventorySlots = newContainer;
+        this.inventoryMenu = newContainer;
         if (!gamemode.hasPlayerFlight()) {
             this.noPhysics = false;
         }
diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
index 7346f5a25..9d7e0ed5e 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
@@ -3,7 +3,6 @@ package net.minecraft.client.entity.player;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.guidebook.ScreenGuidebook;
 import net.minecraft.client.net.handler.PacketHandlerClient;
-import net.minecraft.core.achievement.stat.Stat;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityItem;
@@ -182,7 +181,7 @@ public class PlayerLocalMultiplayer extends PlayerLocal implements Player.Player
     @Override
 	public void updateCreativeInventory(int page, String searchText)
     {
-    	sendQueue.addToSendQueue(new PacketUpdateCreativeInventory(craftingInventory.containerId, page, searchText));
+    	sendQueue.addToSendQueue(new PacketUpdateCreativeInventory(containerMenu.containerId, page, searchText));
     }
 
     @Override
@@ -222,7 +221,7 @@ public class PlayerLocalMultiplayer extends PlayerLocal implements Player.Player
     @Override
 	public void closeScreen()
     {
-        sendQueue.addToSendQueue(new PacketContainerClose(craftingInventory.containerId));
+        sendQueue.addToSendQueue(new PacketContainerClose(containerMenu.containerId));
         inventory.setHeldItemStack(null);
         super.closeScreen();
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/Gui.java b/game/client/src/main/java/net/minecraft/client/gui/Gui.java
index 501e00cbe..8d99fbaa7 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/Gui.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/Gui.java
@@ -203,15 +203,19 @@ public class Gui {
     }
 
     public void drawTexturedModalRect(final int x, final int y, final int u, final int v, final int width, final int height) {
-        final float uScale = 0.00390625F;
-        final float vScale = 0.00390625F;
         final TessellatorGeneral tessellator = GLRenderer.getTessellator();
         tessellator.startDrawingQuads();
+        addTexturedModalRect(tessellator, x, y, u, v, width, height);
+        tessellator.draw();
+    }
+
+    public void addTexturedModalRect(@NotNull TessellatorGeneral tessellator, final int x, final int y, final int u, final int v, final int width, final int height) {
+        final float uScale = 0.00390625F;
+        final float vScale = 0.00390625F;
         tessellator.addVertexWithUV(x, y + height, this.zLevel, (u) * uScale, (v + height) * vScale);
         tessellator.addVertexWithUV(x + width, y + height, this.zLevel, (u + width) * uScale, (v + height) * vScale);
         tessellator.addVertexWithUV(x + width, y, this.zLevel, (u + width) * uScale, (v) * vScale);
         tessellator.addVertexWithUV(x, y, this.zLevel, (u) * uScale, (v) * vScale);
-        tessellator.draw();
     }
 
     public void drawTexturedModalRect(final int x, final int y, final int u, final int v, final int width, final int height, final double uScale, final double vScale) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java
index 6ad285d9e..d44c7b9e0 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java
@@ -28,6 +28,7 @@ import net.minecraft.client.render.renderer.CullFace;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.util.helper.UrlHelper;
 import net.minecraft.core.Version;
@@ -344,7 +345,7 @@ public class ScreenMainMenu extends Screen {
         }
 
         GLRenderer.pushFrame();
-        GLRenderer.setShader(Shaders.WORLD);
+        GLRenderer.setShader(Shaders.TERRAIN);
         final int delta = this.mc.gameWindow.getWidthPixels() / this.mc.resolution.getScaledWidthScreenCoords();
         int var3 = 120 * delta;
         GLRenderer.projectionM4f().identity().perspective(70.0F, (float) this.mc.gameWindow.getWidthPixels() / (float) var3, 0.05F, 100.0F);
@@ -384,6 +385,11 @@ public class ScreenMainMenu extends Screen {
             GLRenderer.modelM4f().scale(0.89F, 1.0F, 0.4F);
             GLRenderer.modelM4f().translate((float) (-logoBlockLayers[0].length()) * 0.5F, (float) (-logoBlockLayers.length) * 0.5F, 0.0F);
             TextureRegistry.worldAtlas.bind();
+            GL41.glActiveTexture(GL41.GL_TEXTURE2);
+            TextureRegistry.worldAtlas.layerTextureMap.get("emissive").bind();
+//        GL41.glActiveTexture(GL41.GL_TEXTURE3);
+//        TextureRegistry.worldAtlas.layerTextureMap.get("maskColor").bind();
+            GL41.glActiveTexture(GL41.GL_TEXTURE0);
             if (renderPass == 0) {
                 this.mc.textureManager.loadTexture("/title/black.png").bind();
             }
@@ -406,7 +412,8 @@ public class ScreenMainMenu extends Screen {
                         GLRenderer.setColor4f(1f, 1f, 1f, alpha);
                         GLRenderer.modelM4f().translate(x, y, z);
                         GLRenderer.modelM4f().scale(scale, scale, scale);
-                        BlockModelDispatcher.getInstance().getDispatch(BLOCKS_TO_DRAW[this.indexToDraw]).renderStandalone(GLRenderer.getTessellator(), 0, LightmapHelper.getLightmapCoord(15, 15));
+                        TessellatorGeneral t = GLRenderer.getTessellator();
+                        BlockModelDispatcher.getInstance().getDispatch(BLOCKS_TO_DRAW[this.indexToDraw]).renderStandalone(t, 0, LightmapHelper.getLightmapCoord(15, 15));
                         GLRenderer.popFrame();
                     }
                 }
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 5016a29bb..8078651e2 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
@@ -60,7 +60,7 @@ public class ScreenActivator extends ScreenContainerAbstract {
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/activator.png").bind();
         int xLeft = (this.width - this.xSize) / 2;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainer.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainer.java
index 0d4807527..243f7b5da 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainer.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainer.java
@@ -26,7 +26,7 @@ public class ScreenContainer extends ScreenContainerAbstract {
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         GLRenderer.enableState(State.BLEND);
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/container.png").bind();
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 4884fd5f0..b2065988a 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
@@ -56,7 +56,7 @@ public abstract class ScreenContainerAbstract extends Screen {
         return false;
     }
 
-    protected abstract void drawGuiContainerBackgroundLayer(float f);
+    protected abstract void drawGuiContainerBackgroundLayer(float partialTick);
 
     protected void drawGuiContainerForegroundLayer() {
     }
@@ -136,7 +136,7 @@ public abstract class ScreenContainerAbstract extends Screen {
     @Override
     public void init() {
         super.init();
-        this.mc.thePlayer.craftingInventory = this.inventorySlots;
+        this.mc.thePlayer.containerMenu = this.inventorySlots;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenCrafting.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenCrafting.java
index cb80e9f4e..fd3feb4f8 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenCrafting.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenCrafting.java
@@ -27,7 +27,7 @@ public class ScreenCrafting extends ScreenContainerAbstract {
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/crafting.png").bind();
         int left = (this.width - this.xSize) / 2;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenDispenser.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenDispenser.java
index 32d814db7..27c5669b9 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenDispenser.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenDispenser.java
@@ -19,7 +19,7 @@ public class ScreenDispenser extends ScreenContainerAbstract {
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/dispenser.png").bind();
         int left = (this.width - this.xSize) / 2;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java
index 26727e541..2bccb5377 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java
@@ -320,7 +320,7 @@ public class ScreenFlagEditor
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/flag_editor.png").bind();
         int j = (this.width - this.xSize) / 2;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnace.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnace.java
index ebb468b32..8cbfdd594 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnace.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnace.java
@@ -23,7 +23,7 @@ public class ScreenFurnace extends ScreenContainerAbstract {
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/furnace.png").bind();
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         int x = (this.width - this.xSize) / 2;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnaceBlast.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnaceBlast.java
index 2eb8e39e0..18c57aa22 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnaceBlast.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFurnaceBlast.java
@@ -26,7 +26,7 @@ public class ScreenFurnaceBlast
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(final float f) {
+    protected void drawGuiContainerBackgroundLayer(final float partialTick) {
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/blastfurnace.png").bind();
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         final int x = (this.width - this.xSize) / 2;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
index eeec84b0b..d8f26f94f 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
@@ -11,6 +11,7 @@ import net.minecraft.client.render.entity.EntityRenderer;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.entity.player.Player;
@@ -42,7 +43,7 @@ public class ScreenInventory extends ScreenContainerAbstract {
 
 
     public ScreenInventory(Player player) {
-        super(player.inventorySlots);
+        super(player.inventoryMenu);
         this.passEvents = true;
         player.addStat(Achievements.OPEN_INVENTORY, 1);
     }
@@ -165,13 +166,16 @@ public class ScreenInventory extends ScreenContainerAbstract {
             }
         }
 
+        TessellatorGeneral t = GLRenderer.getTessellator();
+        t.startDrawingQuads();
         for (int i = 0; i < this.overlayButtonsLayout.elements.size(); i++) {
             OverlayButtonElement<?> button = (OverlayButtonElement<?>) this.overlayButtonsLayout.elements.get(i);
-            drawTexturedModalRect(button.xPosition + 1, button.yPosition + 1, 176, 9 + 9 * this.uvs.getInt(i), 9, 9);
+            addTexturedModalRect(t, button.xPosition + 1, button.yPosition + 1, 176, 9 + 9 * this.uvs.getInt(i), 9, 9);
             boolean val = true;
             if (button.option instanceof OptionBoolean) val = (Boolean) button.option.value;
-            if (!val) drawTexturedModalRect(button.xPosition + 1, button.yPosition + 1, 194, 0, 9, 9);
+            if (!val) addTexturedModalRect(t, button.xPosition + 1, button.yPosition + 1, 194, 0, 9, 9);
         }
+        t.draw();
 
         for (int i = 0; i < this.overlayButtonsLayout.elements.size(); i++) {
             OverlayButtonElement<?> button = (OverlayButtonElement<?>) this.overlayButtonsLayout.elements.get(i);
@@ -245,44 +249,49 @@ public class ScreenInventory extends ScreenContainerAbstract {
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/inventory.png").bind();
-        int j = (this.width - this.xSize) / 2;
-        int k = (this.height - this.ySize) / 2;
-        drawTexturedModalRect(j, k, 0, 0, this.xSize, this.ySize);
+        int x = (this.width - this.xSize) / 2;
+        int y = (this.height - this.ySize) / 2;
+        drawTexturedModalRect(x, y, 0, 0, this.xSize, this.ySize);
 
         GLRenderer.pushFrame();
         GLRenderer.setShader(Shaders.WORLD);
         GLRenderer.getFogState().disable();
         GLRenderer.enableState(State.DEPTH_TEST);
-        GLRenderer.modelM4f().translate(j + 51, k + 75, 50F);
+        GLRenderer.modelM4f().translate(x + 51, y + 75, 50F);
         float f1 = 30F;
         GLRenderer.modelM4f().scale(-f1, f1, f1);
         GLRenderer.modelM4f().rotateZ(org.joml.Math.toRadians(180F));
-        float f2 = this.mc.thePlayer.yBodyRot;
-        float f3 = this.mc.thePlayer.yRot;
-        float f4 = this.mc.thePlayer.xRot;
-        float f5 = (float) (j + 51) - this.xSize_lo;
-        float f6 = (float) ((k + 75) - 50) - this.ySize_lo;
+        float yBodyRot = this.mc.thePlayer.yBodyRot;
+        float yBodyRotO = this.mc.thePlayer.yBodyRotO;
+        float yRot = this.mc.thePlayer.yRot;
+        float yRotO = this.mc.thePlayer.yRotO;
+        float xRot = this.mc.thePlayer.xRot;
+        float xRotO = this.mc.thePlayer.xRotO;
+        float eyesX = (float) (x + 51) - this.xSize_lo;
+        float eyesY = (float) ((y + 75) - 50) - this.ySize_lo;
         GLRenderer.modelM4f().rotateY(org.joml.Math.toRadians(135F));
         Lighting.enableLight();
         GLRenderer.modelM4f().rotateY(org.joml.Math.toRadians(-135F));
-        GLRenderer.modelM4f().rotateX(org.joml.Math.toRadians(-(float) Math.atan(f6 / 40F) * 20F));
-        this.mc.thePlayer.yBodyRot = (float) Math.atan(f5 / 40F) * 20F;
-        this.mc.thePlayer.yRot = (float) Math.atan(f5 / 40F) * 40F;
-        this.mc.thePlayer.xRot = -(float) Math.atan(f6 / 40F) * 20F;
-        this.mc.thePlayer.entityBrightness = 1.0F;
+        GLRenderer.modelM4f().rotateX(org.joml.Math.toRadians(-(float) Math.atan(eyesY / 40F) * 20F));
+        this.mc.thePlayer.yBodyRotO = this.mc.thePlayer.yBodyRot = (float) Math.atan(eyesX / 40F) * 20F;
+        this.mc.thePlayer.yRotO = this.mc.thePlayer.yRot = (float) Math.atan(eyesX / 40F) * 40F;
+        this.mc.thePlayer.xRotO = this.mc.thePlayer.xRot = -(float) Math.atan(eyesY / 40F) * 20F;
         GLRenderer.modelM4f().translate(0.0F, this.mc.thePlayer.heightOffset, 0.0F);
         EntityRendererDispatcher.instance.viewLerpYaw = 180F;
         EntityRenderer.renderShadows = false;
         GLRenderer.globalGetNormalTransformMatrix().scale(1, -1, 1);
-        EntityRendererDispatcher.instance.renderEntityPreviewWithPosYaw(GLRenderer.getTessellator(), this.mc.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F);
+        GLRenderer.setLightmapCoord2i(15, 15);
+        EntityRendererDispatcher.instance.renderEntityPreviewWithPosYaw(GLRenderer.getTessellator(), this.mc.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, partialTick);
         EntityRenderer.renderShadows = true;
-        this.mc.thePlayer.entityBrightness = 0.0F;
-        this.mc.thePlayer.yBodyRot = f2;
-        this.mc.thePlayer.yRot = f3;
-        this.mc.thePlayer.xRot = f4;
+        this.mc.thePlayer.yBodyRot = yBodyRot;
+        this.mc.thePlayer.yBodyRotO = yBodyRotO;
+        this.mc.thePlayer.yRot = yRot;
+        this.mc.thePlayer.yRotO = yRotO;
+        this.mc.thePlayer.xRot = xRot;
+        this.mc.thePlayer.xRotO = xRotO;
         GLRenderer.popFrame();
         Lighting.disable();
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java
index 8e010b1e5..79e1c3ed6 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java
@@ -31,7 +31,7 @@ public class ScreenInventoryCreative extends ScreenInventory implements ITextCha
     public ScreenInventoryCreative(Player entityplayer) {
         super(entityplayer);
         this.xSize = 298;
-        this.container = (MenuInventoryCreative) entityplayer.inventorySlots;
+        this.container = (MenuInventoryCreative) entityplayer.inventoryMenu;
         this.armourValuesFloat = 186;
         this.armourButtonFloatX = 81;
         this.overlayButtonsLayout.setOffset(-(this.xSize / 2), -(this.ySize / 2) - 10);
@@ -149,7 +149,7 @@ public class ScreenInventoryCreative extends ScreenInventory implements ITextCha
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         scroll(Mouse.getDWheel());
 
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
@@ -174,29 +174,34 @@ public class ScreenInventoryCreative extends ScreenInventory implements ITextCha
         float f1 = 30F;
         GLRenderer.modelM4f().scale(-f1, f1, f1);
         GLRenderer.modelM4f().rotateZ(org.joml.Math.toRadians(180F));
-        float f2 = this.mc.thePlayer.yBodyRot;
-        float f3 = this.mc.thePlayer.yRot;
-        float f4 = this.mc.thePlayer.xRot;
-        float f5 = (float) (x + 51) - this.xSize_lo;
-        float f6 = (float) ((y + 75) - 50) - this.ySize_lo;
+        float yBodyRot = this.mc.thePlayer.yBodyRot;
+        float yBodyRotO = this.mc.thePlayer.yBodyRotO;
+        float yRot = this.mc.thePlayer.yRot;
+        float yRotO = this.mc.thePlayer.yRotO;
+        float xRot = this.mc.thePlayer.xRot;
+        float xRotO = this.mc.thePlayer.xRotO;
+        float eyesX = (float) (x + 51) - this.xSize_lo;
+        float eyesY = (float) ((y + 75) - 50) - this.ySize_lo;
         GLRenderer.modelM4f().rotateY(org.joml.Math.toRadians(135F));
         Lighting.enableLight();
         GLRenderer.modelM4f().rotateY(org.joml.Math.toRadians(-135F));
-        GLRenderer.modelM4f().rotateX(org.joml.Math.toRadians(-(float) Math.atan(f6 / 40F) * 20F));
-        this.mc.thePlayer.yBodyRot = (float) Math.atan(f5 / 40F) * 20F;
-        this.mc.thePlayer.yRot = (float) Math.atan(f5 / 40F) * 40F;
-        this.mc.thePlayer.xRot = -(float) Math.atan(f6 / 40F) * 20F;
-        this.mc.thePlayer.entityBrightness = 1.0F;
+        GLRenderer.modelM4f().rotateX(org.joml.Math.toRadians(-(float) Math.atan(eyesY / 40F) * 20F));
+        this.mc.thePlayer.yBodyRotO = this.mc.thePlayer.yBodyRot = (float) Math.atan(eyesX / 40F) * 20F;
+        this.mc.thePlayer.yRotO = this.mc.thePlayer.yRot = (float) Math.atan(eyesX / 40F) * 40F;
+        this.mc.thePlayer.xRotO = this.mc.thePlayer.xRot = -(float) Math.atan(eyesY / 40F) * 20F;
         GLRenderer.modelM4f().translate(0.0F, this.mc.thePlayer.heightOffset, 0.0F);
         EntityRendererDispatcher.instance.viewLerpYaw = 180F;
         EntityRenderer.renderShadows = false;
         GLRenderer.globalGetNormalTransformMatrix().scale(1, -1, 1);
-        EntityRendererDispatcher.instance.renderEntityPreviewWithPosYaw(GLRenderer.getTessellator(), this.mc.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F);
+        GLRenderer.setLightmapCoord2i(15, 15);
+        EntityRendererDispatcher.instance.renderEntityPreviewWithPosYaw(GLRenderer.getTessellator(), this.mc.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, partialTick);
         EntityRenderer.renderShadows = true;
-        this.mc.thePlayer.entityBrightness = 0.0F;
-        this.mc.thePlayer.yBodyRot = f2;
-        this.mc.thePlayer.yRot = f3;
-        this.mc.thePlayer.xRot = f4;
+        this.mc.thePlayer.yBodyRot = yBodyRot;
+        this.mc.thePlayer.yBodyRotO = yBodyRotO;
+        this.mc.thePlayer.yRot = yRot;
+        this.mc.thePlayer.yRotO = yRotO;
+        this.mc.thePlayer.xRot = xRot;
+        this.mc.thePlayer.xRotO = xRotO;
         GLRenderer.popFrame();
         Lighting.disable();
         this.searchField.drawTextBox();
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenTrommel.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenTrommel.java
index 3442f0131..aa52c1f05 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenTrommel.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenTrommel.java
@@ -23,7 +23,7 @@ public class ScreenTrommel extends ScreenContainerAbstract {
     }
 
     @Override
-    protected void drawGuiContainerBackgroundLayer(float f) {
+    protected void drawGuiContainerBackgroundLayer(float partialTick) {
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/trommel.png").bind();
         int j = (this.width - this.xSize) / 2;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
index 4de644106..2907d5591 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
@@ -3,10 +3,7 @@ package net.minecraft.client.gui.hud;
 import static net.minecraft.core.util.helper.Utils.*;
 
 import java.awt.Color;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.entity.player.PlayerLocalMultiplayer;
@@ -72,7 +69,7 @@ public class HudIngame extends Gui {
     private String recordPlaying = "";
     private int recordPlayingUpFor = 0;
     private boolean colorString = false;
-    public float damageGuiPartialTime;
+    public float destroyProgress;
     float prevVignetteBrightness = 1.0f;
     protected FontRenderer fontRenderer;
     public int chatScroll = 0;
@@ -104,7 +101,7 @@ public class HudIngame extends Gui {
 
         // Render pumpkin overlay
         final ItemStack headSlotItem = this.mc.thePlayer.inventory.armorItemInSlot(HumanArmorShape.HEAD);
-        if (this.mc.gameSettings.thirdPersonView.value == 0 && headSlotItem != null && (headSlotItem.itemID == Blocks.PUMPKIN_CARVED_IDLE.id() || headSlotItem.itemID == Blocks.PUMPKIN_REDSTONE.id())) {
+        if (this.mc.gameSettings.thirdPersonView.value == 0 && headSlotItem != null && (headSlotItem.getItem() == Blocks.PUMPKIN_CARVED_IDLE.asItem() || headSlotItem.getItem() == Blocks.PUMPKIN_REDSTONE.asItem())) {
             renderPumpkinBlur(width, height);
         }
 
@@ -336,50 +333,48 @@ public class HudIngame extends Gui {
                 if (this.mc.objectMouseOver instanceof HitResult.Tile hitTile) {
                     this.debugOffset += space;
 
-                    Block<?> block = Blocks.blocksList[this.mc.currentWorld.getBlockId(hitTile.tilePos)];
-                    if (block != null) {
-                        drawDebugScreenLineRight("Looking at:");
+                    Block<?> block = this.mc.currentWorld.getBlockType(hitTile.tilePos);
+                    drawDebugScreenLineRight("Looking at:");
 
-                        String name;
-                        int meta = this.mc.currentWorld.getBlockData(hitTile.tilePos);
-                        try {
-                            name = new ItemStack(block, 1, meta).getDisplayName();
-                        } catch (Exception e) {
-                            name = "<ERROR>";
-                        }
+                    String name;
+                    int meta = this.mc.currentWorld.getBlockData(hitTile.tilePos);
+                    try {
+                        name = new ItemStack(block, 1, meta).getDisplayName();
+                    } catch (Exception e) {
+                        name = "<ERROR>";
+                    }
 
-                        String id = block.namespaceId() + " [" + block.id() + ":" + meta + "]";
+                    String id = block.namespaceId() + " [" + block.id() + ":" + meta + "]";
 
-                        drawDebugScreenLineRight(name);
-                        drawDebugScreenLineRight(block.getLanguageKey(meta));
-                        drawDebugScreenLineRight(id);
+                    drawDebugScreenLineRight(name);
+                    drawDebugScreenLineRight(block.getLanguageKey(meta));
+                    drawDebugScreenLineRight(id);
 
-                        if (compass) {
-                            drawDebugScreenLineRight("[" + hitTile.tilePos.x() + ", " + hitTile.tilePos.y() + ", " + hitTile.tilePos.z() + "]");
-                        }
+                    if (compass) {
+                        drawDebugScreenLineRight("[" + hitTile.tilePos.x() + ", " + hitTile.tilePos.y() + ", " + hitTile.tilePos.z() + "]");
+                    }
 
-                        drawDebugScreenLineRight("Harvest: " + this.mc.thePlayer.canHarvestBlock(block));
+                    drawDebugScreenLineRight("Harvest: " + this.mc.thePlayer.canHarvestBlock(block));
 
-                        if (clock) {
-                            int lightX = hitTile.tilePos.x();
-                            int lightY = hitTile.tilePos.y();
-                            int lightZ = hitTile.tilePos.z();
+                    if (clock) {
+                        int lightX = hitTile.tilePos.x();
+                        int lightY = hitTile.tilePos.y();
+                        int lightZ = hitTile.tilePos.z();
 
-                            Side side = hitTile.side;
-                            lightX += side.getOffsetX();
-                            lightY += side.getOffsetY();
-                            lightZ += side.getOffsetZ();
+                        Side side = hitTile.side;
+                        lightX += side.getOffsetX();
+                        lightY += side.getOffsetY();
+                        lightZ += side.getOffsetZ();
 
-                            drawDebugScreenLineRight("Light: Sky: " + this.mc.currentWorld.getSavedLightValue(LightLayer.Sky, lightX, lightY, lightZ) + " Block: " + this.mc.currentWorld.getSavedLightValue(LightLayer.Block, lightX, lightY, lightZ));
-                        }
+                        drawDebugScreenLineRight("Light: Sky: " + this.mc.currentWorld.getSavedLightValue(LightLayer.Sky, lightX, lightY, lightZ) + " Block: " + this.mc.currentWorld.getSavedLightValue(LightLayer.Block, lightX, lightY, lightZ));
+                    }
 
-                        drawDebugScreenLineRight("Signal: " + this.mc.currentWorld.hasSignal(hitTile.tilePos, hitTile.side));
-                        drawDebugScreenLineRight("Direct signal: " + this.mc.currentWorld.hasDirectSignal(hitTile.tilePos, hitTile.side));
+                    drawDebugScreenLineRight("Signal: " + this.mc.currentWorld.hasSignal(hitTile.tilePos, hitTile.side));
+                    drawDebugScreenLineRight("Direct signal: " + this.mc.currentWorld.hasDirectSignal(hitTile.tilePos, hitTile.side));
 
-                        for (Tag<Block<?>> tag : BlockTags.TAG_LIST) {
-                            if (tag.appliesTo(block)) {
-                                drawDebugScreenLineRight(tag.getName());
-                            }
+                    for (Tag<Block<?>> tag : BlockTags.TAG_LIST) {
+                        if (tag.appliesTo(block)) {
+                            drawDebugScreenLineRight(tag.getName());
                         }
                     }
                 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
index 4b0dd4956..3afee5d6a 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
@@ -45,7 +45,7 @@ public class HudIngameDoom
 
         // Render pumpkin overlay
         ItemStack headSlotItem = this.mc.thePlayer.getItemInArmorSlot(HumanArmorShape.HEAD);
-        if (this.mc.gameSettings.thirdPersonView.value == 0 && headSlotItem != null && (headSlotItem.itemID == Blocks.PUMPKIN_CARVED_IDLE.id() || headSlotItem.itemID == Blocks.PUMPKIN_REDSTONE.id())) {
+        if (this.mc.gameSettings.thirdPersonView.value == 0 && headSlotItem != null && (headSlotItem.getItem() == Blocks.PUMPKIN_CARVED_IDLE.asItem() || headSlotItem.itemID == Blocks.PUMPKIN_REDSTONE.id())) {
             renderPumpkinBlur(width, height);
         }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java
index 0f1359e05..efc1934d2 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java
@@ -23,7 +23,7 @@ public class HudComponentArmorBar
 
     @Override
     public boolean isVisible() {
-        return mc.playerController.canHurtPlayer() && mc.gameSettings.immersiveMode.drawHotbar() && mc.thePlayer.getPlayerProtectionAmount() > 0;
+        return mc.gameSettings.immersiveMode.drawHotbar() && mc.thePlayer.getPlayerProtectionAmount() > 0;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java
index 99e610a4d..0b34a6071 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java
@@ -15,7 +15,7 @@ public class HudComponentFireBar
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawHotbar() && mc.playerController.canHurtPlayer() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.remainingFireTicks > 0;
+        return mc.gameSettings.immersiveMode.drawHotbar() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.remainingFireTicks > 0;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java
index 72a5641f4..294532b28 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java
@@ -26,7 +26,7 @@ public class HudComponentHealthBar
 
     @Override
     public boolean isVisible() {
-        return mc.playerController.canHurtPlayer() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.gameSettings.immersiveMode.drawHotbar();
+        return !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.gameSettings.immersiveMode.drawHotbar();
     }
 
     @Override
@@ -88,7 +88,7 @@ public class HudComponentHealthBar
                     }
                 }
                 if (mc.objectMouseOver instanceof HitResult.Tile hitTile) {
-                    Block<?> b = mc.currentWorld.getBlock(hitTile.tilePos);
+                    Block<?> b = mc.currentWorld.getBlockType(hitTile.tilePos);
                     if (Block.getLogicClass(b) instanceof BlockLogicEdible edible) {
                         healing = edible.getHealAmount(mc.currentWorld, hitTile.tilePos);
                     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java
index 3fc7f4bec..b04117d28 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java
@@ -23,7 +23,7 @@ public class HudComponentOxygenBar
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawHotbar() && mc.playerController.canHurtPlayer() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.isUnderLiquid(Materials.WATER);
+        return mc.gameSettings.immersiveMode.drawHotbar() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.isUnderLiquid(Materials.WATER);
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java b/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
index 44a7a8e58..892633eaf 100644
--- a/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
+++ b/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
@@ -883,37 +883,37 @@ public class PacketHandlerClient extends PacketHandler
             case PacketContainerOpen.TYPE_GENERIC_CONTAINER: {
                 ContainerSimple simpleContainer = new ContainerSimple(packetContainerOpen.windowTitle, packetContainerOpen.slotsCount);
                 mc.thePlayer.displayContainerScreen(simpleContainer);
-                mc.thePlayer.craftingInventory.containerId = packetContainerOpen.windowId;
+                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_FURNACE: {
                 TileEntityFurnace tileEntityFurnace = new TileEntityFurnace();
                 mc.thePlayer.displayFurnaceScreen(tileEntityFurnace);
-                mc.thePlayer.craftingInventory.containerId = packetContainerOpen.windowId;
+                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_DISPENSER: {
                 TileEntityDispenser tileEntityDispenser = new TileEntityDispenser();
                 mc.thePlayer.displayDispenserScreen(tileEntityDispenser);
-                mc.thePlayer.craftingInventory.containerId = packetContainerOpen.windowId;
+                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_ACTIVATOR: {
                 TileEntityActivator tileEntityActivator = new TileEntityActivator();
                 mc.thePlayer.displayActivatorScreen(tileEntityActivator);
-                mc.thePlayer.craftingInventory.containerId = packetContainerOpen.windowId;
+                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_BLAST_FURNACE: {
                 TileEntityFurnaceBlast tileEntityFurnaceBlast = new TileEntityFurnaceBlast();
                 mc.thePlayer.displayBlastFurnaceScreen(tileEntityFurnaceBlast);
-                mc.thePlayer.craftingInventory.containerId = packetContainerOpen.windowId;
+                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_TROMMEL: {
                 TileEntityTrommel tileEntityTrommel = new TileEntityTrommel();
                 mc.thePlayer.displayTrommelScreen(tileEntityTrommel);
-                mc.thePlayer.craftingInventory.containerId = packetContainerOpen.windowId;
+                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_PAINTING: {
@@ -923,7 +923,7 @@ public class PacketHandlerClient extends PacketHandler
             case PacketContainerOpen.TYPE_CRAFTING: {
                 PlayerLocal playerLocal = mc.thePlayer;
                 mc.thePlayer.displayWorkbenchScreen(new TilePos(playerLocal.x, playerLocal.y, playerLocal.z));
-                mc.thePlayer.craftingInventory.containerId = packetContainerOpen.windowId;
+                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             default: {
@@ -940,7 +940,7 @@ public class PacketHandlerClient extends PacketHandler
         {
             TileEntityFlag tileEntityFlag = (TileEntityFlag) tileEntity;
             mc.thePlayer.displayFlagEditorScreen(tileEntityFlag);
-            mc.thePlayer.craftingInventory.containerId = packetFlagOpen.windowId;
+            mc.thePlayer.containerMenu.containerId = packetFlagOpen.windowId;
         }
     }
 
@@ -959,16 +959,16 @@ public class PacketHandlerClient extends PacketHandler
         }
         else if (packetContainerSetSlot.windowId == 0 && packetContainerSetSlot.itemSlot >= 36 && packetContainerSetSlot.itemSlot < 45)
         {
-            ItemStack itemstack = mc.thePlayer.inventorySlots.getSlot(packetContainerSetSlot.itemSlot).getItemStack();
+            ItemStack itemstack = mc.thePlayer.inventoryMenu.getSlot(packetContainerSetSlot.itemSlot).getItemStack();
             if (packetContainerSetSlot.myItemStack != null && (itemstack == null || itemstack.stackSize < packetContainerSetSlot.myItemStack.stackSize))
             {
                 packetContainerSetSlot.myItemStack.animationsToGo = 5;
             }
-            mc.thePlayer.inventorySlots.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
+            mc.thePlayer.inventoryMenu.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
         }
-        else if (packetContainerSetSlot.windowId == mc.thePlayer.craftingInventory.containerId)
+        else if (packetContainerSetSlot.windowId == mc.thePlayer.containerMenu.containerId)
         {
-            mc.thePlayer.craftingInventory.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
+            mc.thePlayer.containerMenu.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
         }
     }
 
@@ -978,11 +978,11 @@ public class PacketHandlerClient extends PacketHandler
         MenuAbstract container = null;
         if (packetContainerAck.windowId == 0)
         {
-            container = mc.thePlayer.inventorySlots;
+            container = mc.thePlayer.inventoryMenu;
         }
-        else if (packetContainerAck.windowId == mc.thePlayer.craftingInventory.containerId)
+        else if (packetContainerAck.windowId == mc.thePlayer.containerMenu.containerId)
         {
-            container = mc.thePlayer.craftingInventory;
+            container = mc.thePlayer.containerMenu;
         }
         if (container != null)
         {
@@ -1003,11 +1003,11 @@ public class PacketHandlerClient extends PacketHandler
     {
         if (packetContainerSetContent.windowId == 0)
         {
-            mc.thePlayer.inventorySlots.setAll(packetContainerSetContent.stackList);
+            mc.thePlayer.inventoryMenu.setAll(packetContainerSetContent.stackList);
         }
-        else if (packetContainerSetContent.windowId == mc.thePlayer.craftingInventory.containerId)
+        else if (packetContainerSetContent.windowId == mc.thePlayer.containerMenu.containerId)
         {
-            mc.thePlayer.craftingInventory.setAll(packetContainerSetContent.stackList);
+            mc.thePlayer.containerMenu.setAll(packetContainerSetContent.stackList);
         }
     }
 
@@ -1015,9 +1015,9 @@ public class PacketHandlerClient extends PacketHandler
     public void handleContainerSetData(@NotNull PacketContainerSetData packetContainerSetData)
     {
         handleInvalidPacket(packetContainerSetData);
-        if (mc.thePlayer.craftingInventory != null && mc.thePlayer.craftingInventory.containerId == packetContainerSetData.windowId)
+        if (mc.thePlayer.containerMenu != null && mc.thePlayer.containerMenu.containerId == packetContainerSetData.windowId)
         {
-            mc.thePlayer.craftingInventory.setData(packetContainerSetData.progressBar, packetContainerSetData.progressBarValue);
+            mc.thePlayer.containerMenu.setData(packetContainerSetData.progressBar, packetContainerSetData.progressBarValue);
         }
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java
index 128849c9c..9727b497e 100644
--- a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java
+++ b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java
@@ -2,6 +2,8 @@ package net.minecraft.client.player.controller;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.entity.player.PlayerLocal;
+import net.minecraft.client.gui.hud.HudIngame;
+import net.minecraft.client.render.RenderGlobal;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicDoor;
@@ -16,359 +18,385 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.Objects;
+
 import static net.minecraft.core.world.LevelListener.EVENT_BLOCK_BREAK;
 
 public abstract class PlayerController {
-	
-	protected float currentDamage;
-	protected float previousDamage;
-	protected int soundDelay;
-	protected int swingCooldown = 0;
-	protected int blockHitDelay;
-	protected Integer miningX, miningY, miningZ;
-
-	protected final Minecraft mc;
-
-	public PlayerController(Minecraft minecraft) {
-		mc = minecraft;
-	}
-	
-	//Called when the mouse is clicked and about 5 times per second while the button is held down
-	//Repeat is false when the mouse was clicked this frame
-	public void startDestroyBlock(int x, int y, int z, Side side, double xHit, double yHit, boolean repeat) {
-		if (mc.thePlayer.getHeldObject() != null) return;
-		if (!mc.thePlayer.getGamemode().canInteract()) return;
-		if(!mc.thePlayer.getGamemode().hasBlockBreakingAnimation()) {
-			swingItem(true);
-			
-			ItemStack heldItem = mc.thePlayer.getCurrentEquippedItem();
-			if(heldItem != null && heldItem.getItem().hasTag(ItemTags.PREVENT_CREATIVE_MINING)) {
-				return;
-			}
-			
-			destroyBlock(x, y, z, side, mc.thePlayer);
-			sendStartDigPacket(x, y, z, side, xHit, yHit);
-			return;
-		}
-
-		Block<?> mineBlock = Blocks.getBlock(mc.currentWorld.getBlockId(x, y, z));
-		if(mineBlock != null) {
-			float mineStrength = mineBlock.blockStrength(mc.currentWorld, x, y, z, side, mc.thePlayer);
-			
-			if(mineStrength < 1.0f) {
-				if(!repeat) {
-					sendStartDigPacket(x, y, z, side, xHit, yHit);
-					hitBlock(x, y, z, side, xHit, yHit);
-					setMineBlock(x, y, z);
-				}
-			}
-		}
-	}
-	
-	//Called 20 times per second when the mouse button is held and blocks are targeted
-	public void continueDestroyBlock(int x, int y, int z, Side side, double xHit, double yHit) {
-		if(!mc.thePlayer.getGamemode().hasBlockBreakingAnimation() || !mc.thePlayer.getGamemode().canInteract() || mc.thePlayer.getHeldObject() != null) {
-			return;
-		}
-		
-		swingItem(false);
-		
-		if(blockHitDelay > 0) {
-			blockHitDelay--;
-			return;
-		}
-		
-		Block<?> mineBlock = Blocks.getBlock(mc.currentWorld.getBlockId(x, y, z));
-		if(mineBlock != null) {	
-			syncCurrentPlayItem();
-			
-			float mineStrength = mineBlock.blockStrength(mc.currentWorld, x, y, z, side, mc.thePlayer);
-			if(mineStrength >= 1.0f) {
-				//Instant Mining
-				
-				setMineBlock(x, y, z);
-				destroyBlock(x, y, z, side, mc.thePlayer);
-				//Start Dig Packet acts as block destroy packet when instantmining
-				sendStartDigPacket(x, y, z, side, xHit, yHit);
-				
-				currentDamage = 0.0f;
-				previousDamage = 0.0f;
-				soundDelay = 0;
-				blockHitDelay = 1;
-			}else {
-				//Regular Mining
-				
-				if(!isMiningBlock(x, y, z)) {
-					sendStartDigPacket(x, y, z, side, xHit, yHit);
-					if (mc.currentWorld.getBlockLogic(x, y, z, BlockLogicDoor.class) == null) { // "Fixes" issue where at certain angles you can spam hit the top and bottom blocks of the door.
-						hitBlock(x, y, z, side, xHit, yHit);
-					}
-					currentDamage = 0.0f;
-					previousDamage = 0.0f;
-					setMineBlock(x, y, z);
-				}
-				
-				mc.particleEngine.crack(x, y, z, side);
-				playDigSound(mineBlock, x, y, z);
-				 
-				currentDamage += mineStrength;
-				if(currentDamage > 1.0f) {
-					destroyBlock(x, y, z, side, mc.thePlayer);
-					sendDestroyBlockPacket(x, y, z, side, xHit, yHit);
-					setMineBlock(null, null, null);
-					currentDamage = 0.0f;
-					previousDamage = 0.0f;
-					soundDelay = 0;
-					
-					int newBlockHitDelay;
-					if(mineStrength > 0.5f) {
-						newBlockHitDelay = 2;
-					}else if(mineStrength > 0.4f) {
-						newBlockHitDelay = 3;
-					}else if(mineStrength > 0.3f) {
-						newBlockHitDelay = 4;
-					}else {
-						newBlockHitDelay = 5;
-					}
-					
-					blockHitDelay = newBlockHitDelay;
-				}
-			}
-			
-		}else {
-			currentDamage = 0.0f;
-			previousDamage = 0.0f;
-			soundDelay = 0;
-		}
-	}
-	
-	public boolean swingItem(boolean force) {
-		if(swingCooldown == 0 || force) {
-			mc.thePlayer.swingItem();
-			swingCooldown = 5;
-			return true;
-		}
-		return false;
-	}
-
-	public boolean destroyBlock(int x, int y, int z, @NotNull Side side, @NotNull Player player) {
-		if (!player.getGamemode().canInteract() || mc.thePlayer.getHeldObject() != null) return false;
-		setMineBlock(null, null, null);
-		World world = mc.currentWorld;
-		Block<?> block = Blocks.getBlock(world.getBlockId(x, y, z));
-		if(block == null) return false;
-		
-		Item heldItem = null;
-		ItemStack heldItemStack = player.getCurrentEquippedItem();
-		if(heldItemStack != null) {
-			if(!heldItemStack.beforeDestroyBlock(world, block.id(), x, y, z, side, player)) {
-				return false;
-			}
-			heldItem = heldItemStack.getItem();
-		}
-		
-		world.playBlockEvent(EVENT_BLOCK_BREAK, x, y, z, block.id());
-		int meta = world.getBlockMetadata(x, y, z);
-		boolean removed = world.setBlockWithNotify(x, y, z, 0);
-		if(removed) {
-			block.onBlockDestroyedByPlayer(world, x, y, z, side, meta, player, heldItem);
-		}
-		return removed;
-	}
-
-	public void stopDestroyBlock(boolean leftClickDown) {
-		currentDamage = 0.0F;
-		previousDamage = 0.0f;
-		soundDelay = 0;
-		
-		if(blockHitDelay > 0) {
-			blockHitDelay--;
-		}
-	}
-	
-	protected void hitBlock(int x, int y, int z, Side side, double xHit, double yHit) {
-		if (!mc.thePlayer.getGamemode().canInteract() || mc.thePlayer.getHeldObject() != null) return;
-		mc.currentWorld.onBlockHit(mc.thePlayer, x, y, z, side);
-		
-		Block<?> block = Blocks.getBlock(mc.currentWorld.getBlockId(x, y, z));
-		if(block != null) {
-			block.onBlockLeftClicked(mc.currentWorld, x, y, z, mc.thePlayer, side, xHit, yHit);
-		}
-	}
-	
-	private boolean isMiningBlock(int x, int y, int z) {
-		return miningX != null && miningX == x && miningY != null && miningY == y && miningZ != null && miningZ == z;
-	}
-	
-	private void setMineBlock(Integer x, Integer y, Integer z) {
-		this.miningX = x;
-		this.miningY = y;
-		this.miningZ = z;
-	}
-
-	public void render(float f) {
-		if (currentDamage <= 0.0F) {
-			mc.hudIngame.damageGuiPartialTime = 0.0F;
-			mc.renderGlobal.destroyProgress = 0.0F;
-		} else {
-			float f1 = previousDamage + (currentDamage - previousDamage) * f;
-			mc.hudIngame.damageGuiPartialTime = f1;
-			mc.renderGlobal.destroyProgress = f1;
-		}
-
-        mc.ppm.render(f);
+
+    protected final @NotNull Minecraft mc;
+
+    protected float destroyProgress;
+    protected float oDestroyProgress;
+    protected int soundDelay;
+    protected int swingCooldown = 0;
+    protected int destroyDelay;
+    protected @Nullable TilePosc mining;
+
+    public PlayerController(final @NotNull Minecraft minecraft) {
+        this.mc = minecraft;
+    }
+
+    /**
+     * Called when the mouse is clicked and about 5 times per second while the button is held down.
+     * <br>
+     * {@code repeat} is false when the mouse was clicked this frame.
+     */
+    public void startDestroyBlock(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit, final boolean repeat) {
+        final @NotNull World world = Objects.requireNonNull(this.mc.currentWorld);
+        final @NotNull Player player = Objects.requireNonNull(this.mc.thePlayer);
+
+        if (player.getHeldObject() != null || !player.getGamemode().canInteract()) {
+            return;
+        }
+
+        if (!player.getGamemode().hasBlockBreakingAnimation()) {
+            this.swingItem(true);
+
+            final @Nullable ItemStack heldItem = player.getCurrentEquippedItem();
+            if (heldItem != null && heldItem.getItem().hasTag(ItemTags.PREVENT_CREATIVE_MINING)) {
+                return;
+            }
+
+            this.destroyBlock(tilePos, side);
+            this.sendStartDigPacket(tilePos, side, xHit, yHit);
+            return;
+        }
+
+        final @NotNull Block<?> mineBlock = world.getBlockType(tilePos);
+        final float mineStrength = mineBlock.getStrength(world, tilePos, side, player);
+
+        if (mineStrength < 1.0f) {
+            if (!repeat) {
+                this.sendStartDigPacket(tilePos, side, xHit, yHit);
+                this.hitBlock(tilePos, side, xHit, yHit);
+                this.setMineBlock(tilePos);
+            }
+        }
+    }
+
+    //Called 20 times per second when the mouse button is held and blocks are targeted
+    public void continueDestroyBlock(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
+        final @NotNull World world = Objects.requireNonNull(this.mc.currentWorld);
+        final @NotNull Player player = Objects.requireNonNull(this.mc.thePlayer);
+
+        if (!player.getGamemode().hasBlockBreakingAnimation() || !player.getGamemode().canInteract() || player.getHeldObject() != null) {
+            return;
+        }
+
+        this.swingItem(false);
+
+        if (this.destroyDelay > 0) {
+            this.destroyDelay--;
+            return;
+        }
+
+        final Block<?> mineBlock = world.getBlockType(tilePos);
+        this.syncCurrentPlayItem();
+
+        final float mineStrength = mineBlock.getStrength(world, tilePos, side, player);
+        if (mineStrength >= 1.0f) {
+            //Instant Mining
+            this.setMineBlock(tilePos);
+            this.destroyBlock(tilePos, side);
+
+            //Start Dig Packet acts as block destroy packet when instantmining
+            this.sendStartDigPacket(tilePos, side, xHit, yHit);
+
+            this.destroyProgress = 0.0f;
+            this.oDestroyProgress = 0.0f;
+            this.soundDelay = 0;
+            this.destroyDelay = 1;
+        } else {
+            //Regular Mining
+            if (!this.isMiningBlock(tilePos)) {
+                this.sendStartDigPacket(tilePos, side, xHit, yHit);
+                if (world.getBlockLogic(tilePos, BlockLogicDoor.class) == null) { // "Fixes" issue where at certain angles you can spam hit the top and bottom blocks of the door.
+                    this.hitBlock(tilePos, side, xHit, yHit);
+                }
+                this.destroyProgress = 0.0f;
+                this.oDestroyProgress = 0.0f;
+                this.setMineBlock(tilePos);
+            }
+
+            Objects.requireNonNull(this.mc.particleEngine).crack(tilePos.x(), tilePos.y(), tilePos.z(), side);
+            this.playDigSound(mineBlock, tilePos);
+
+            this.destroyProgress += mineStrength;
+            if (this.destroyProgress > 1.0f) {
+                this.destroyBlock(tilePos, side);
+                this.sendDestroyBlockPacket(tilePos, side, xHit, yHit);
+                this.setMineBlock(null);
+                this.destroyProgress = 0.0f;
+                this.oDestroyProgress = 0.0f;
+                this.soundDelay = 0;
+
+                final int newDestroyDelay;
+                if (mineStrength > 0.5f) {
+                    newDestroyDelay = 2;
+                } else if (mineStrength > 0.4f) {
+                    newDestroyDelay = 3;
+                } else if (mineStrength > 0.3f) {
+                    newDestroyDelay = 4;
+                } else {
+                    newDestroyDelay = 5;
+                }
+
+                this.destroyDelay = newDestroyDelay;
+            }
+        }
+
+    }
+
+    public boolean swingItem(final boolean force) {
+        final @NotNull Player player = Objects.requireNonNull(this.mc.thePlayer);
+
+        if (this.swingCooldown == 0 || force) {
+            player.swingItem();
+            this.swingCooldown = 5;
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean destroyBlock(final @NotNull TilePosc tilePos, final @NotNull Side side) {
+        final @NotNull World world = Objects.requireNonNull(this.mc.currentWorld);
+        final @NotNull Player player = Objects.requireNonNull(this.mc.thePlayer);
+
+        if (!player.getGamemode().canInteract() || player.getHeldObject() != null) {
+            return false;
+        }
+
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        final int data = world.getBlockData(tilePos);
+
+        this.setMineBlock(null);
+
+        @Nullable Item heldItem = null;
+        final @Nullable ItemStack heldItemStack = player.getCurrentEquippedItem();
+        if (heldItemStack != null) {
+            if (!heldItemStack.beforeBlockDestroyed(world, player, block, tilePos, side)) {
+                return false;
+            }
+            heldItem = heldItemStack.getItem();
+        }
+
+        world.playBlockEvent(tilePos, EVENT_BLOCK_BREAK, block.id());
+
+        if (world.setBlockTypeNotify(tilePos, Blocks.AIR)) {
+            block.onDestroyedByPlayer(world, tilePos, side, data, player, heldItem);
+            return true;
+        }
+
+        return false;
+    }
+
+    public void stopDestroyBlock() {
+        this.destroyProgress = 0.0F;
+        this.oDestroyProgress = 0.0f;
+        this.soundDelay = 0;
+
+        if (this.destroyDelay > 0) {
+            this.destroyDelay--;
+        }
     }
 
-	public float getBlockReachDistance() {
-		return mc.thePlayer.getGamemode().getBlockReachDistance();
-	}
-
-	public float getEntityReachDistance() {
-		return mc.thePlayer.getGamemode().getEntityReachDistance();
-	}
-
-	public void initPlayer(Player player) {
-		player.yRot = -180F;
-	}
-
-	public void tick() {
-		if(swingCooldown > 0) swingCooldown--;
-		
-		syncCurrentPlayItem();
-		previousDamage = currentDamage;
-		mc.sndManager.tick();
-		mc.ppm.tick();
-	}
-
-	public boolean canHurtPlayer() {
-		return true;
-	}
-
-	public void adjustPlayer(Player player) {
-	}
-
-	/**
-	 * Used to dynamically use or place an ItemStack on any given tile.
-	 * <p>
-	 * (i.e. interacting with a chest while holding a block, defaulting to opening the chest when standing, vs. placing the block when crouched)
-	 */
-	public boolean useOrPlaceItemStackOnTile(@NotNull Player player, @NotNull World world, @Nullable ItemStack itemstack, int blockX, int blockY, int blockZ, Side side, double xPlaced, double yPlaced)
-	{
-		if (!player.getGamemode().canInteract()) return false;
-		int blockId = world.getBlockId(blockX, blockY, blockZ);
-		if (player.getHeldObject() == null) {
-			if (player.isSneaking() && itemstack == null) { // If crouched and hand empty try to pickup block entity
-				TileEntity tileEntity = world.getTileEntity(blockX, blockY, blockZ);
-				if (tileEntity != null && tileEntity.canBeCarried(world, player)) {
-					player.setHeldObject(tileEntity.pickup(world, player));
-					return true;
-				}
-			}
-			if (!player.isSneaking() || itemstack == null) {  // If standing or hand empty perform block right click method
-				if (blockId > 0 && Blocks.blocksList[blockId].onBlockRightClicked(world, blockX, blockY, blockZ, player, side, xPlaced, yPlaced)) {
-					return true;
-				}
-			}
-			if (itemstack == null) { // No stack then do nothing
-				return false;
-			} else { // Use itemstack
-				return itemstack.useItem(player, world, blockX, blockY, blockZ, side, xPlaced, yPlaced);
-			}
-		} else {
-			if (!player.isSneaking()) {  // If standing or hand empty perform block right click method
-				if (blockId > 0 && Blocks.blocksList[blockId].onBlockRightClicked(world, blockX, blockY, blockZ, player, side, xPlaced, yPlaced)) {
-					return true;
-				}
-			}
-			boolean didPlace = player.getHeldObject().tryPlace(world, player, blockX, blockY, blockZ, side, xPlaced, yPlaced);
-			if (didPlace) {
-				player.setHeldObject(null);
-			}
-			return didPlace;
-		}
-	}
-
-	/**
-	 * Used to specifically use an ItemStack on nothing, most commonly defaulting to typical "item use" behavior.
-	 * <p>
-	 * (i.e. throwing a fishing rod or shooting a bow)
-	 */
-	public boolean useItemStackOnNothing(Player player, World world, ItemStack stack) {
-		if (!player.getGamemode().canInteract()) return false;
-		int prevStackSize = stack.stackSize;
-		ItemStack newItemStack = stack.useItemRightClick(world, player);
-		if(newItemStack != stack || newItemStack.stackSize != prevStackSize) {
-			player.inventory.mainInventory[player.inventory.getCurrentSlot()] = newItemStack;
-			if(newItemStack == null || newItemStack.stackSize <= 0) {
-				player.inventory.mainInventory[player.inventory.getCurrentSlot()] = null;
-			}
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Used to exclusively place an ItemStack. No interactions, just placing a held ItemStack.
-	 * <p>
-	 * (i.e. placing blocks using easy bridge)
-	 */
-	public boolean placeItemStackOnTile(@NotNull Player player, @NotNull World world, @Nullable ItemStack itemstack, int blockX, int blockY, int blockZ, Side side, double xPlaced, double yPlaced) {
-		if (!player.getGamemode().canInteract()) return false;
-		if (player.getHeldObject() == null) {
-			if (itemstack == null) { // No stack then do nothing
-				return false;
-			} else { // Use itemstack
-				return itemstack.useItem(player, world, blockX, blockY, blockZ, side, xPlaced, yPlaced);
-			}
-		}
-		return false;
-	}
-
-	public Player createPlayer(World world) {
-		return new PlayerLocal(mc, world, mc.session, world.dimension.id);
-	}
-
-	public boolean interact(Player player, Entity entity) {
-		if (!player.getGamemode().canInteract()) return false;
-		return player.useCurrentItemOnEntity(entity);
-	}
-
-	public void attack(@NotNull Player player, @NotNull Entity entity) {
-		if (!player.getGamemode().canInteract()) return;
-		player.attackTargetEntityWithCurrentItem(entity);
-	}
-
-	public ItemStack handleInventoryMouseClick(int windowId, InventoryAction action, int[] args, Player player) {
-		return player.craftingInventory.clicked(action, args, player);
-	}
-
-	public void handleCloseInventory(int i, Player player) {
-		player.craftingInventory.onCraftGuiClosed(player);
-		player.craftingInventory = player.inventorySlots;
-	}
-	
-	public void playDigSound(Block<?> block, int x, int y, int z) {
-		if(soundDelay <= 0) {
-			mc.currentWorld.playBlockSoundEffect(null, x + 0.5f, y + 0.5f, z + 0.5f, block, EnumBlockSoundEffectType.DIG);
-			soundDelay = 3;
-		}else {
-			soundDelay--;
-		}
-	}
-
-	protected void syncCurrentPlayItem() {}
-	
-	public void sendStartDigPacket(int x, int y, int z, Side side, double xHit, double yHit) {}
-	
-	public void sendDestroyBlockPacket(int x, int y, int z, Side side, double xHit, double yHit) {}
-
-	public void initWorld(World world) {}
-
-	public void setPaintingType(ArtType art)
-	{
-		mc.thePlayer.setSelectedArt(art);
-	}
+    protected void hitBlock(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
+        final @NotNull World world = Objects.requireNonNull(this.mc.currentWorld);
+        final @NotNull Player player = Objects.requireNonNull(this.mc.thePlayer);
+
+        if (!player.getGamemode().canInteract() || player.getHeldObject() != null) {
+            return;
+        }
+
+        world.onBlockHit(player, tilePos, side);
+
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        block.onAttacked(world, tilePos, player, side, xHit, yHit);
+    }
+
+    private boolean isMiningBlock(final @NotNull TilePosc tilePos) {
+        return tilePos.equals(this.mining);
+    }
+
+    private void setMineBlock(final @Nullable TilePosc tilePos) {
+        this.mining = tilePos;
+    }
+
+    public void render(final float partialTick) {
+        final @NotNull HudIngame hud = Objects.requireNonNull(this.mc.hudIngame);
+        final @NotNull RenderGlobal renderGlobal = Objects.requireNonNull(this.mc.renderGlobal);
+
+        if (this.destroyProgress <= 0.0F) {
+            hud.destroyProgress = 0.0F;
+            renderGlobal.destroyProgress = 0.0F;
+        } else {
+            final float lDestroyProgress = this.oDestroyProgress + (this.destroyProgress - this.oDestroyProgress) * partialTick;
+            hud.destroyProgress = lDestroyProgress;
+            renderGlobal.destroyProgress = lDestroyProgress;
+        }
+
+        this.mc.ppm.render(partialTick);
+    }
+
+    public void tick() {
+        if (this.swingCooldown > 0) {
+            this.swingCooldown--;
+        }
+
+        this.syncCurrentPlayItem();
+        this.oDestroyProgress = this.destroyProgress;
+        this.mc.sndManager.tick();
+
+        this.mc.ppm.tick();
+    }
+
+    /**
+     * Used to dynamically use or place an ItemStack on any given tile.
+     * <p>
+     * (i.e. interacting with a chest while holding a block, defaulting to opening the chest when standing, vs. placing the block when crouched)
+     */
+    public boolean useOrPlaceItemStackOnTile(final @NotNull Player player, final @NotNull World world, final @Nullable ItemStack itemStack, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xPlaced, final double yPlaced) {
+        if (!player.getGamemode().canInteract()) {
+            return false;
+        }
+
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+
+        if (player.getHeldObject() == null) {
+            if (player.isSneaking() && itemStack == null) { // If crouched and hand empty try to pickup block entity
+                final @Nullable TileEntity tileEntity = world.getTileEntity(tilePos);
+                if (tileEntity != null && tileEntity.canBeCarried(world, player)) {
+                    player.setHeldObject(tileEntity.pickup(world, player));
+                    return true;
+                }
+            }
+            if (!player.isSneaking() || itemStack == null) {  // If standing or hand empty perform block right click method
+                if (block.onInteracted(world, tilePos, player, side, xPlaced, yPlaced)) {
+                    return true;
+                }
+            }
+            if (itemStack == null) { // No stack then do nothing
+                return false;
+            } else { // Use itemStack
+                return itemStack.useItemOnBlock(player, world, tilePos, side, xPlaced, yPlaced);
+            }
+        } else {
+            if (!player.isSneaking()) {  // If standing or hand empty perform block right click method
+                if (block.onInteracted(world, tilePos, player, side, xPlaced, yPlaced)) {
+                    return true;
+                }
+            }
+
+            if (player.getHeldObject().tryPlace(world, player, tilePos.x(), tilePos.y(), tilePos.z(), side, xPlaced, yPlaced)) {
+                player.setHeldObject(null);
+                return true;
+            }
+
+            return false;
+        }
+    }
+
+    /**
+     * Used to specifically use an ItemStack on nothing, most commonly defaulting to typical "item use" behavior.
+     * <p>
+     * (i.e. throwing a fishing rod or shooting a bow)
+     */
+    public boolean useItemStackOnNothing(final @NotNull Player player, final @NotNull World world, final @NotNull ItemStack stack) {
+        if (!player.getGamemode().canInteract()) {
+            return false;
+        }
+
+        final int prevStackSize = stack.stackSize;
+        final @Nullable ItemStack newItemStack = stack.useItem(world, player);
+        if (newItemStack != stack || newItemStack.stackSize != prevStackSize) {
+            player.inventory.setCurrentItem(newItemStack);
+            if (newItemStack == null || newItemStack.stackSize <= 0) {
+                player.inventory.setCurrentItem(null);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Used to exclusively place an ItemStack. No interactions, just placing a held ItemStack.
+     * <p>
+     * (i.e. placing blocks using easy bridge)
+     */
+    public boolean placeItemStackOnTile(final @NotNull Player player, final @NotNull World world, final @Nullable ItemStack itemStack, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xPlaced, final double yPlaced) {
+        if (!player.getGamemode().canInteract()) {
+            return false;
+        }
+
+        if (player.getHeldObject() == null) {
+            if (itemStack == null) { // No stack then do nothing
+                return false;
+            } else { // Use itemStack
+                return itemStack.useItemOnBlock(player, world, tilePos, side, xPlaced, yPlaced);
+            }
+        }
+
+        return false;
+    }
+
+    public @NotNull Player createPlayer(final @NotNull World world) {
+        return new PlayerLocal(this.mc, world, Objects.requireNonNull(this.mc.session), Objects.requireNonNull(world.dimension).id);
+    }
+
+    public boolean interact(final @NotNull Player player, final @NotNull Entity entity) {
+        if (!player.getGamemode().canInteract()) {
+            return false;
+        }
+
+        return player.useCurrentItemOnEntity(entity);
+    }
+
+    public void attack(final @NotNull Player player, final @NotNull Entity entity) {
+        if (!player.getGamemode().canInteract()) {
+            return;
+        }
+
+        player.attackTargetEntityWithCurrentItem(entity);
+    }
+
+    public @Nullable ItemStack handleInventoryMouseClick(final int windowId, final @NotNull InventoryAction action, final int @Nullable [] args, final @NotNull Player player) {
+        return player.containerMenu.clicked(action, args, player);
+    }
+
+    public void handleCloseInventory(final int windowId, final @NotNull Player player) {
+        player.containerMenu.onCraftGuiClosed(player);
+        player.containerMenu = player.inventoryMenu;
+    }
+
+    public void playDigSound(final @NotNull Block<?> block, final @NotNull TilePosc tilePos) {
+        if (this.soundDelay <= 0) {
+            Objects.requireNonNull(this.mc.currentWorld).playBlockSoundEffect(null, tilePos.x() + 0.5f, tilePos.y() + 0.5f, tilePos.z() + 0.5f, block, EnumBlockSoundEffectType.DIG);
+            this.soundDelay = 3;
+        } else {
+            this.soundDelay--;
+        }
+    }
+
+    protected void syncCurrentPlayItem() {
+        // Do nothing
+    }
+
+    public void sendStartDigPacket(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
+        // Do nothing
+    }
+
+    public void sendDestroyBlockPacket(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
+    }
+
+    public void setPaintingType(final @NotNull ArtType art) {
+        Objects.requireNonNull(this.mc.thePlayer).setSelectedArt(art);
+    }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java
index 039a95ac7..7d210aca9 100644
--- a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java
+++ b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerMP.java
@@ -4,6 +4,7 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.entity.player.PlayerLocalMultiplayer;
 import net.minecraft.client.net.handler.PacketHandlerClient;
 import net.minecraft.core.InventoryAction;
+import net.minecraft.core.block.Block;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.ArtType;
@@ -12,116 +13,122 @@ import net.minecraft.core.net.packet.*;
 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.TilePosc;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
-public class PlayerControllerMP extends PlayerController {
-
-	protected PacketHandlerClient netHandler;
-	protected int currentItem;
-
-	public PlayerControllerMP(Minecraft minecraft, PacketHandlerClient netHandler) {
-		super(minecraft);
-		
-		this.netHandler = netHandler;
-	}
-
-	@Override
-	public boolean destroyBlock(int x, int y, int z, @NotNull Side side, @NotNull Player player) {
-		int id = mc.currentWorld.getBlockId(x, y, z);
-		boolean removed = super.destroyBlock(x, y, z, side, player);
-		ItemStack item = mc.thePlayer.getCurrentEquippedItem();
-		if (item != null) {
-			item.onDestroyBlock(mc.currentWorld, id, x, y, z, side, mc.thePlayer);
-			if (item.stackSize <= 0) {
-				mc.thePlayer.destroyCurrentEquippedItem();
-			}
-		}
-		return removed;
-	}
-	
-	@Override
-	protected void hitBlock(int x, int y, int z, Side side, double xHit, double yHit) {
-		super.hitBlock(x, y, z, side, xHit, yHit);
-		netHandler.addToSendQueue(new PacketPlayerAction(PacketPlayerAction.ACTION_DIG_CONTINUED, x, y, z, side, xHit, yHit));
-	}
-	
-	@Override
-	public void sendStartDigPacket(int x, int y, int z, Side side, double xHit, double yHit) {
-		netHandler.addToSendQueue(new PacketPlayerAction(PacketPlayerAction.ACTION_DIG_START, x, y, z, side, xHit, yHit));
-	}
-	
-	@Override
-	public void sendDestroyBlockPacket(int x, int y, int z, Side side, double xHit, double yHit) {
-		netHandler.addToSendQueue(new PacketPlayerAction(PacketPlayerAction.ACTION_DIG_COMPLETE, x, y, z, side, xHit, yHit));
-	}
-	
-	@Override
-	protected void syncCurrentPlayItem() {
-		int i = mc.thePlayer.inventory.getCurrentSlot();
-		if (i != currentItem) {
-			currentItem = i;
-			netHandler.addToSendQueue(new PacketSetCarriedItem(currentItem));
-		}
-	}
-
-	@Override
-	public boolean useOrPlaceItemStackOnTile(Player entityplayer, World world, ItemStack itemstack, int blockX, int blockY, int blockZ, Side side, double xPlaced, double yPlaced) {
-		syncCurrentPlayItem();
-		netHandler.addToSendQueue(new PacketUseOrPlaceItemStack(blockX, blockY, blockZ, side.getDirection(), entityplayer.inventory.getCurrentItem(), xPlaced, yPlaced, PacketUseOrPlaceItemStack.TYPE_USE_OR_PLACE_ON_TILE));
-		return super.useOrPlaceItemStackOnTile(entityplayer, world, itemstack, blockX, blockY, blockZ, side, xPlaced, yPlaced);
-	}
-
-	@Override
-	public boolean useItemStackOnNothing(Player entityplayer, World world, ItemStack itemstack) {
-		syncCurrentPlayItem();
-		netHandler.addToSendQueue(new PacketUseOrPlaceItemStack(-1, -1, -1, Direction.NONE, entityplayer.inventory.getCurrentItem(), 0, 0, PacketUseOrPlaceItemStack.TYPE_USE_ON_NOTHING));
-		return super.useItemStackOnNothing(entityplayer, world, itemstack);
-	}
-
-	@Override
-	public boolean placeItemStackOnTile(Player entityplayer, World world, ItemStack itemstack, int blockX, int blockY, int blockZ, Side side, double xPlaced, double yPlaced) {
-		syncCurrentPlayItem();
-		netHandler.addToSendQueue(new PacketUseOrPlaceItemStack(blockX, blockY, blockZ, side.getDirection(), entityplayer.inventory.getCurrentItem(), xPlaced, yPlaced, PacketUseOrPlaceItemStack.TYPE_PLACE_ONLY));
-		return super.placeItemStackOnTile(entityplayer, world, itemstack, blockX, blockY, blockZ, side, xPlaced, yPlaced);
-	}
-
-	@Override
-	public Player createPlayer(World world) {
-		return new PlayerLocalMultiplayer(mc, world, mc.session, netHandler);
-	}
-
-	@Override
-	public void attack(@NotNull Player entityplayer, @NotNull Entity entity) {
-		syncCurrentPlayItem();
-		netHandler.addToSendQueue(new PacketEntityInteract(entityplayer.id, entity.id, PacketEntityInteract.ACTION_ATTACK));
-		entityplayer.attackTargetEntityWithCurrentItem(entity);
-	}
-
-	@Override
-	public boolean interact(Player entityplayer, Entity entity) {
-		syncCurrentPlayItem();
-		netHandler.addToSendQueue(new PacketEntityInteract(entityplayer.id, entity.id, PacketEntityInteract.ACTION_INTERACT));
-		return entityplayer.useCurrentItemOnEntity(entity);
-	}
-
-	@Override
-	public ItemStack handleInventoryMouseClick(int windowId, InventoryAction action, int[] args, Player entityplayer) {
-		short actionId = entityplayer.craftingInventory.backup(entityplayer.inventory);
-		ItemStack itemstack = super.handleInventoryMouseClick(windowId, action, args, entityplayer);
-		netHandler.addToSendQueue(new PacketContainerClick(windowId, action, args, itemstack, actionId));
-		return itemstack;
-	}
-
-	@Override
-	public void handleCloseInventory(int i, Player entityplayer) {
-		if (i == -9999) {
-        } else {
+import java.util.Objects;
+
+public class PlayerControllerMP
+    extends PlayerController {
+
+    protected @NotNull PacketHandlerClient packetHandler;
+    protected int currentSlot;
+
+    public PlayerControllerMP(final @NotNull Minecraft minecraft, final @NotNull PacketHandlerClient packetHandler) {
+        super(minecraft);
+
+        this.packetHandler = packetHandler;
+    }
+
+    @Override
+    public boolean destroyBlock(final @NotNull TilePosc tilePos, final @NotNull Side side) {
+        final @NotNull World world = Objects.requireNonNull(this.mc.currentWorld);
+        final @NotNull Player player = Objects.requireNonNull(this.mc.thePlayer);
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+
+        final boolean removed = super.destroyBlock(tilePos, side);
+        final @Nullable ItemStack item = player.getCurrentEquippedItem();
+        if (item != null) {
+            item.onBlockDestroyed(world, player, block, tilePos, side);
+            if (item.stackSize <= 0) {
+                player.destroyCurrentEquippedItem();
+            }
+        }
+        return removed;
+    }
+
+    @Override
+    protected void hitBlock(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
+        super.hitBlock(tilePos, side, xHit, yHit);
+        this.packetHandler.addToSendQueue(new PacketPlayerAction(PacketPlayerAction.ACTION_DIG_CONTINUED, tilePos.x(), tilePos.y(), tilePos.z(), side, xHit, yHit));
+    }
+
+    @Override
+    public void sendStartDigPacket(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
+        this.packetHandler.addToSendQueue(new PacketPlayerAction(PacketPlayerAction.ACTION_DIG_START, tilePos.x(), tilePos.y(), tilePos.z(), side, xHit, yHit));
+    }
+
+    @Override
+    public void sendDestroyBlockPacket(final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
+        this.packetHandler.addToSendQueue(new PacketPlayerAction(PacketPlayerAction.ACTION_DIG_COMPLETE, tilePos.x(), tilePos.y(), tilePos.z(), side, xHit, yHit));
+    }
+
+    @Override
+    protected void syncCurrentPlayItem() {
+        final int slot = Objects.requireNonNull(this.mc.thePlayer).inventory.getCurrentSlot();
+
+        if (slot != this.currentSlot) {
+            this.currentSlot = slot;
+            this.packetHandler.addToSendQueue(new PacketSetCarriedItem(this.currentSlot));
         }
-	}
+    }
+
+    @Override
+    public boolean useOrPlaceItemStackOnTile(final @NotNull Player player, final @NotNull World world, final @Nullable ItemStack itemStack, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xPlaced, final double yPlaced) {
+        this.syncCurrentPlayItem();
+        this.packetHandler.addToSendQueue(new PacketUseOrPlaceItemStack(tilePos.x(), tilePos.y(), tilePos.z(), side.getDirection(), player.inventory.getCurrentItem(), xPlaced, yPlaced, PacketUseOrPlaceItemStack.TYPE_USE_OR_PLACE_ON_TILE));
+        return super.useOrPlaceItemStackOnTile(player, world, itemStack, tilePos, side, xPlaced, yPlaced);
+    }
+
+    @Override
+    public boolean useItemStackOnNothing(final @NotNull Player player, final @NotNull World world, final @NotNull ItemStack itemStack) {
+        this.syncCurrentPlayItem();
+        this.packetHandler.addToSendQueue(new PacketUseOrPlaceItemStack(-1, -1, -1, Direction.NONE, player.inventory.getCurrentItem(), 0, 0, PacketUseOrPlaceItemStack.TYPE_USE_ON_NOTHING));
+        return super.useItemStackOnNothing(player, world, itemStack);
+    }
+
+    @Override
+    public boolean placeItemStackOnTile(final @NotNull Player player, final @NotNull World world, final @Nullable ItemStack itemStack, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xPlaced, final double yPlaced) {
+        this.syncCurrentPlayItem();
+        this.packetHandler.addToSendQueue(new PacketUseOrPlaceItemStack(tilePos.x(), tilePos.y(), tilePos.z(), side.getDirection(), player.inventory.getCurrentItem(), xPlaced, yPlaced, PacketUseOrPlaceItemStack.TYPE_PLACE_ONLY));
+        return super.placeItemStackOnTile(player, world, itemStack, tilePos, side, xPlaced, yPlaced);
+    }
+
+    @Override
+    public @NotNull Player createPlayer(final @NotNull World world) {
+        return new PlayerLocalMultiplayer(this.mc, world, Objects.requireNonNull(this.mc.session), this.packetHandler);
+    }
+
+    @Override
+    public void attack(final @NotNull Player player, final @NotNull Entity entity) {
+        this.syncCurrentPlayItem();
+        this.packetHandler.addToSendQueue(new PacketEntityInteract(player.id, entity.id, PacketEntityInteract.ACTION_ATTACK));
+        player.attackTargetEntityWithCurrentItem(entity);
+    }
+
+    @Override
+    public boolean interact(final @NotNull Player player, final @NotNull Entity entity) {
+        this.syncCurrentPlayItem();
+        this.packetHandler.addToSendQueue(new PacketEntityInteract(player.id, entity.id, PacketEntityInteract.ACTION_INTERACT));
+        return player.useCurrentItemOnEntity(entity);
+    }
+
+    @Override
+    public @Nullable ItemStack handleInventoryMouseClick(final int windowId, final @NotNull InventoryAction action, final int @Nullable [] args, final @NotNull Player player) {
+        final short actionId = player.containerMenu.backup(player.inventory);
+        final @Nullable ItemStack itemStack = super.handleInventoryMouseClick(windowId, action, args, player);
+        this.packetHandler.addToSendQueue(new PacketContainerClick(windowId, action, args, itemStack, actionId));
+        return itemStack;
+    }
+
+    @Override
+    public void handleCloseInventory(final int windowId, final @NotNull Player player) {
+        // Do nothing
+    }
 
-	@Override
-	public void setPaintingType(ArtType art)
-	{
-		netHandler.addToSendQueue(new PacketSetPaintingArt(art));
-	}
+    @Override
+    public void setPaintingType(final @NotNull ArtType art) {
+        this.packetHandler.addToSendQueue(new PacketSetPaintingArt(art));
+    }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerSP.java b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerSP.java
index 764cf9ece..f300416e3 100644
--- a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerSP.java
+++ b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerControllerSP.java
@@ -1,41 +1,54 @@
 package net.minecraft.client.player.controller;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+
+public class PlayerControllerSP
+    extends PlayerController {
+
+    public PlayerControllerSP(final @NotNull Minecraft minecraft) {
+        super(minecraft);
+    }
+
+    @Override
+    public boolean destroyBlock(final @NotNull TilePosc tilePos, final @NotNull Side side) {
+        final @NotNull World world = Objects.requireNonNull(this.mc.currentWorld);
+        final @NotNull Player player = Objects.requireNonNull(this.mc.thePlayer);
+
+        if (!player.getGamemode().canInteract() || player.getHeldObject() != null) {
+            return false;
+        }
+
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        final int data = world.getBlockData(tilePos);
+
+        final @Nullable TileEntity tileEntity = world.getTileEntity(tilePos);
+        final boolean removed = super.destroyBlock(tilePos, side);
+        final @Nullable ItemStack item = player.getCurrentEquippedItem();
+
+        if (item != null) {
+            item.onBlockDestroyed(world, player, block, tilePos, side);
+        }
+        if (removed && player.getGamemode().hasItemDrops()) {
+            block.onHarvest(world, player, tilePos, data, tileEntity);
+        }
+
+        if (item != null && item.stackSize <= 0) {
+            player.destroyCurrentEquippedItem();
+        }
+
+        return removed;
+    }
 
-public class PlayerControllerSP extends PlayerController {
-
-	public PlayerControllerSP(Minecraft minecraft) {
-		super(minecraft);
-	}
-
-	@Override
-	public boolean destroyBlock(int x, int y, int z, @NotNull Side side, @NotNull Player player) {
-		if (!player.getGamemode().canInteract() || mc.thePlayer.getHeldObject() != null) return false;
-		int id = mc.currentWorld.getBlockId(x, y, z);
-		int meta = mc.currentWorld.getBlockMetadata(x, y, z);
-		TileEntity tileEntity = mc.currentWorld.getTileEntity(x, y, z);
-		boolean removed = super.destroyBlock(x, y, z, side, player);
-		ItemStack item = mc.thePlayer.getCurrentEquippedItem();
-
-		if (item != null) {
-			item.onDestroyBlock(mc.currentWorld, id, x, y, z, side, mc.thePlayer);
-		}
-		if (removed && mc.thePlayer.getGamemode().hasItemDrops()) {
-			Blocks.blocksList[id].harvestBlock(mc.currentWorld, mc.thePlayer, x, y, z, meta, tileEntity);
-		}
-
-		if (item != null && item.stackSize <= 0)
-		{
-			mc.thePlayer.destroyCurrentEquippedItem();
-		}
-
-		return removed;
-	}
-	
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java
index 3ac8e1ae0..0b47c55be 100644
--- a/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java
@@ -1,8 +1,8 @@
 package net.minecraft.client.render;
 
-import java.util.HashMap;
 import java.util.Map;
 
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.entity.*;
 import net.minecraft.client.render.font.FontRenderer;
@@ -41,13 +41,11 @@ public final class EntityRendererDispatcher {
     public static double renderPosY = 0;
     public static double renderPosZ = 0;
 
-    private final @NotNull Map<@NotNull Class<? extends Entity>, @Nullable EntityRenderer<? extends Entity>> renderers;
+    private final @NotNull Map<@NotNull Class<? extends Entity>, @Nullable EntityRenderer<? extends Entity>> renderers = new Object2ObjectOpenHashMap<>();
     public final @NotNull TextureManager textureManager;
     public final @NotNull TexturePackList packList;
     public final @NotNull FontRenderer font;
     public final @NotNull GameSettings settings;
-    public @Nullable World world;
-    public @Nullable ICamera camera;
     public float viewLerpYaw = 0;
     public float viewLerpPitch = 0;
     public double viewLerpPosX = 0;
@@ -60,8 +58,6 @@ public final class EntityRendererDispatcher {
         this.packList = mc.texturePackList;
         this.font = mc.font;
         this.settings = mc.gameSettings;
-
-        this.renderers = new HashMap<>();
         reload();
     }
 
@@ -127,15 +123,14 @@ public final class EntityRendererDispatcher {
         return (EntityRenderer<T>) getRenderer(entity.getClass());
     }
 
-    public void cacheActiveRenderInfo(final @NotNull World world, final @NotNull ICamera camera, final float partialTick) {
-        if (this.world != world) {
-            for (final @Nullable EntityRenderer<?> renderer : this.renderers.values()) {
-                if (renderer == null) continue;
-                renderer.onWorldChanged(world);
-            }
+    public void onWorldChanged(@NotNull World world) {
+        for (final @Nullable EntityRenderer<?> renderer : this.renderers.values()) {
+            if (renderer == null) continue;
+            renderer.onWorldChanged(world);
         }
-        this.world = world;
-        this.camera = camera;
+    }
+
+    public void cacheActiveRenderInfo(final @NotNull ICamera camera, final float partialTick) {
         this.viewLerpYaw = (float) camera.getYRot(partialTick);
         this.viewLerpPitch = (float) camera.getXRot(partialTick);
         this.viewLerpPosX = camera.getX(partialTick);
@@ -143,7 +138,7 @@ public final class EntityRendererDispatcher {
         this.viewLerpPosZ = camera.getZ(partialTick);
     }
 
-    public <T extends Entity> void renderEntity(final TessellatorGeneral tessellator, final T entity, final float partialTick) {
+    public <T extends Entity> void renderEntity(final @NotNull TessellatorGeneral tessellator, final @NotNull T entity, final float partialTick) {
         final double lerpPosX = entity.xo + (entity.x - entity.xo) * (double) partialTick;
         final double lerpPosY = entity.yo + (entity.y - entity.yo) * (double) partialTick;
         final double lerpPosZ = entity.zo + (entity.z - entity.zo) * (double) partialTick;
diff --git a/game/client/src/main/java/net/minecraft/client/render/LightingCache.java b/game/client/src/main/java/net/minecraft/client/render/LightingCache.java
index bbb159fe4..bcbc65d37 100644
--- a/game/client/src/main/java/net/minecraft/client/render/LightingCache.java
+++ b/game/client/src/main/java/net/minecraft/client/render/LightingCache.java
@@ -2,7 +2,6 @@ package net.minecraft.client.render;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.block.Block;
-import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
@@ -25,7 +24,7 @@ final public class LightingCache {
 
     private final @NotNull TilePos offset = new TilePos(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
 
-    private Block<?> block;
+    private @NotNull Block<?> block;
     private WorldSource access;
     private final @NotNull TilePos queryPos = new TilePos();
 
@@ -46,8 +45,7 @@ final public class LightingCache {
     }
 
     private float calcBrightness(final @NotNull TilePos tilePos) {
-        final int blockId = this.access.getBlockId(tilePos);
-        final Block<?> block = Blocks.getBlock(blockId);
+        final Block<?> block = this.access.getBlockType(tilePos);
 
         if (this.block.emission >= 15) {
             return 1.0f;
@@ -55,9 +53,6 @@ final public class LightingCache {
         if (!this.mc.isAmbientOcclusionEnabled()) {
             return 1.0f;
         }
-        if (block == null) {
-            return 1.0f;
-        }
         return 1.0f - block.getAmbientOcclusionStrength(this.access, tilePos);
     }
 
@@ -75,7 +70,7 @@ final public class LightingCache {
     public boolean getOpacity(int relX, int relY, int relZ) {
         int index = (relX + CACHE_RANGE) * CACHE_SIZE * CACHE_SIZE + (relY + CACHE_RANGE) * CACHE_SIZE + (relZ + CACHE_RANGE);
         if (!bitGet(this.opacityCached, index)) {
-            this.opacityValue = bitSetState(this.opacityValue, index, Blocks.solid[this.access.getBlockId(this.offset.add(relX, relY, relZ, this.queryPos))]);
+            this.opacityValue = bitSetState(this.opacityValue, index, this.access.getBlockType(this.offset.add(relX, relY, relZ, this.queryPos)).solid());
             this.opacityCached = bitSet(this.opacityCached, index);
         }
         return bitGet(this.opacityValue, index);
diff --git a/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java b/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
index 77983d73f..3cf6d1e24 100644
--- a/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
+++ b/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
@@ -21,6 +21,7 @@ import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.terrain.ChunkRenderer;
 import net.minecraft.client.render.tessellator.RenderBuffer;
+import net.minecraft.client.render.tessellator.TessellatorAurora;
 import net.minecraft.client.render.tessellator.TessellatorShader;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -49,6 +50,7 @@ import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.BoundingVolume;
 import net.minecraft.core.world.AuroraProvider;
 import net.minecraft.core.world.LevelListener;
+import net.minecraft.core.world.pos.ChunkPos;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.season.Seasons;
 import net.minecraft.core.world.weather.Weather;
@@ -62,10 +64,7 @@ import org.joml.primitives.AABBd;
 import org.joml.primitives.AABBdc;
 import org.lwjgl.opengl.GL41;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
 
 import static java.awt.Color.HSBtoRGB;
 
@@ -101,6 +100,7 @@ public class RenderGlobal
     private int ticks;
     private @NotNull RenderBuffer starBuffer;
     private final @NotNull RenderBuffer skyBuffer;
+    private @Nullable RenderBuffer auroraBuffer;
     private int xMinChunk;
     private int yMinChunk;
     private int zMinChunk;
@@ -292,18 +292,94 @@ public class RenderGlobal
 
         this.noEntityRenderFrames = 2;
     }
+    private final TessellatorAurora tessellatorAurora = new TessellatorAurora("Aurora Tessellator", 524288);
+    public @Nullable RenderBuffer meshAurora(@NotNull ICamera camera) {
+        if (!this.mc.gameSettings.aurora.value) return null;
+        float celestialAngle = this.world.getCelestialAngle(1f);
+        float celestialAngleO = this.world.getCelestialAngle(0);
+        if (celestialAngle < 0.25f && celestialAngleO < 0.25f) return null;
+
+        double cameraX = camera.getX(1f);
+        double cameraXO = camera.getX(0);
+        double cameraZ = camera.getZ(1f);
+        double cameraZO = camera.getZ(0);
+
+        final double scale = 1f;
+        double auroraY = (this.world.getWorldType().getMaxY() + 64f) * 2f;
+
+        // Draw pieces
+        double time = this.world.getWorldTime();
+        AuroraProvider aurora = this.world.auroraProvider;
+
+        double radius = 512;
+        long worldTime = this.world.getWorldTime();
+
+        this.tessellatorAurora.startDrawing(DrawMode.QUADS);
+        for (double x = -radius; x < radius; x += 16) {
+            for (double z = -radius; z < radius; z += 16) {
+                double posXO = cameraXO + x;
+                double posX = cameraX + x;
+                double posZO = cameraZO + z;
+                double posZ = cameraZ + z;
+
+                double distanceSq = x * x + z + z;
+                double distanceSqPercentage = distanceSq / (radius * radius * 2);
+                distanceSqPercentage = 1f - distanceSqPercentage;
+
+                if (0.3f * distanceSqPercentage < 0.01f) continue;
+                double sampleO = aurora.getAuroraPresence(posXO, posZO, worldTime, celestialAngleO);
+                double sample = aurora.getAuroraPresence(posX, posZ, worldTime + 1, celestialAngle);
+                if (sample * 0.3f * distanceSqPercentage < 0.01f) continue;
+
+                double atan = org.joml.Math.atan2(z, x);
+                double rotationX = Math.cos(org.joml.Math.PI_OVER_2_f + atan);
+                double rotationZ = Math.sin(org.joml.Math.PI_OVER_2_f + atan);
+
+                for (int i = 0; i < 2; i++) {
+                    for (int j = 0; j < 2; j++) {
+                        double xOff = i * 8;
+                        double zOff = j * 8;
+
+                        double aurX = (x + xOff) * scale;
+                        double aurY = (auroraY * scale  * scale) + aurora.getAuroraHeightOffset((posX + xOff), (posZ + zOff), time + 1);
+                        double aurZ = (z + zOff) * scale;
+
+                        double aurYO = (auroraY * scale  * scale) + aurora.getAuroraHeightOffset((posX + xOff), (posZ + zOff), time);
+
+                        float r = aurora.getAuroraRedOffset((posX + xOff), (posZ + zOff), time + 1);
+                        float g = aurora.getAuroraGreenOffset((posX + xOff), (posZ + zOff), time + 1);
+                        float b = aurora.getAuroraBlueOffset((posX + xOff), (posZ + zOff), time + 1);
+
+                        float ro = aurora.getAuroraRedOffset((posXO + xOff), (posZO + zOff), time);
+                        float go = aurora.getAuroraGreenOffset((posXO + xOff), (posZO + zOff), time);
+                        float bo = aurora.getAuroraBlueOffset((posXO + xOff), (posZO + zOff), time);
+
+                        renderAuroraBeam(this.tessellatorAurora,
+                            aurX, aurY, aurZ,
+                            aurX, aurYO, aurZ,
+                            rotationX, rotationZ,
+                            r, g, b,
+                            ro, go, bo, scale,
+                            (float) (sample * 0.3f * distanceSqPercentage),
+                            (float) (sampleO * 0.3f * distanceSqPercentage));
+                    }
+                }
+            }
+        }
+        return this.tessellatorAurora.record(GL41.glGenVertexArrays(), GL41.glGenBuffers());
+    }
 
     public void renderAurora(ICamera camera, float partialTick) {
         float celestialAngle = this.world.getCelestialAngle(partialTick);
         if (celestialAngle < 0.25f) return;
 
-        double cameraX = camera.getX(partialTick);
         double cameraY = camera.getY(partialTick);
-        double cameraZ = camera.getZ(partialTick);
-        double cameraYaw = camera.getYRot(partialTick);
-        double temperature = this.world.getBlockTemperature((int) cameraX, (int) cameraZ);
+
+        TilePos cameraBlock = camera.getTilePos(partialTick);
+
+        double temperature = this.world.getBlockTemperature(cameraBlock);
         float mult = 0.0f;
-        if ((temperature <= 0.4f || this.world.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_WINTER_ENDLESS) && this.world.isChunkLoaded((int) cameraX, (int) cameraZ)) {
+        if ((temperature <= 0.4f || this.world.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_WINTER_ENDLESS) && this.world.isChunkLoaded(new ChunkPos(cameraBlock))) {
             // temperature from 0.0f to 0.4f
             temperature /= 0.4f;
             // temperature from 0.0f to 1.0f
@@ -332,73 +408,70 @@ public class RenderGlobal
         double totalDelta = this.targetAuroraBrightness - this.auroraBrightness;
         double auroraBrightnessDelta = totalDelta / 100;
         this.auroraBrightness += auroraBrightnessDelta * partialTick;
+        if (this.auroraBrightness <= 0) return;
 
-        GLRenderer.enableState(State.BLEND);
-        GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
         GLRenderer.globalSetLightEnabled(false);
-        GLRenderer.enableState(State.DEPTH_TEST);
-        GLRenderer.setDepthFunc(CompareFunc.ALWAYS);
+        GLRenderer.pushFrame();
+        GLRenderer.setColor4f(1f, 1f, 1f, (float) this.auroraBrightness);
+        GLRenderer.setShader(Shaders.AURORA);
+        float fov = GLRenderer.projectionM4f().perspectiveFov();
+        GLRenderer.projectionM4f().identity().perspective(fov, (float) this.mc.gameWindow.getWidthPixels() / (float) this.mc.gameWindow.getHeightPixels(), 0.05F, 2000); // Extend out farplane so turning camera doesn't clip aurora
+        GLRenderer.modelM4f().translate(0, (float) -cameraY, 0);
+        GLRenderer.getFogState().disable();
+        GLRenderer.setAlphaTest(0.0f);
+        GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
+        GLRenderer.enableState(State.BLEND);
+        GLRenderer.disableState(State.CULL_FACE);
+        GLRenderer.disableState(State.DEPTH_TEST);
 
-        final double scale = 1f;
-        double auroraY = (this.world.getWorldType().getMinY() + this.world.getWorldType().getYRange() + 64f) * 2f;
 
-        // Draw pieces
-        double rotationX = Math.cos(((cameraYaw * Math.PI) / 180D));
-        double rotationZ = Math.sin(((cameraYaw * Math.PI) / 180D));
+        if (this.auroraBuffer != null) {
+            this.textureManager.bindTexture(this.textureManager.loadTexture("/assets/minecraft/textures/environment/aurora.png"));
+            GLRenderer.render(this.auroraBuffer);
+        }
 
-        this.textureManager.bindTexture(this.textureManager.loadTexture("/assets/minecraft/textures/environment/aurora.png"));
-        double time = this.world.getWorldTime() + partialTick;
-        AuroraProvider aurora = this.world.auroraProvider;
+        GLRenderer.popFrame();
+        GLRenderer.globalSetLightEnabled(false);
+    }
 
-        double radius = 512;
-        long worldTime = this.world.getWorldTime();
+    private void renderAuroraBeam(@NotNull TessellatorAurora tessellator,
+                                  double x, double y, double z,
+                                  double xo, double yo, double zo,
+                                  double xOffset, double zOffset,
+                                  float redOffset, float greenOffset, float blueOffset,
+                                  float redOffsetO, float greenOffsetO, float blueOffsetO,
+                                  double scale,
+                                  float transparency, float transparencyO) {
+        float width = 16f;
 
-        TessellatorGeneral t = GLRenderer.getTessellator();
-        t.startDrawingQuads();
-        for (double x = -radius; x < radius; x += 16) {
-            for (double z = -radius; z < radius; z += 16) {
-                double posX = cameraX + x;
-                double posZ = cameraZ + z;
+        float r = org.joml.Math.clamp(0, 1, redOffset);
+        float g = org.joml.Math.clamp(0, 1, (255 / 255f) + greenOffset);
+        float b = org.joml.Math.clamp(0, 1, (127 / 255f) + blueOffset);
 
-                double distanceSq = x * x + z + z;
-                double distanceSqPercentage = distanceSq / (radius * radius + radius * radius);
-                distanceSqPercentage = 1f - distanceSqPercentage;
+        float rO = org.joml.Math.clamp(0, 1, redOffsetO);
+        float gO = org.joml.Math.clamp(0, 1, (255 / 255f) + greenOffsetO);
+        float bO = org.joml.Math.clamp(0, 1, (127 / 255f) + blueOffsetO);
 
-                double sample = aurora.getAuroraPresence(posX, posZ, worldTime, celestialAngle) * this.auroraBrightness;
-                if (sample * 0.3f * distanceSqPercentage < 0.01f) continue;
+        tessellator.addVertex(
+            x - xOffset * scale * width, y - scale * 256, z - zOffset * scale * width,
+            xo - xOffset * scale * width, yo - scale * 256, zo - zOffset * scale * width,
+            r, g, b, transparency, rO, gO, bO, transparencyO, 1, 1);
 
-                for (int i = 0; i < 2; i++) {
-                    for (int j = 0; j < 2; j++) {
-                        double xOff = i * 8;
-                        double zOff = j * 8;
-                        renderAuroraBeam(t,
-                            (x + xOff) * scale,
-                            (auroraY * scale - cameraY * scale) + aurora.getAuroraHeightOffset((posX + xOff), (posZ + zOff), time),
-                            (z + zOff) * scale, rotationX,
-                            rotationZ,
-                            aurora.getAuroraRedOffset((posX + xOff), (posZ + zOff), time),
-                            aurora.getAuroraGreenOffset((posX + xOff), (posZ + zOff), time),
-                            aurora.getAuroraBlueOffset((posX + xOff), (posZ + zOff), time), scale,
-                            (float) (sample * 0.3f * distanceSqPercentage));
-                    }
-                }
-            }
-        }
-        t.draw();
+       tessellator.addVertex(
+           x - xOffset * scale * width, y + scale, z - zOffset * scale * width,
+           xo - xOffset * scale * width, yo + scale, zo - zOffset * scale * width,
+           r, g, b, transparency, rO, gO, bO, transparencyO, 1, 0);
 
-        GLRenderer.setDepthFunc(CompareFunc.LESS_EQUAL);
-        GLRenderer.setColor4f(1f, 1f, 1f, 1f);
-        GLRenderer.disableState(State.BLEND);
-        GLRenderer.globalSetLightEnabled(false);
-    }
+       tessellator.addVertex(
+           x + xOffset * scale * width, y + scale, z + zOffset * scale * width,
+           xo + xOffset * scale * width, yo + scale, zo + zOffset * scale * width,
+           r, g, b, transparency, rO, gO, bO, transparencyO, 0, 0);
+
+       tessellator.addVertex(
+           x + xOffset * scale * width, y - scale * 256, z + zOffset * scale * width,
+           xo + xOffset * scale * width, yo - scale * 256, zo + zOffset * scale * width,
+           r, g, b, transparency, rO, gO, bO, transparencyO, 0, 1);
 
-    private void renderAuroraBeam(@NotNull TessellatorGeneral tessellator, double x, double y, double z, double xOffset, double zOffset, float redOffset, float greenOffset, float blueOffset, double scale, float transparency) {
-        float width = 16f;
-        tessellator.setColor4f(0 / 255f + redOffset, 255 / 255f + greenOffset, 127 / 255f + blueOffset, transparency);
-        tessellator.addVertexWithUV(x - xOffset * scale * width, y - scale * 256, z - zOffset * scale * width, 1.0, 1.0);
-        tessellator.addVertexWithUV(x - xOffset * scale * width, y + scale, z - zOffset * scale * width, 1.0, 0.0);
-        tessellator.addVertexWithUV(x + xOffset * scale * width, y + scale, z + zOffset * scale * width, 0.0, 0.0);
-        tessellator.addVertexWithUV(x + xOffset * scale * width, y - scale * 256, z + zOffset * scale * width, 0.0, 1.0);
     }
 
     public void renderEntities(ICamera camera, float partialTick) {
@@ -406,8 +479,8 @@ public class RenderGlobal
             this.noEntityRenderFrames--;
             return;
         }
-        TileEntityRenderDispatcher.instance.cacheActiveRenderInfo(this.world, camera, partialTick);
-        EntityRendererDispatcher.instance.cacheActiveRenderInfo(this.world, camera, partialTick);
+        TileEntityRenderDispatcher.instance.cacheActiveRenderInfo(camera, partialTick);
+        EntityRendererDispatcher.instance.cacheActiveRenderInfo(camera, partialTick);
         this.totalEntities = 0;
         this.renderedEntities = 0;
         this.culledEntities = 0;
@@ -460,7 +533,7 @@ public class RenderGlobal
         // DO NOT TURN THIS INTO A FOREACH EITHER
         for (int i = 0, tileEntitiesSize = this.renderableTileEntities.size(); i < tileEntitiesSize; i++) {
             TileEntity tileEntity = this.renderableTileEntities.get(i);
-            TileEntityRenderDispatcher.instance.renderTileEntity(tessellator, camera, tileEntity, partialTick);
+            TileEntityRenderDispatcher.instance.renderTileEntity(tessellator, camera, this.world, tileEntity, partialTick);
         }
     }
 
@@ -602,6 +675,12 @@ public class RenderGlobal
         this.cloudOffsetZ += this.cloudVelocityZ;
 
         this.ticks++;
+
+        if (this.auroraBuffer != null) {
+            this.auroraBuffer.delete();
+            this.auroraBuffer = null;
+        }
+        this.auroraBuffer = meshAurora(this.mc.activeCamera);
     }
 
     public void renderSky(float partialTick) {
@@ -1077,16 +1156,12 @@ public class RenderGlobal
             TextureRegistry.worldAtlas.bind();
             GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 0.25F);
             GLRenderer.pushFrame();
-            int k = this.world.getBlockId(tileHit.tilePos);
-            Block<?> block = k <= 0 ? null : Blocks.blocksList[k];
+            Block<?> block = this.world.getBlockType(tileHit.tilePos);
             GLRenderer.setPolygonOffset(-3F, -3F);
             GLRenderer.enableState(State.POLYGON_OFFSET_FILL);
             double x = camera.getX(partialTick);
             double y = camera.getY(partialTick);
             double z = camera.getZ(partialTick);
-            if (block == null) {
-                block = Blocks.STONE;
-            }
             tessellator.startDrawingQuads();
             tessellator.setTranslation(-x, -y, -z);
             tessellator.lockColor();
@@ -1122,7 +1197,7 @@ public class RenderGlobal
 
             if (hitResult instanceof HitResult.Tile hitTile) {
                 float expand = 0.002F;
-                Block<?> block = this.world.getBlock(hitTile.tilePos);
+                Block<?> block = this.world.getBlockType(hitTile.tilePos);
                 if (block != null) {
                     BoundingVolume volume = block.getBoundingVolume(this.world, hitTile.tilePos);
                     if (volume != null) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
index 4ac2f973d..198198164 100644
--- a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
+++ b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
@@ -416,7 +416,6 @@ public class TextureManager {
         this.mc.mainMenuBackground.refresh(errors);
 		
         Colorizers.reload();
-        Colorizers.update(true);
 
         this.mc.worldRenderer.lightmapHelper.setup();
 	}
diff --git a/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java
index 5ad45565f..ac82c1181 100644
--- a/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java
@@ -29,7 +29,6 @@ public final class TileEntityRenderDispatcher
     public final @NotNull TexturePackList packList;
     private final @NotNull FontRenderer font;
     public final @NotNull GameSettings settings;
-    public @Nullable World world;
     public @Nullable ICamera camera;
     public float viewLerpYaw = 0;
     public float viewLerpPitch = 0;
@@ -95,15 +94,8 @@ public final class TileEntityRenderDispatcher
         return getRenderer(tileEntity) != null;
     }
 
-    public void cacheActiveRenderInfo(final @NotNull World world, final @NotNull ICamera camera, final float partialTick)
+    public void cacheActiveRenderInfo(final @NotNull ICamera camera, final float partialTick)
     {
-        if(this.world != world) {
-            for (final @Nullable TileEntityRenderer<?> renderer : this.renderers.values()) {
-                if (renderer == null) continue;
-                renderer.onWorldChanged(world);
-            }
-        }
-        this.world = world;
         this.camera = camera;
         this.viewLerpYaw = (float) camera.getYRot(partialTick);
         this.viewLerpPitch = (float) camera.getXRot(partialTick);
@@ -112,16 +104,22 @@ public final class TileEntityRenderDispatcher
         this.viewLerpPosZ = camera.getZ(partialTick);
     }
 
-    public <T extends TileEntity> void renderTileEntity(final @NotNull TessellatorGeneral tessellator, final ICamera camera, final @NotNull T tileEntity, final float partialTick)
+    public void onWorldChanged(@NotNull World world) {
+        for (final @Nullable TileEntityRenderer<?> renderer : this.renderers.values()) {
+            if (renderer == null) continue;
+            renderer.onWorldChanged(world);
+        }
+    }
+
+    public <T extends TileEntity> void renderTileEntity(final @NotNull TessellatorGeneral tessellator, final @NotNull ICamera camera, final @NotNull World world, final @NotNull T tileEntity, final float partialTick)
     {
         final TileEntityRenderer<T> renderer = TileEntityRenderDispatcher.instance.getRenderer(tileEntity);
 
         if (renderer == null) return;
-        if(tileEntity.getDistanceFrom(this.viewLerpPosX, this.viewLerpPosY, this.viewLerpPosZ) > 4096D * settings.entityRenderDistance.value) return;
+        if(tileEntity.getDistanceFrom(this.viewLerpPosX, this.viewLerpPosY, this.viewLerpPosZ) > 4096D * this.settings.entityRenderDistance.value) return;
         if (!renderer.isVisible(tileEntity, camera, partialTick)) return;
 
-        assert this.world != null;
-        GLRenderer.setLightmapCoord1i(this.world.getLightmapCoord(tileEntity.x, tileEntity.y, tileEntity.z, 0));
+        GLRenderer.setLightmapCoord1i(world.getLightmapCoord(tileEntity.x, tileEntity.y, tileEntity.z, 0));
         GLRenderer.setColor3f(1f, 1f, 1f);
         renderer.doRender(tessellator,
             tileEntity,
diff --git a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
index 130c9ce4e..4c36e0855 100644
--- a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
@@ -129,8 +129,8 @@ public class WorldRenderer {
             return;
         }
 
-        final double blockReach = this.mc.playerController.getBlockReachDistance();
-        final double entityReach = this.mc.playerController.getEntityReachDistance();
+        final double blockReach = this.mc.thePlayer.getGamemode().getBlockReachDistance();
+        final double entityReach = this.mc.thePlayer.getGamemode().getEntityReachDistance();
 
         Vector3dc pos1 = this.mc.thePlayer.getPosition(partialTicks, true);
         Vector3dc look = this.mc.thePlayer.getViewVector(partialTicks);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
index 5cda20536..bf48ba4b2 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
@@ -1,23 +1,32 @@
 package net.minecraft.client.render.block.color;
 
+import net.minecraft.client.render.block.model.BlockModel;
 import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.util.dispatch.Dispatcher;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
+import net.minecraft.core.world.World;
+import org.jetbrains.annotations.NotNull;
 
 public final class BlockColorDispatcher
-    extends Dispatcher<Block<?>, BlockColor>
-{
+    extends Dispatcher<Block<?>, BlockColor> {
     private static final BlockColorDispatcher instance = new BlockColorDispatcher();
     private static final BlockColor defaultColor = new BlockColorDefault();
 
-    public static BlockColorDispatcher getInstance()
-    {
+    public static BlockColorDispatcher getInstance() {
         return instance;
     }
 
-    private BlockColorDispatcher()
-    {
+    private BlockColorDispatcher() {
+        reload();
+    }
+
+    public void onWorldChanged(@NotNull World world) {
+        reload();
+    }
+
+    public void reload() {
+        this.dispatches.clear();
         addDispatch(Blocks.ALGAE, new BlockColorCustom(Colorizers.grass));
         addDispatch(Blocks.FLUID_WATER_STILL, new BlockColorWater(Colorizers.water));
         addDispatch(Blocks.FLUID_WATER_FLOWING, new BlockColorWater(Colorizers.water));
@@ -45,9 +54,9 @@ public final class BlockColorDispatcher
         addDispatch(Blocks.NETHERRACK_CRYSTALLINE, new BlockColorCrystal(Colorizers.crystal));
     }
 
+
     @Override
-    protected BlockColor getDefault()
-    {
+    protected BlockColor getDefault() {
         return defaultColor;
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModel.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModel.java
index 7ce4d673a..d16c5cbda 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModel.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModel.java
@@ -6,6 +6,7 @@ import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogic;
 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 org.jetbrains.annotations.NotNull;
@@ -36,6 +37,9 @@ public abstract class BlockModel<T extends BlockLogic> {
     public abstract @Nullable IconCoordinate getOverlayTexture(int meta);
     public abstract int particleColorIndex(@NotNull WorldSource worldSource, @NotNull TilePosc tilePos, @NotNull Side side, int meta);
 
+    public void onWorldChanged(@NotNull World world) {
+    }
+
     public boolean isRetro() {
         return Minecraft.getMinecraft().currentWorld != null && Minecraft.getMinecraft().currentWorld.isRetro();
     }
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 295654d4c..7dc2e7fcf 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
@@ -25,6 +25,7 @@ import net.minecraft.client.render.block.model.generic.BlockModelGenericFenceThi
 import net.minecraft.client.render.block.model.generic.BlockModelGenericFlowerStackable;
 import net.minecraft.client.render.block.model.generic.BlockModelGenericFullyRotatable;
 import net.minecraft.client.render.block.model.generic.BlockModelGenericFurnace;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericGrass;
 import net.minecraft.client.render.block.model.generic.BlockModelGenericLayer;
 import net.minecraft.client.render.block.model.generic.BlockModelGenericLever;
 import net.minecraft.client.render.block.model.generic.BlockModelGenericMatcher;
@@ -62,15 +63,14 @@ import net.minecraft.client.util.dispatch.Dispatcher;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.world.World;
 import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.useless.dragonfly.data.block.mojang.BlockModelMojangData;
 
 public final class BlockModelDispatcher
-    extends Dispatcher<Block<?>, BlockModel<?>> {
+    extends Dispatcher<@NotNull Block<?>, @NotNull BlockModel<?>> {
     private static final Logger LOGGER = LogUtils.getLogger();
-    private static final Side[] S_TB = {Side.TOP, Side.BOTTOM};
-    private static final Side[] S_SIDES = {Side.NORTH, Side.EAST, Side.SOUTH, Side.WEST};
 
     private static BlockModelDispatcher instance = new BlockModelDispatcher();
 
@@ -80,14 +80,14 @@ public final class BlockModelDispatcher
 
     public static BlockModelEmpty<?> modelEmpty = new BlockModelEmpty<>(null);
 
-    public void addDispatch(final BlockModel<?> model) {
+    public void addDispatch(final @NotNull BlockModel<?> model) {
         addDispatch(model.block, model);
     }
 
     @Override
-    public void addDispatch(final Block<?> key, final BlockModel<?> value) {
+    public void addDispatch(final @NotNull Block<?> key, final @NotNull BlockModel<?> value) {
         if (hasDispatch(key)) {
-            throw new IllegalArgumentException("Block '" + key.toString() + "' already assigned a model!");
+            throw new IllegalArgumentException("Block '" + key + "' already assigned a model!");
         }
         this.dispatches.put(key, value);
     }
@@ -111,6 +111,12 @@ public final class BlockModelDispatcher
         reload();
     }
 
+    public void onWorldChanged(@NotNull World world) {
+        for (BlockModel<?> model : this.dispatches.values()) {
+            model.onWorldChanged(world);
+        }
+    }
+
     public void reload() {
         BlockModelMojangData.Cache.resetCache();
         this.dispatches.clear();
@@ -244,7 +250,7 @@ public final class BlockModelDispatcher
         addDispatch(new BlockModelGlass<>(Blocks.GLASS_TINTED, "minecraft:block/glass_tinted/").onRenderLayer(1).setAllTextures("minecraft:block/glass_tinted"));
         addDispatch(new BlockModelGeneric<>(Blocks.GLASS_STEEL, loadDataModel("minecraft:block/glass_steel")).forceCullSelf(true));
 
-        addDispatch(new BlockModelGeneric<>(Blocks.GRASS, loadDataModel("minecraft:block/grass")));
+        addDispatch(new BlockModelGenericGrass<>(Blocks.GRASS));
         addDispatch(new BlockModelGeneric<>(Blocks.GRASS_RETRO, loadDataModel("minecraft:block/grass_retro")));
         addDispatch(new BlockModelGeneric<>(Blocks.GRASS_SCORCHED, loadDataModel("minecraft:block/grass_scorched")));
         addDispatch(new BlockModelGeneric<>(Blocks.PATH_DIRT, loadDataModel("minecraft:block/grass_path")));
@@ -279,14 +285,14 @@ public final class BlockModelDispatcher
             .setTex("minecraft:block/water_still", Side.TOP));
         addDispatch(new BlockModelFluid<>(Blocks.FLUID_WATER_STILL)
             .onRenderLayer(1)
-            .setTex("minecraft:block/water_still", S_TB)
-            .setTex("minecraft:block/water_flowing", S_SIDES));
+            .setTex("minecraft:block/water_still", Side.TOP, Side.BOTTOM)
+            .setTex("minecraft:block/water_flowing", Side.NORTH, Side.EAST, Side.SOUTH, Side.WEST));
         addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_FLOWING)
             .setAllTextures("minecraft:block/lava_flowing")
             .setTex("minecraft:block/lava_still", Side.TOP));
         addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_STILL)
-            .setTex("minecraft:block/lava_still", S_TB)
-            .setTex("minecraft:block/lava_flowing", S_SIDES));
+            .setTex("minecraft:block/lava_still", Side.TOP, Side.BOTTOM)
+            .setTex("minecraft:block/lava_flowing", Side.NORTH, Side.EAST, Side.SOUTH, Side.WEST));
 
         addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_OAK, loadDataModel("minecraft:block/log/oak")));
         addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_PINE, loadDataModel("minecraft:block/log/pine")));
@@ -407,9 +413,6 @@ public final class BlockModelDispatcher
 
         addDispatch(new BlockModelGenericLever<>(Blocks.LEVER_COBBLE_STONE).render3D(false));
 
-        final float f = 0.5F;
-        final float f1 = 0.125F;
-        final float f2 = 0.5F;
         addDispatch(new BlockModelGenericPressurePlate<>(Blocks.PRESSURE_PLATE_STONE, "minecraft:block/pressure_plate/stone"));
         addDispatch(new BlockModelGenericPressurePlate<>(Blocks.PRESSURE_PLATE_PLANKS_OAK, "minecraft:block/pressure_plate/planks/oak"));
         addDispatch(new BlockModelGenericPressurePlate<>(Blocks.PRESSURE_PLATE_COBBLE_STONE, "minecraft:block/pressure_plate/cobbled_stone"));
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java
index 0e2e77a25..da9386924 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoor.java
@@ -25,8 +25,8 @@ public class BlockModelDoor<T extends BlockLogicDoor> extends BlockModelStandard
         AABBdc bounds = this.block.getBoundsFromState(worldSource, tilePos);
         TilePos queryPos = new TilePos();
 
-        boolean aboveIsDoor = Block.hasLogicClass(worldSource.getBlock(tilePos.up(queryPos)), BlockLogicDoor.class);
-        boolean belowIsDoor = Block.hasLogicClass(worldSource.getBlock(tilePos.down(queryPos)), BlockLogicDoor.class);
+        boolean aboveIsDoor = Block.hasLogicClass(worldSource.getBlockType(tilePos.up(queryPos)), BlockLogicDoor.class);
+        boolean belowIsDoor = Block.hasLogicClass(worldSource.getBlockType(tilePos.down(queryPos)), BlockLogicDoor.class);
 
         int meta = worldSource.getBlockData(tilePos);
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java
index be38e6e85..137361f9e 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceThin.java
@@ -81,13 +81,13 @@ public class BlockModelFenceThin<T extends BlockLogicFenceThin> extends BlockMod
         double fenceBottommostMaxU = fenceBottommostTex.getSubIconU(onePix * 16);
         double fenceBottommostMaxV = fenceBottommostTex.getSubIconV(onePix * 16);
 
-        Block<?> blockAbove = worldSource.getBlock(tilePos.up(queryPos));
+        Block<?> blockAbove = worldSource.getBlockType(tilePos.up(queryPos));
         boolean connectUpNorth = blockAbove == this.block && thin.canConnectTo(worldSource, tilePos.up(queryPos), Side.NORTH);
         boolean connectUpSouth = blockAbove == this.block && thin.canConnectTo(worldSource, tilePos.up(queryPos), Side.SOUTH);
         boolean connectUpEast = blockAbove == this.block && thin.canConnectTo(worldSource, tilePos.up(queryPos), Side.EAST);
         boolean connectUpWest = blockAbove == this.block && thin.canConnectTo(worldSource, tilePos.up(queryPos), Side.WEST);
 
-        Block<?> blockBelow = worldSource.getBlock(tilePos.down(queryPos));
+        Block<?> blockBelow = worldSource.getBlockType(tilePos.down(queryPos));
         boolean connectDownNorth = blockBelow == this.block && thin.canConnectTo(worldSource, tilePos.down(queryPos), Side.NORTH);
         boolean connectDownSouth = blockBelow == this.block && thin.canConnectTo(worldSource, tilePos.down(queryPos), Side.SOUTH);
         boolean connectDownEast = blockBelow == this.block && thin.canConnectTo(worldSource, tilePos.down(queryPos), Side.EAST);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java
index d37924c1d..7fd6d8f60 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java
@@ -57,36 +57,36 @@ public class BlockModelGlass<T extends BlockLogic> extends BlockModelTransparent
             TilePos queryPos = new TilePos();
             switch (side) {
                 case SOUTH:
-                    u = source.getBlockId(tilePos.up(queryPos)) == this.block.id();
-                    d = source.getBlockId(tilePos.down(queryPos)) == this.block.id();
-                    l = source.getBlockId(tilePos.west(queryPos)) == this.block.id();
-                    r = source.getBlockId(tilePos.east(queryPos)) == this.block.id();
+                    u = source.getBlockType(tilePos.up(queryPos)) == this.block;
+                    d = source.getBlockType(tilePos.down(queryPos)) == this.block;
+                    l = source.getBlockType(tilePos.west(queryPos)) == this.block;
+                    r = source.getBlockType(tilePos.east(queryPos)) == this.block;
                     break;
                 case NORTH:
-                    u = source.getBlockId(tilePos.up(queryPos)) == this.block.id();
-                    d = source.getBlockId(tilePos.down(queryPos)) == this.block.id();
-                    l = source.getBlockId(tilePos.east(queryPos)) == this.block.id();
-                    r = source.getBlockId(tilePos.west(queryPos)) == this.block.id();
+                    u = source.getBlockType(tilePos.up(queryPos)) == this.block;
+                    d = source.getBlockType(tilePos.down(queryPos)) == this.block;
+                    l = source.getBlockType(tilePos.east(queryPos)) == this.block;
+                    r = source.getBlockType(tilePos.west(queryPos)) == this.block;
                     break;
                 case WEST:
-                    u = source.getBlockId(tilePos.up(queryPos)) == this.block.id();
-                    d = source.getBlockId(tilePos.down(queryPos)) == this.block.id();
-                    l = source.getBlockId(tilePos.north(queryPos)) == this.block.id();
-                    r = source.getBlockId(tilePos.south(queryPos)) == this.block.id();
+                    u = source.getBlockType(tilePos.up(queryPos)) == this.block;
+                    d = source.getBlockType(tilePos.down(queryPos)) == this.block;
+                    l = source.getBlockType(tilePos.north(queryPos)) == this.block;
+                    r = source.getBlockType(tilePos.south(queryPos)) == this.block;
                     break;
                 case EAST:
-                    u = source.getBlockId(tilePos.up(queryPos)) == this.block.id();
-                    d = source.getBlockId(tilePos.down(queryPos)) == this.block.id();
-                    l = source.getBlockId(tilePos.south(queryPos)) == this.block.id();
-                    r = source.getBlockId(tilePos.north(queryPos)) == this.block.id();
+                    u = source.getBlockType(tilePos.up(queryPos)) == this.block;
+                    d = source.getBlockType(tilePos.down(queryPos)) == this.block;
+                    l = source.getBlockType(tilePos.south(queryPos)) == this.block;
+                    r = source.getBlockType(tilePos.north(queryPos)) == this.block;
                     break;
                 case TOP:
                 case BOTTOM:
                 default:
-                    u = source.getBlockId(tilePos.north(queryPos)) == this.block.id();
-                    d = source.getBlockId(tilePos.south(queryPos)) == this.block.id();
-                    l = source.getBlockId(tilePos.west(queryPos)) == this.block.id();
-                    r = source.getBlockId(tilePos.east(queryPos)) == this.block.id();
+                    u = source.getBlockType(tilePos.north(queryPos)) == this.block;
+                    d = source.getBlockType(tilePos.south(queryPos)) == this.block;
+                    l = source.getBlockType(tilePos.west(queryPos)) == this.block;
+                    r = source.getBlockType(tilePos.east(queryPos)) == this.block;
                     break;
             }
             return this.coordinates[(u ? UP : 0) | (d ? DOWN : 0) | (l ? LEFT : 0) | (r ? RIGHT : 0)];
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java
index e0ba0e1f2..c0b1680e4 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLayer.java
@@ -24,7 +24,7 @@ public class BlockModelLayer<T extends BlockLogic> extends BlockModelStandard<T>
 
     @Override
     public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePos tilePos, @NotNull Side side, int meta) {
-        if (!side.isVertical() && source.getBlockId(tilePos) == this.block.id() && source.getBlockData(tilePos) == meta) {
+        if (!side.isVertical() && source.getBlockType(tilePos) == this.block && source.getBlockData(tilePos) == meta) {
             return false;
         }
         return super.shouldSideBeRendered(source, bounds, tilePos, side);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java
index c82f91d7c..d76558d41 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java
@@ -57,7 +57,7 @@ public class BlockModelLeaves<T extends BlockLogic> extends BlockModelStandard<T
 
     @Override
     public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        if (!BlockModelGenericLeaves.fancyGraphics && source.getBlockId(tilePos) == this.block.id()) {
+        if (!BlockModelGenericLeaves.fancyGraphics && source.getBlockType(tilePos) == this.block) {
             return false;
         } else {
             return super.shouldSideBeRendered(source, bounds, tilePos, side);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTransparent.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTransparent.java
index c7202598d..b227d6627 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTransparent.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTransparent.java
@@ -18,7 +18,7 @@ public class BlockModelTransparent<T extends BlockLogic> extends BlockModelStand
 
     @Override
     public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        if (!this.renderInside && source.getBlockId(tilePos) == this.block.id()) {
+        if (!this.renderInside && source.getBlockType(tilePos) == this.block) {
             return false;
         } else {
             return super.shouldSideBeRendered(source, bounds, tilePos, side);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java b/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java
index eaeb793e3..ef1b1e6fb 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/RenderBlocks.java
@@ -3,7 +3,6 @@ package net.minecraft.client.render.block.model;
 import net.minecraft.client.render.LightingCache;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
@@ -20,7 +19,7 @@ import net.minecraft.core.world.WorldSource;
 import static net.minecraft.client.render.block.model.BlockModel.FULL_CUBE_THRESHOLD;
 
 public final class RenderBlocks {
-    public final Minecraft mc;
+    public final @NotNull Minecraft mc;
     public IconCoordinate overrideBlockTexture;
     public boolean flipTexture;
     public boolean renderAllFaces;
@@ -97,14 +96,7 @@ public final class RenderBlocks {
 
     public float getBlockBrightness(@NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
         if (this.mc.fullbright) return 1.0f;
-        int id = worldSource.getBlockId(tilePos);
-        Block<?> block = worldSource.getBlock(tilePos);
-        if (block != null) {
-
-            return block.getBrightness(worldSource, tilePos);
-        }
-
-        return worldSource.getBrightness(tilePos, Blocks.lightEmission[id]);
+        return worldSource.getBlockType(tilePos).getBrightness(worldSource, tilePos);
     }
 
     @Deprecated
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGeneric.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGeneric.java
index b5edb73fa..8040e6dd7 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGeneric.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGeneric.java
@@ -93,7 +93,7 @@ public class BlockModelGeneric<T extends BlockLogic> extends BlockModel<T> {
         if (direction != null) {
             TilePos shifted = blockPos.add(direction, new TilePos());
             if (this.forceCullSelf) {
-                return worldSource.getBlock(shifted) == this.block || worldSource.isBlockOpaqueCube(shifted);
+                return worldSource.getBlockType(shifted) == this.block || worldSource.isBlockOpaqueCube(shifted);
             } else {
                 return worldSource.isBlockOpaqueCube(shifted);
             }
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceThin.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceThin.java
index 3ad86b001..5ed90d3df 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceThin.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceThin.java
@@ -4,7 +4,6 @@ import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicFence;
 import net.minecraft.core.block.BlockLogicFenceThin;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
@@ -38,7 +37,7 @@ public class BlockModelGenericFenceThin<T extends BlockLogicFenceThin> extends B
         boolean west = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.WEST);
         boolean east = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.EAST);
 
-        Block<?> blockAbove = worldSource.getBlock(tilePos.up(queryPos));
+        Block<?> blockAbove = worldSource.getBlockType(tilePos.up(queryPos));
         boolean upNorth = blockAbove == this.block && this.block.getLogic().canConnectTo(worldSource, tilePos.up(queryPos), Side.NORTH);
         boolean upSouth = blockAbove == this.block && this.block.getLogic().canConnectTo(worldSource, tilePos.up(queryPos), Side.SOUTH);
         boolean upWest = blockAbove == this.block && this.block.getLogic().canConnectTo(worldSource, tilePos.up(queryPos), Side.WEST);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFurnace.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFurnace.java
index 471d6f532..56031bde0 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFurnace.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFurnace.java
@@ -1,13 +1,18 @@
 package net.minecraft.client.render.block.model.generic;
 
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
+import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogic;
+import net.minecraft.core.block.BlockLogicRotatable;
 import net.minecraft.core.block.entity.TileEntityFurnaceBlast;
 import net.minecraft.core.player.inventory.container.Container;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.useless.dragonfly.models.block.StaticBlockModel;
 
 public class BlockModelGenericFurnace<T extends BlockLogic> extends BlockModelGeneric<T> {
@@ -18,6 +23,32 @@ public class BlockModelGenericFurnace<T extends BlockLogic> extends BlockModelGe
         this.filled = BlockModelDispatcher.loadDataModel(baseKey + "_filled").asModel();
     }
 
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        Direction direction = BlockLogicRotatable.getDirectionFromMeta(worldSource.getBlockData(tilePos));
+        switch (direction) {
+            case UP -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case DOWN -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, -1, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case NORTH -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case WEST -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case EAST -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case SOUTH -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+        }
+        return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+
     @Override
     public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
         if (source.getTileEntity(tilePosc) instanceof Container container) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericGrass.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericGrass.java
new file mode 100644
index 000000000..2426570f9
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericGrass.java
@@ -0,0 +1,27 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.model.BlockModelDispatcher;
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.BlockLogic;
+import net.minecraft.core.block.Blocks;
+import net.minecraft.core.world.WorldSource;
+import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericGrass<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel snowy;
+    public BlockModelGenericGrass(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/grass"));
+        this.snowy = BlockModelDispatcher.loadDataModel("minecraft:block/grass_snowy").asModel();
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        if (source.getBlockType(tilePosc.up(new TilePos())) == Blocks.LAYER_SNOW) {
+            return this.snowy;
+        }
+        return super.getModel(source, tilePosc);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java
index 4d3887740..63b4982dd 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java
@@ -35,7 +35,7 @@ public class BlockModelGenericLeaves<T extends BlockLogic> extends BlockModelGen
         }
         if (direction != null) {
             TilePos shifted = blockPos.add(direction, new TilePos());
-            return worldSource.getBlock(shifted) == this.block || worldSource.isBlockOpaqueCube(shifted);
+            return worldSource.getBlockType(shifted) == this.block || worldSource.isBlockOpaqueCube(shifted);
         }
         return false;
     }
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java
index 38258c7fd..86d6f3407 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java
@@ -27,7 +27,7 @@ public class BlockModelGenericRope<T extends BlockLogic> extends BlockModelGener
 
     @Override
     public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
-        Block<?> below = worldSource.getBlock(tilePos.down(new TilePos()));
+        Block<?> below = worldSource.getBlockType(tilePos.down(new TilePos()));
         boolean hasFloor = below != null && below.canPlaceOnSurface();
         boolean hasBlockNegX = canConnect(worldSource, tilePos, Direction.WEST);
         boolean hasBlockPosX = canConnect(worldSource, tilePos, Direction.EAST);
@@ -74,7 +74,7 @@ public class BlockModelGenericRope<T extends BlockLogic> extends BlockModelGener
 
     private boolean canConnect(@NotNull WorldSource worldSource, @NotNull TilePosc tilePos, @NotNull Direction direction) {
         TilePos shiftedPos = tilePos.add(direction, new TilePos());
-        Block<?> _block = worldSource.getBlock(shiftedPos);
+        Block<?> _block = worldSource.getBlockType(shiftedPos);
         if (direction == Direction.DOWN) { // TODO replace with a proper system for querying what block another block is "attached" to
             if (Block.hasLogicClass(_block, BlockLogicLanternFirefly.class) && (worldSource.getBlockData(shiftedPos) & 0b1) != 0) {
                 return true;
diff --git a/game/client/src/main/java/net/minecraft/client/render/camera/CameraUtil.java b/game/client/src/main/java/net/minecraft/client/render/camera/CameraUtil.java
index 983ff11c6..a22e3fd2d 100644
--- a/game/client/src/main/java/net/minecraft/client/render/camera/CameraUtil.java
+++ b/game/client/src/main/java/net/minecraft/client/render/camera/CameraUtil.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.camera;
 
+import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicFluid;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.util.phys.HitResult;
@@ -11,6 +12,8 @@ import org.jetbrains.annotations.Nullable;
 import org.joml.Vector3d;
 import org.joml.Vector3dc;
 
+import java.util.Objects;
+
 public abstract class CameraUtil {
     public static @Nullable HitResult traceRay(@NotNull ICamera camera, @NotNull World world, double distance, float partialTick) {
         Vector3dc pos = camera.getPosition(partialTick);
@@ -22,8 +25,8 @@ public abstract class CameraUtil {
     public static boolean isUnderLiquid(@NotNull ICamera camera, @NotNull World world, @NotNull Material material, float partialTick) {
         double cameraY = camera.getY(partialTick);
         TilePos tilePos = camera.getTilePos(partialTick);
-        int id = world.getBlockId(tilePos);
-        if (id != 0 && Blocks.blocksList[id].getMaterial() == material) {
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        if (block.getMaterial() == material) {
             float fluidHeight = BlockLogicFluid.getHeight(world.getBlockData(tilePos)) - 0.2F;
             float waterSurface = (float) (tilePos.y + 1) - fluidHeight;
             return cameraY < (double) waterSurface;
diff --git a/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java b/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
index 4bdbe814a..5766e384f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
+++ b/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
@@ -9,6 +9,7 @@ import java.util.List;
 import javax.imageio.ImageIO;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.texturepack.TexturePack;
 import net.minecraft.core.Global;
@@ -18,13 +19,14 @@ import net.minecraft.core.world.World;
 import net.minecraft.core.world.season.Season;
 import net.minecraft.core.world.season.SeasonManagerCycle;
 import net.minecraft.core.world.season.Seasons;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 
 public class Colorizers {
 	private static final Logger LOGGER = LogUtils.getLogger();
 	public static Minecraft mc;
 	
-	private static List<Colorizer> allColorizers = null;
+	private static final @NotNull List<Colorizer> allColorizers = new ObjectArrayList<>();
 
 	public static Colorizer grass;
 	public static Colorizer water;
@@ -48,7 +50,7 @@ public class Colorizers {
 	
 	private static float fadeDuration = 1.0f;
 	
-	public static void init(Minecraft minecraft) {
+	public static void init(@NotNull Minecraft minecraft) {
 		mc = minecraft;
 		
 		registerColorizers();
@@ -56,19 +58,21 @@ public class Colorizers {
 	
 	public static void reload() {
 		List<Season> seasons = Seasons.getAllSeasons();
-		
-		for(int i=0; i < allColorizers.size(); i++) {
-			Colorizer colorizer = allColorizers.get(i);
+		registerColorizers();
+
+		for (Colorizer colorizer : allColorizers) {
 			colorizer.setup(mc, seasons);
 			TexturePack texturePack = colorizer.getTexturePack();
 			if(texturePack != null) {
-                LOGGER.info("Using {} color from asset pack {}", colorizer.name, texturePack.fileName);
+				LOGGER.info("Using {} color from asset pack {}", colorizer.name, texturePack.fileName);
 			}
 		}
+
+		update(true);
 	}
 	
 	public static void registerColorizers() {
-		allColorizers = new ArrayList<>();
+		allColorizers.clear();
 		
 		grass = add(new Colorizer("grass"));
 		water = add(new Colorizer("water"));
@@ -115,10 +119,6 @@ public class Colorizers {
 			return;
 		}
 		
-		if(currentDimension != lastDimension) {
-			reload();
-		}
-		
 		lastDimension = currentDimension;
 		lastSeason = currentSeason;
 		lastSeasonProgress = seasonProgress;
@@ -243,9 +243,8 @@ public class Colorizers {
 	}
 	
 	public static float getSeasonProgress(World world) {
-		if(world.seasonManager instanceof SeasonManagerCycle) {
-			SeasonManagerCycle seasonManager = (SeasonManagerCycle) world.seasonManager;
-			Season currentSeason = seasonManager.getCurrentSeason();
+		if(world.seasonManager instanceof SeasonManagerCycle seasonManager) {
+            Season currentSeason = seasonManager.getCurrentSeason();
 			
 			int dayInSeason = seasonManager.getDayInSeason();
 			int dayLengthTicks = Global.DAY_LENGTH_TICKS;
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java
index b0922931b..c01ecfd26 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java
@@ -8,6 +8,8 @@ import net.minecraft.client.render.renderer.State;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.util.collection.NamespaceID;
+import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 import org.joml.Math;
 import org.joml.primitives.AABBdc;
@@ -36,7 +38,7 @@ public abstract class EntityRenderer<T extends Entity> {
     protected EntityRendererDispatcher renderDispatcher = null;
     protected Class<? extends T> appliedClass = null;
 
-    private float shadowSize;
+    private final float shadowSize;
     protected float shadowOpacity;
 
     public EntityRenderer(final float shadowSize) {
@@ -80,12 +82,19 @@ public abstract class EntityRenderer<T extends Entity> {
         } else {
             model = EntityGeometryMojangData.Cache.getFallbackModel();
         }
-        this.modelMap.put(localId, model);
+        var last = this.modelMap.put(localId, model);
+        if (last != null && last != model) {
+            last.delete();
+        }
         return model;
     }
 
     public final @NotNull EntityRenderer<T> setModel(@NotNull final String localId, @NotNull final String modelId, final double inflation) {
-        this.modelMap.put(localId, EntityGeometryMojangData.Cache.getModel(modelId, inflation));
+        var model = EntityGeometryMojangData.Cache.getModel(modelId, inflation);
+        var last = this.modelMap.put(localId, model);
+        if (last != null && last != model) {
+            last.delete();
+        }
         return this;
     }
 
@@ -138,7 +147,8 @@ public abstract class EntityRenderer<T extends Entity> {
         GLRenderer.globalSetLightEnabled(true);
     }
 
-    private void renderShadow(final @NotNull TessellatorGeneral tessellator, @NotNull final T entity, final double posX, final double posY, final double posZ,
+    private void renderShadow(final @NotNull TessellatorGeneral tessellator, @NotNull final T entity,
+                              final double posX, final double posY, final double posZ,
                               final float opacity, final float partialTick) {
         GLRenderer.enableState(State.BLEND);
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
@@ -163,12 +173,16 @@ public abstract class EntityRenderer<T extends Entity> {
         final double dzLerp = posZ - lerpZ;
         tessellator.startDrawingQuads();
 
-        for (int blockX = minX; blockX <= maxX; blockX++) {
-            for (int blockY = minY; blockY <= maxY; blockY++) {
-                for (int blockZ = minZ; blockZ <= maxZ; blockZ++) {
-                    final int blockId = world.getBlockId(blockX, blockY - 1, blockZ);
-                    if (blockId > 0 && world.getBlockLightValue(blockX, blockY, blockZ) > 3) {
-                        renderShadowOnBlock(tessellator, entity, Blocks.blocksList[blockId], posX, posY + (double) entity.getShadowHeightOffs(), posZ, blockX, blockY, blockZ, opacity, shadowSize, dxLerp, dyLerp + (double) entity.getShadowHeightOffs(), dzLerp);
+        TilePos q = new TilePos();
+        TilePos blockPos = new TilePos();
+        for (blockPos.x = minX; blockPos.x <= maxX; blockPos.x++) {
+            for (blockPos.y = minY; blockPos.y <= maxY; blockPos.y++) {
+                for (blockPos.z = minZ; blockPos.z <= maxZ; blockPos.z++) {
+                    final @NotNull Block<?> block = world.getBlockType(blockPos.down(q));
+                    if (world.getBlockLightValue(blockPos) > 3) {
+                        renderShadowOnBlock(tessellator, entity, block,
+                            posX, posY + (double) entity.getShadowHeightOffs(), posZ,
+                            blockPos, opacity, shadowSize, dxLerp, dyLerp + (double) entity.getShadowHeightOffs(), dzLerp);
                     }
                 }
 
@@ -181,15 +195,16 @@ public abstract class EntityRenderer<T extends Entity> {
         GLRenderer.setDepthMask(true);
     }
 
-    private void renderShadowOnBlock(final @NotNull TessellatorGeneral tessellator, final @NotNull T entity, final @NotNull Block<?> block, final double d, final double d1, final double d2,
-                                     final int x, final int y, final int z, final float opacity, final float size, final double xo,
+    private void renderShadowOnBlock(final @NotNull TessellatorGeneral tessellator, final @NotNull T entity, final @NotNull Block<?> block,
+                                     final double x, final double y, final double z,
+                                     final @NotNull TilePosc tilePos, final float opacity, final float size, final double xo,
                                      final double yo, final double zo) {
         if (!block.isCubeShaped()) {
             return;
         }
-        double brightness = entity.world.getLightBrightness(x, y, z);
+        double brightness = entity.world.getLightBrightness(tilePos);
         if (Global.accessor.isFullbrightEnabled()) brightness = 1.0f;
-        double alpha = ((double) opacity - (d1 - ((double) (y + 1) + yo)) / 2D) * 0.5D * brightness;
+        double alpha = ((double) opacity - (y - ((double) (tilePos.y() + 1) + yo)) / 2D) * 0.5D * brightness;
         if (alpha < 0.0D) {
             return;
         }
@@ -197,7 +212,7 @@ public abstract class EntityRenderer<T extends Entity> {
             alpha = 1.0D;
         }
         tessellator.setColor4f(1.0F, 1.0F, 1.0F, (float) alpha);
-        final AABBdc aabb = block.getCollisionBoundingBoxFromPool(entity.world, x, y, z);
+        final AABBdc aabb = block.getCollisionAABB(entity.world, tilePos);
         if (aabb == null) {
             return;
         }
@@ -206,10 +221,10 @@ public abstract class EntityRenderer<T extends Entity> {
         final double yMin = aabb.maxY() + yo + 0.015625D - 1;
         final double zMin = aabb.minZ() + zo;
         final double zMax = aabb.maxZ() + zo;
-        final float f2 = (float) ((d - xMin) / 2D / (double) size + 0.5D);
-        final float f3 = (float) ((d - xMax) / 2D / (double) size + 0.5D);
-        final float f4 = (float) ((d2 - zMin) / 2D / (double) size + 0.5D);
-        final float f5 = (float) ((d2 - zMax) / 2D / (double) size + 0.5D);
+        final float f2 = (float) ((x - xMin) / 2D / (double) size + 0.5D);
+        final float f3 = (float) ((x - xMax) / 2D / (double) size + 0.5D);
+        final float f4 = (float) ((z - zMin) / 2D / (double) size + 0.5D);
+        final float f5 = (float) ((z - zMax) / 2D / (double) size + 0.5D);
         tessellator.addVertexWithUV(xMin, yMin, zMin, f2, f4);
         tessellator.addVertexWithUV(xMin, yMin, zMax, f2, f5);
         tessellator.addVertexWithUV(xMax, yMin, zMax, f3, f5);
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
index 448fec596..e79f8b6cc 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
@@ -59,10 +59,12 @@ public abstract class MobRenderer<T extends Mob> extends EntityRenderer<T> {
         }
         renderAdditional(tessellator, entity, partialTick);
 
-        final int argb = getOverlayColor(entity, 1f, partialTick);
+        final int argb = getOverlayColor(entity, partialTick);
         final boolean hasOverlayAlpha = Color.alphaFromInt(argb) > 0;
         if (hasOverlayAlpha || entity.hurtTime > 0 || entity.deathTime > 0) {
+            this.renderDispatcher.textureManager.loadTexture("/assets/minecraft/textures/misc/white.png").bind();
             GLRenderer.pushFrame();
+            GLRenderer.setLightmapCoord2i(15, 15);
             GLRenderer.setShader(Shaders.COLOR_WORLD);
             GLRenderer.enableState(State.BLEND);
             GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
@@ -78,14 +80,10 @@ public abstract class MobRenderer<T extends Mob> extends EntityRenderer<T> {
 
             }
             if (hasOverlayAlpha) {
-                final float r = Color.redFromInt(argb) / 255f;
-                final float g = Color.greenFromInt(argb) / 255f;
-                final float b = Color.blueFromInt(argb) / 255f;
-                final float a = Color.alphaFromInt(argb) / 255f;
-                for (int layer = 0; layer < maxRenderLayer; layer++) {
+                for (int layer = 0; layer <= maxRenderLayer; layer++) {
                     final StaticEntityModel model = this.setupModels.get(layer);
                     if (model != null) {
-                        GLRenderer.setColor4f(r, g, b, a);
+                        GLRenderer.setColor1i(argb);
                         model.render();
                     }
                 }
@@ -170,7 +168,7 @@ public abstract class MobRenderer<T extends Mob> extends EntityRenderer<T> {
     }
 
     protected void renderLivingLabel(final @NotNull TessellatorGeneral t, final @NotNull T entity, final @NotNull CharSequence text, final double x, final double y, final double z, final int maxDistance, final boolean depthTest) {
-        final float cameraDistance = (float) this.renderDispatcher.camera.distanceTo(entity);
+        final float cameraDistance = (float) Minecraft.getMinecraft().activeCamera.distanceTo(entity);
         if (cameraDistance > maxDistance) {
             return;
         }
@@ -209,7 +207,7 @@ public abstract class MobRenderer<T extends Mob> extends EntityRenderer<T> {
         GLRenderer.popFrame();
     }
 
-    protected int getOverlayColor(final @NotNull T entity, final float brightness, final float partialTick) {
+    protected int getOverlayColor(final @NotNull T entity, final float partialTick) {
         return 0;
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererCreeper.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererCreeper.java
index ed5a936cf..d13a5aa59 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererCreeper.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererCreeper.java
@@ -18,7 +18,7 @@ public class MobRendererCreeper extends MobRenderer<MobCreeper> {
     }
 
     @Override
-    protected int getOverlayColor(final @NotNull MobCreeper creeper, final float brightness, final float partialTick) {
+    protected int getOverlayColor(final @NotNull MobCreeper creeper, final float partialTick) {
         final float step = creeper.getSwelling(partialTick);
         if ((int) (step * 10.0f) % 2 == 0) {
             return 0;
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java
index 96912b50d..4848aefe5 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java
@@ -109,17 +109,18 @@ public class MobRendererPlayer extends MobRendererBipedArmored<Player> {
 
     @Override
     protected void renderSpecials(final @NotNull TessellatorGeneral t, final @NotNull Player entity, final double x, final double y, final double z) {
-        if (Minecraft.getMinecraft().thePlayer.getGamemode() != Gamemodes.SPECTATOR && entity.getGamemode() == Gamemodes.SPECTATOR) {
+        Minecraft mc = Minecraft.getMinecraft();
+        if (mc.thePlayer.getGamemode() != Gamemodes.SPECTATOR && entity.getGamemode() == Gamemodes.SPECTATOR) {
             return;
         }
-        if (Minecraft.getMinecraft().gameSettings.immersiveMode.drawNames() && this.renderDispatcher.camera != null) // Render name
+        if (mc.gameSettings.immersiveMode.drawNames() && mc.activeCamera != null) // Render name
         {
-            if (this.renderDispatcher.camera instanceof EntityCamera && ((EntityCamera) this.renderDispatcher.camera).mob == entity) {
+            if (mc.activeCamera instanceof EntityCamera entityCamera && entityCamera.mob == entity) {
                 return;
             }
             final float f = 1.6F;
             final float f1 = 0.01666667F * f;
-            final float f2 = (float) this.renderDispatcher.camera.distanceTo(entity); //getting lost on renderManager.livingPlayer
+            final float f2 = (float) mc.activeCamera.distanceTo(entity); //getting lost on renderManager.livingPlayer
             final float f3 = entity.isSneaking() ? 32F : 64F;
             if (f2 < f3) {
                 final String s = entity.getDisplayName();
diff --git a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModel.java b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModel.java
index f0f09125d..7f99fffff 100644
--- a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModel.java
+++ b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModel.java
@@ -8,6 +8,7 @@ import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.FrontFace;
 import net.minecraft.client.render.renderer.GLRenderer;
+import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
@@ -32,6 +33,7 @@ public abstract class ItemModel {
 
     public void renderGui(@NotNull TessellatorGeneral tessellator, @Nullable Entity holder, @NotNull ItemStack itemStack, int x, int y, int lightmapCoord, float partialTick) {
         GLRenderer.pushFrame();
+        GLRenderer.setShader(Shaders.TERRAIN);
         GLRenderer.globalSetLightEnabled(false);
         GLRenderer.enableState(State.BLEND);
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
@@ -56,6 +58,7 @@ public abstract class ItemModel {
 
     public void renderFirstPerson(@NotNull TessellatorGeneral tessellator, @NotNull ItemRenderer itemRenderer, @NotNull Player player, @NotNull ItemStack itemStack, int lightmapCoord, float partialTick) {
         GLRenderer.pushFrame();
+        GLRenderer.setShader(Shaders.TERRAIN);
         GLRenderer.enableState(State.BLEND);
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
         GLRenderer.enableState(State.CULL_FACE);
diff --git a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java
index 98ee01810..92297b7da 100644
--- a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java
+++ b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelBlock.java
@@ -18,6 +18,7 @@ import net.minecraft.core.item.block.ItemBlock;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.joml.Math;
+import org.lwjgl.opengl.GL41;
 import org.useless.dragonfly.DisplayPos;
 
 public class ItemModelBlock extends ItemModelStandard {
@@ -48,6 +49,7 @@ public class ItemModelBlock extends ItemModelStandard {
             return;
         }
         random.setSeed(187L);
+        GLRenderer.setShader(Shaders.TERRAIN);
         DisplayPos displayPos = getDisplayPos(displayPosId);
         GLRenderer.modelM4f().translate(displayPos.tx, displayPos.ty, displayPos.tz);
         GLRenderer.modelM4f().rotateX(Math.toRadians(displayPos.rx));
@@ -86,7 +88,7 @@ public class ItemModelBlock extends ItemModelStandard {
             return;
         }
         GLRenderer.pushFrame();
-        GLRenderer.setShader(Shaders.WORLD);
+        GLRenderer.setShader(Shaders.TERRAIN);
         GLRenderer.enableState(State.BLEND);
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
         GLRenderer.enableState(State.CULL_FACE);
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java b/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java
index b7e7fb6a4..9a03a9a07 100644
--- a/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java
@@ -218,7 +218,7 @@ public class Particle {
 
         Direction direction = Direction.NONE;
         while (dx * dx + dy * dy + dz * dz < length * length + 4) {
-            Block<?> block = this.world.getBlock(tilePos);
+            Block<?> block = this.world.getBlockType(tilePos);
             if (block != null && collidesWithBlock(block, this.world.getBlockData(tilePos))) {
                 this.aabbs.clear();
                 block.getCollisionAABBs(this.world, tilePos, this.refAABB.setMin(tilePos.x, tilePos.y, tilePos.z).setMax(tilePos.x + 1, tilePos.y + 1, tilePos.z + 1), this.aabbs);
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java
index 5f8b6b132..0a8577142 100644
--- a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java
@@ -1,12 +1,10 @@
 package net.minecraft.client.render.particle;
 
-import net.minecraft.client.render.ParticleEngine;
 import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.tessellator.TessellatorParticle;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicLeavesBase;
-import net.minecraft.core.block.Blocks;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
@@ -30,7 +28,7 @@ public class ParticleLeaf extends Particle {
     }
 
     public ParticleLeaf init(@NotNull TilePos tilePos) {
-        Block<?> block = Blocks.blocksList[this.world.getBlockId(tilePos)];
+        Block<?> block = this.world.getBlockType(tilePos);
         if (!Block.hasLogicClass(block, BlockLogicLeavesBase.class)) this.remove();
         int col = BlockColorDispatcher.getInstance().getDispatch(block).getWorldColor(this.world, tilePos.x, tilePos.y, tilePos.z, 0);
         this.rCol *= (float) (col >> 16 & 0xff) / 255F;
diff --git a/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java b/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java
index 5b0a84583..f60caeff7 100644
--- a/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java
@@ -116,6 +116,9 @@ public class GLRenderer {
     private float currentLightmapBlock = 15.5f/16f;
     private float currentLightmapSky = 15.5f/16f;
 
+    private final float[] alphaTestStack = new float[RENDER_FRAMES_STACK_SIZE];
+    private float currentAlphaTest = 0.1f;
+
     private int stackIndex = 0;
 
 
@@ -136,7 +139,7 @@ public class GLRenderer {
         shader.bind();
         if (instance.viewProjMatDirty) {
             GL41.glBindBuffer(GL41.GL_UNIFORM_BUFFER, UniformBlockManager.BLOCK_MATRICES.ubo);
-            UniformBlockManager.BLOCK_MATRICES.adapter.bufferData(projectionM4f(), N * 4 * 4 * 0, UniformBlockManager.BLOCK_MATRICES.buffer.clear());
+            UniformBlockManager.BLOCK_MATRICES.adapter.bufferData(projectionM4f(), N * 4 * 4 * 0, UniformBlockManager.BLOCK_MATRICES.buffer);
             UniformBlockManager.BLOCK_MATRICES.adapter.bufferData(projectionM4f().invert(matBuf), N * 4 * 4 * 1, UniformBlockManager.BLOCK_MATRICES.buffer);
             UniformBlockManager.BLOCK_MATRICES.adapter.bufferData(viewM4f(), N * 4 * 4 * 2, UniformBlockManager.BLOCK_MATRICES.buffer);
             UniformBlockManager.BLOCK_MATRICES.adapter.bufferData(viewM4f().invert(matBuf), N * 4 * 4 * 3, UniformBlockManager.BLOCK_MATRICES.buffer);
@@ -147,8 +150,10 @@ public class GLRenderer {
         shader.uniformMat4f("model", modelM4f());
         shader.uniformMat4f("texture", textureM4f());
 
+        shader.uniformFloat("uAlphaTest", instance.currentAlphaTest);
         shader.uniformVec4f("uColor", Color.redFromInt(instance.currentColor)/255f, Color.greenFromInt(instance.currentColor)/255f, Color.blueFromInt(instance.currentColor)/255f, Color.alphaFromInt(instance.currentColor)/255f);
         shader.uniformFloat("uCurrentTick", instance.mc.ticksRan + instance.mc.timer.partialTicks);
+        shader.uniformFloat("uPartialTick", instance.mc.timer.partialTicks);
         shader.uniformFloat("uLineWidth", instance.currentLineWidth);
 
         double renderScale = (float) instance.mc.gameSettings.renderScale.value.scale;
@@ -339,6 +344,14 @@ public class GLRenderer {
         return instance.currentLightmapSky;
     }
 
+    public static void setAlphaTest(float alphaTest) {
+        instance.currentAlphaTest = alphaTest;
+    }
+
+    public static float getAlphaTest() {
+        return instance.currentAlphaTest;
+    }
+
     public static void setColor1i(int argb) {
         instance.currentColor = argb;
     }
@@ -411,6 +424,7 @@ public class GLRenderer {
         instance.polygonUnitsStack[instance.stackIndex] = instance.currentPolygonUnits;
         instance.lightmapBlockStack[instance.stackIndex] = instance.currentLightmapBlock;
         instance.lightmapSkyStack[instance.stackIndex] = instance.currentLightmapSky;
+        instance.alphaTestStack[instance.stackIndex] = instance.currentAlphaTest;
 
         if (DEBUG) {
             StackTraceElement[] eles = Thread.currentThread().getStackTrace();
@@ -431,6 +445,7 @@ public class GLRenderer {
 
         instance.projectionMatrixStack.pushMatrix();
         instance.viewMatrixStack.pushMatrix();
+        instance.viewProjMatDirty = true;
         instance.modelMatrixStack.pushMatrix();
         instance.textureMatrixStack.pushMatrix();
     }
@@ -510,9 +525,11 @@ public class GLRenderer {
 
         instance.currentLightmapBlock = instance.lightmapBlockStack[instance.stackIndex];
         instance.currentLightmapSky = instance.lightmapSkyStack[instance.stackIndex];
+        instance.currentAlphaTest = instance.alphaTestStack[instance.stackIndex];
     }
 
     protected static void reset() {
         instance.stackIndex = 1;
+        setShader(Shaders.INTERFACE);
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java b/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java
index e8aaee8eb..248d155e0 100644
--- a/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java
+++ b/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java
@@ -23,6 +23,8 @@ public final class Shaders {
     public static final @NotNull ShaderProvider PROVIDER_INTERNAL = new ShaderProviderInternal("/shaders/");
 
     public static final @NotNull Shader WORLD = register("world", new Shader());
+    public static final @NotNull Shader AURORA = register("aurora", new Shader());
+    public static final @NotNull Shader ENTITY = register("entity", new Shader());
     public static final @NotNull Shader TERRAIN = register("terrain", new Shader());
     public static final @NotNull Shader INTERFACE = register("interface", new Shader());
     public static final @NotNull Shader COLOR = register("color", new Shader());
diff --git a/game/client/src/main/java/net/minecraft/client/render/terrain/ChunkRendererMultiDraw.java b/game/client/src/main/java/net/minecraft/client/render/terrain/ChunkRendererMultiDraw.java
index 1af75351e..632d6311f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/terrain/ChunkRendererMultiDraw.java
+++ b/game/client/src/main/java/net/minecraft/client/render/terrain/ChunkRendererMultiDraw.java
@@ -10,7 +10,7 @@ import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.culling.CameraFrustum;
 import net.minecraft.client.render.terrain.VertexBuffer.Entry;
 import net.minecraft.client.render.tessellator.TessellatorTerrainImpl;
-import net.minecraft.core.block.Blocks;
+import net.minecraft.core.block.Block;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
@@ -67,25 +67,21 @@ public class ChunkRendererMultiDraw extends ChunkRenderer {
             for (pos.y = minY; pos.y < maxY; pos.y++) {
                 for (pos.z = minZ; pos.z < maxZ; pos.z++) {
                     for (pos.x = minX; pos.x < maxX; pos.x++) {
-                        final int blockId = chunkCache.getBlockId(pos);
-                        if (blockId <= 0) {
-                            continue;
-                        }
+                        final @NotNull Block<?> block = chunkCache.getBlockType(pos);
                         if (!hasStartedDrawing) {
                             hasStartedDrawing = true;
                             tessellator.startDrawingQuads();
-//							tessellator.setTranslation(-this.posX, -this.posY, -this.posZ);
 
                             RenderRegion region = this.terrainRenderer.getRenderRegionAtBlockPos(this.posX, this.posZ);
                             tessellator.setTranslation(-(region.posX << this.terrainRenderer.REGION_SIZE), 0.0, -(region.posZ << this.terrainRenderer.REGION_SIZE));
                         }
-                        if (renderPass == 0 && Blocks.isEntityTile[blockId]) {
+                        if (renderPass == 0 && block.isEntityTile()) {
                             final TileEntity tileentity = chunkCache.getTileEntity(pos);
                             if (tileentity != null && TileEntityRenderDispatcher.instance.hasRenderer(tileentity)) {
                                 this.renderableBlockEntities.add(tileentity);
                             }
                         }
-                        final BlockModel<?> model = BlockModelDispatcher.getInstance().getDispatch(Blocks.blocksList[blockId]);
+                        final BlockModel<?> model = BlockModelDispatcher.getInstance().getDispatch(block);
                         final int blockRenderPass = model.renderLayer();
 
                         if (blockRenderPass != renderPass) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/tessellator/Tessellator.java b/game/client/src/main/java/net/minecraft/client/render/tessellator/Tessellator.java
index fb1d12f89..9710f6ee6 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tessellator/Tessellator.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tessellator/Tessellator.java
@@ -2,19 +2,39 @@ package net.minecraft.client.render.tessellator;
 
 import net.minecraft.client.render.renderer.DrawMode;
 import org.jetbrains.annotations.NotNull;
+import org.joml.Vector3dc;
+import org.joml.Vector3fc;
 
 public interface Tessellator {
     boolean QUAD_EMULATION = /*Minecraft.getOs() == EnumOS.macos || */true; // I hate you so fucking much apple
     void startDrawing(@NotNull DrawMode drawMode);
-    @Deprecated
     default void startDrawingQuads() {
         startDrawing(DrawMode.QUADS);
     }
 
     void addVertex(double x, double y, double z);
+    default void addVertex(@NotNull Vector3dc pos) {
+        addVertex(pos.x(), pos.y(), pos.z());
+    }
+    default void addVertex(@NotNull Vector3fc pos) {
+        addVertex(pos.x(), pos.y(), pos.z());
+    }
 
     void setTranslation(double x, double y, double z);
+    default void setTranslation(@NotNull Vector3dc pos) {
+        setTranslation(pos.x(), pos.y(), pos.z());
+    }
+    default void setTranslation(@NotNull Vector3fc pos) {
+        setTranslation(pos.x(), pos.y(), pos.z());
+    }
+
     void offsetTranslation(double x, double y, double z);
+    default void offsetTranslation(@NotNull Vector3dc pos) {
+        offsetTranslation(pos.x(), pos.y(), pos.z());
+    }
+    default void offsetTranslation(@NotNull Vector3fc pos) {
+        offsetTranslation(pos.x(), pos.y(), pos.z());
+    }
 
     default void drawRectangle(int x, int y, int width, int height) {
         this.addVertex(x, y, 0.0D);
diff --git a/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorAurora.java b/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorAurora.java
new file mode 100644
index 000000000..321b3d0c8
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorAurora.java
@@ -0,0 +1,139 @@
+package net.minecraft.client.render.tessellator;
+
+import com.mojang.logging.LogUtils;
+import net.minecraft.client.render.renderer.DrawMode;
+import org.jetbrains.annotations.NotNull;
+import org.lwjgl.BufferUtils;
+import org.lwjgl.opengl.GL41;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+
+public class TessellatorAurora {
+    private static final Logger LOGGER = LogUtils.getLogger();
+    private static final int VERT_SIZE = 8 * Float.BYTES + 8;
+
+    private boolean quadEmulation = false;
+
+    public final @NotNull String name;
+    public @NotNull ByteBuffer data;
+
+    protected double offsetX;
+    protected double offsetY;
+    protected double offsetZ;
+
+    public @NotNull DrawMode drawMode = DrawMode.TRIANGLES;
+    public boolean drawing;
+    public int vertexCount;
+    private int quadVertCount = 0;
+
+    public TessellatorAurora(@NotNull String name, int initialCapacity) {
+        this.name = name;
+        this.data = BufferUtils.createByteBuffer(initialCapacity);
+    }
+
+    public void startDrawing(@NotNull DrawMode drawMode) {
+        if (this.drawing) {
+            this.drawing = false;
+            throw new IllegalStateException(this.name + "Already drawing!");
+        }
+
+        if (drawMode == DrawMode.QUADS && Tessellator.QUAD_EMULATION) {
+            this.drawMode = DrawMode.TRIANGLES;
+            this.quadEmulation = true;
+        } else {
+            this.drawMode = drawMode;
+        }
+        this.drawing = true;
+        this.vertexCount = 0;
+        this.quadVertCount = 0;
+
+        this.data.clear();
+    }
+
+    public void setTranslation(double x, double y, double z) {
+        this.offsetX = x;
+        this.offsetY = y;
+        this.offsetZ = z;
+    }
+
+    public void offsetTranslation(double x, double y, double z) {
+        this.offsetX += x;
+        this.offsetY += y;
+        this.offsetZ += z;
+    }
+
+    public void checkIsDrawing() {
+        if (!this.drawing) {
+            throw new IllegalStateException(this.name + " not drawing!");
+        }
+    }
+
+    public void checkCanFit(int size) {
+        if (this.data.capacity() < this.data.position() + size) {
+            int newSize = this.data.capacity() * 2;
+
+            LOGGER.info("Expanding {} Buffer ({} -> {})", this.name, this.data.capacity(), newSize);
+
+            ByteBuffer newBuffer = BufferUtils.createByteBuffer(newSize);
+            this.data.flip();
+            newBuffer.put(this.data);
+            this.data = newBuffer;
+        }
+    }
+
+    public void addVertex(double x, double y, double z, double xo, double yo, double zo, float r, float g, float b, float a, float ro, float go, float bo, float ao, float u, float v) {
+        checkIsDrawing();
+        checkCanFit(128);
+
+        this.data.putFloat((float) (x + this.offsetX)).putFloat((float) (y + this.offsetY)).putFloat((float) (z + this.offsetZ));
+        this.data.putFloat((float) (xo + this.offsetX)).putFloat((float) (yo + this.offsetY)).putFloat((float) (zo + this.offsetZ));
+
+        this.data.putInt(((int) (a * 255) & 0xFF) << 24 | ((int) (b * 255) & 0xFF) << 16 | ((int) (g * 255) & 0xFF) << 8 | (int) (r * 255) & 0xFF);
+        this.data.putInt(((int) (ao * 255) & 0xFF) << 24 | ((int) (bo * 255) & 0xFF) << 16 | ((int) (go * 255) & 0xFF) << 8 | (int) (ro * 255) & 0xFF);
+
+        this.data.putFloat(u).putFloat(v);
+
+        this.vertexCount++;
+
+        if (this.quadEmulation && this.quadVertCount % 4 == 2) {
+            int vertSize = VERT_SIZE;
+
+            checkCanFit(256);
+            this.data.put(this.data.position(), this.data, this.data.position() - vertSize * 3, vertSize);
+            this.data.put(this.data.position() + vertSize, this.data, this.data.position() - vertSize, vertSize);
+            this.data.position(this.data.position() + vertSize * 2);
+            this.vertexCount += 2;
+        }
+
+        this.quadVertCount++;
+    }
+
+    public @NotNull RenderBuffer record(int vao, int vbo) {
+        checkIsDrawing();
+        this.drawing = false;
+
+        enable(vao, vbo);
+        GL41.glBufferData(GL41.GL_ARRAY_BUFFER, this.data.flip(), GL41.GL_STATIC_DRAW);
+        GL41.glBindVertexArray(0);
+        return new RenderBuffer(vao, vbo, 0, this.vertexCount, this.drawMode);
+    }
+
+    public void enable(int vao, int vbo) {
+        GL41.glBindVertexArray(vao);
+        GL41.glBindBuffer(GL41.GL_ARRAY_BUFFER, vbo);
+
+        int offset = 0;
+        GL41.glVertexAttribPointer(0, 3, GL41.GL_FLOAT, false, VERT_SIZE, offset); offset += Float.BYTES * 3; // Pos
+        GL41.glVertexAttribPointer(1, 3, GL41.GL_FLOAT, false, VERT_SIZE, offset); offset += Float.BYTES * 3; // PosO
+        GL41.glVertexAttribPointer(2, 4, GL41.GL_UNSIGNED_BYTE, true, VERT_SIZE, offset); offset += 4; // Color
+        GL41.glVertexAttribPointer(3, 4, GL41.GL_UNSIGNED_BYTE, true, VERT_SIZE, offset); offset += 4; // ColorO
+        GL41.glVertexAttribPointer(4, 2, GL41.GL_FLOAT, false, VERT_SIZE, offset); offset += 2; // UV
+
+        GL41.glEnableVertexAttribArray(0);
+        GL41.glEnableVertexAttribArray(1);
+        GL41.glEnableVertexAttribArray(2);
+        GL41.glEnableVertexAttribArray(3);
+        GL41.glEnableVertexAttribArray(4);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTextured.java b/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTextured.java
index 90a2348c4..e8694c184 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTextured.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTextured.java
@@ -1,5 +1,9 @@
 package net.minecraft.client.render.tessellator;
 
+import org.jetbrains.annotations.NotNull;
+import org.joml.Vector3dc;
+import org.joml.Vector3fc;
+
 public interface TessellatorTextured extends Tessellator {
     void setTextureUV(double u, double v);
 
@@ -7,6 +11,12 @@ public interface TessellatorTextured extends Tessellator {
         setTextureUV(u, v);
         addVertex(x, y, z);
     }
+    default void addVertexWithUV(@NotNull Vector3dc pos, double u, double v) {
+        addVertexWithUV(pos.x(), pos.y(), pos.z(), u, v);
+    }
+    default void addVertexWithUV(@NotNull Vector3fc pos, double u, double v) {
+        addVertexWithUV(pos.x(), pos.y(), pos.z(), u, v);
+    }
 
     default void drawRectangleWithUV(int x, int y, int width, int height, double u, double v, double uvWidth, double uvHeight) {
         this.addVertexWithUV(x, y, 0.0D, u, v);
diff --git a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
index 1e1312569..5e70813f2 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
@@ -6,6 +6,7 @@ import net.minecraft.client.gui.TooltipElement;
 import net.minecraft.client.gui.keyboard.KeyboardLayout;
 import net.minecraft.client.render.EntityRendererDispatcher;
 import net.minecraft.client.render.TileEntityRenderDispatcher;
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
 import net.minecraft.client.sound.SoundRepository;
@@ -105,6 +106,7 @@ public class TexturePackList
 		}
 		mc.textureManager.updateDynamicTextures(false);
 		SoundRepository.reload();
+		BlockColorDispatcher.getInstance().reload();
 		BlockModelDispatcher.getInstance().reload();
 		ItemModelDispatcher.getInstance().reload();
 		EntityGeometryMojangData.Cache.reload(this);
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java
index a897e1903..f1469c18b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMovingPiston.java
@@ -33,8 +33,8 @@ public class TileEntityRendererMovingPiston extends TileEntityRenderer<TileEntit
     @Override
     public void doRender(TessellatorGeneral tessellator, TileEntityMovingPistonBlock tileEntity, double x, double y, double z,
                          float partialTick) {
-        Block<?> block = Blocks.getBlock(tileEntity.getMovedId());
-        if (block != null && tileEntity.getProgress(partialTick) < 1.0F) {
+        Block<?> block = tileEntity.getMovedBlock();
+        if (tileEntity.getProgress(partialTick) < 1.0F) {
             if (this.container == null || this.container.world != tileEntity.worldObj) {
                 this.container = new BlocksContainer(tileEntity.worldObj);
             }
diff --git a/game/client/src/main/java/net/minecraft/client/render/uniform/UniformBlockManager.java b/game/client/src/main/java/net/minecraft/client/render/uniform/UniformBlockManager.java
index 8a691c93e..72eb0f5e3 100644
--- a/game/client/src/main/java/net/minecraft/client/render/uniform/UniformBlockManager.java
+++ b/game/client/src/main/java/net/minecraft/client/render/uniform/UniformBlockManager.java
@@ -6,6 +6,8 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 import net.minecraft.client.render.FogManager;
 import org.jetbrains.annotations.NotNull;
 import org.joml.Matrix4f;
+import org.useless.dragonfly.models.entity.StaticEntityModel;
+import org.useless.dragonfly.models.entity.mojang.StaticEntityModelMojang;
 
 import java.nio.ByteBuffer;
 import java.util.Map;
@@ -28,6 +30,7 @@ public class UniformBlockManager {
             return dest;
         }
     });
+    public static final @NotNull UniformBlock<Matrix4f> BLOCK_ENTITY_BONES = register("Bones", 3, N * 4 * StaticEntityModelMojang.MAX_BONES, Matrix4f::get);
 
     public static <T> UniformBlock<T> register(@NotNull String name, int index, int size, @NotNull BufferAdapter<T> adapter) {
         UniformBlock<T> block = new UniformBlock<>(name, index, size, adapter);
diff --git a/game/client/src/main/java/net/minecraft/client/render/worldtype/WorldTypeFXNether.java b/game/client/src/main/java/net/minecraft/client/render/worldtype/WorldTypeFXNether.java
index f96c1404e..33d113393 100644
--- a/game/client/src/main/java/net/minecraft/client/render/worldtype/WorldTypeFXNether.java
+++ b/game/client/src/main/java/net/minecraft/client/render/worldtype/WorldTypeFXNether.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.worldtype;
 
 import net.minecraft.client.render.colorizer.Colorizers;
+import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
@@ -62,7 +63,7 @@ public class WorldTypeFXNether extends WorldTypeFX {
                 double ry = (player.y - radius) + (world.rand.nextDouble() * radius * 2);
                 double rz = (player.z - radius) + (world.rand.nextDouble() * radius * 2);
 
-                if (world.getBlockId(new TilePos(rx, ry, rz)) == 0) {
+                if (world.getBlockType(new TilePos(rx, ry, rz)) == Blocks.AIR) {
                     world.spawnParticle("ashmote", rx, ry, rz, 0, 0, 0, 0);
                 }
             }
diff --git a/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java b/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
index 357f31b68..a8ec4bc9d 100644
--- a/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
+++ b/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
@@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.client.net.handler.PacketHandlerClient;
 import net.minecraft.client.world.chunk.provider.ChunkProviderClient;
+import net.minecraft.core.block.Block;
 import net.minecraft.core.data.gamerule.GameRules;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.Entity;
@@ -96,7 +97,7 @@ public class WorldClientMP extends WorldClient {
     }
 
     @Override
-    public void scheduleBlockUpdate(final @NotNull TilePosc tilePos, final int id, final long delay) {
+    public void scheduleBlockUpdate(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final long delay) {
         // Do nothing
     }
 
@@ -175,10 +176,10 @@ public class WorldClientMP extends WorldClient {
 
     @Override
     public boolean setBlockData(final @NotNull TilePosc tilePos, final int data) {
-        final int id = this.getBlockId(tilePos);
+        final @NotNull Block<?> block = this.getBlockType(tilePos);
         final int currentData = this.getBlockData(tilePos);
         if (super.setBlockData(tilePos, data)) {
-            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), id, currentData));
+            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), block.id(), currentData));
             return true;
         } else {
             return false;
@@ -186,11 +187,11 @@ public class WorldClientMP extends WorldClient {
     }
 
     @Override
-    public boolean setBlockIdData(final @NotNull TilePosc tilePos, final int id, final int data) {
-        final int currentId = this.getBlockId(tilePos);
+    public boolean setBlockTypeData(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final int data) {
+        final @NotNull Block<?> currentBlock = this.getBlockType(tilePos);
         final int currentData = this.getBlockData(tilePos);
-        if (super.setBlockIdData(tilePos, id, data)) {
-            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), currentId, currentData));
+        if (super.setBlockTypeData(tilePos, block, data)) {
+            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), currentBlock.id(), currentData));
             return true;
         } else {
             return false;
@@ -198,11 +199,11 @@ public class WorldClientMP extends WorldClient {
     }
 
     @Override
-    public boolean setBlockId(final @NotNull TilePosc tilePos, final int id) {
-        final int currentId = this.getBlockId(tilePos);
-        final int data = this.getBlockData(tilePos);
-        if (super.setBlockId(tilePos, id)) {
-            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), currentId, data));
+    public boolean setBlockType(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        final @NotNull Block<?> currentBlock = this.getBlockType(tilePos);
+        final int currentData = this.getBlockData(tilePos);
+        if (super.setBlockType(tilePos, block)) {
+            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), currentBlock.id(), currentData));
             return true;
         } else {
             return false;
diff --git a/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java b/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java
index 1a218ddfe..813b609a0 100644
--- a/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java
+++ b/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/Cube.java
@@ -10,6 +10,8 @@ import com.google.gson.JsonSerializer;
 import net.minecraft.core.util.helper.Direction;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.joml.Vector3d;
+import org.joml.Vector3dc;
 import org.useless.util.GsonHelper;
 
 import java.lang.reflect.Type;
@@ -21,10 +23,10 @@ public class Cube {
     public final double @NotNull [] size;
     public final @Nullable Face @NotNull [] faces;
     public final double inflate;
-    public final double @NotNull [] pivot;
-    public final double @Nullable [] rotation;
+    public final @NotNull Vector3dc pivot;
+    public final @Nullable Vector3dc rotation;
 
-    protected Cube(final double @NotNull [] origin, final double @NotNull [] size, final @Nullable Face.Builder @NotNull [] faces, final double inflate, final double @NotNull [] pivot, final double @Nullable [] rotation) {
+    protected Cube(final double @NotNull [] origin, final double @NotNull [] size, final @Nullable Face.Builder @NotNull [] faces, final double inflate, final @NotNull Vector3d pivot, final @Nullable Vector3d rotation) {
         this.origin = origin;
         this.size = size;
         this.pivot = pivot;
@@ -43,8 +45,8 @@ public class Cube {
         private final double @NotNull [] size;
         private final @Nullable Face.Builder @NotNull [] faces;
         private double inflate;
-        private final double @NotNull [] pivot;
-        private double @Nullable [] rotation = null;
+        private final @NotNull Vector3d pivot;
+        private @Nullable Vector3d rotation = null;
         private boolean mirror;
 
         public Builder(
@@ -55,7 +57,7 @@ public class Cube {
             this.size = new double[]{sX, sY, sZ};
             this.faces = new Face.Builder[6];
             this.inflate = 0;
-            this.pivot = new double[]{0, 0, 0};
+            this.pivot = new Vector3d();
         }
 
         public Builder(
@@ -66,7 +68,7 @@ public class Cube {
             this.size = size;
             this.faces = new Face.Builder[6];
             this.inflate = 0;
-            this.pivot = new double[]{0, 0, 0};
+            this.pivot = new Vector3d();
         }
 
         public @NotNull Builder setFaces(final double u, final double v) {
@@ -93,17 +95,13 @@ public class Cube {
         }
 
         public @NotNull Builder setPivot(final double x, final double y, final double z) {
-            this.pivot[0] = x;
-            this.pivot[1] = y;
-            this.pivot[2] = z;
+            this.pivot.set(x, y, z);
             return this;
         }
 
         public @NotNull Builder setRotation(final double x, final double y, final double z) {
-            if (this.rotation == null) this.rotation = new double[3];
-            this.rotation[0] = x;
-            this.rotation[1] = y;
-            this.rotation[2] = z;
+            if (this.rotation == null) this.rotation = new Vector3d();
+            this.rotation.set(x, y, z);
             return this;
         }
 
diff --git a/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java b/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java
index 7aa17e976..255686b42 100644
--- a/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java
+++ b/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java
@@ -6,11 +6,8 @@ import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.block.color.BlockColor;
 import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.block.model.generic.BlockModelGeneric;
-import net.minecraft.client.render.renderer.GLRenderer;
-import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.block.BlockLogic;
 import net.minecraft.core.util.helper.Axis;
 import net.minecraft.core.util.helper.Color;
@@ -26,7 +23,6 @@ import org.joml.Vector3d;
 import org.joml.Vector3dc;
 import org.joml.Vector3f;
 import org.joml.Vector3fc;
-import org.lwjgl.opengl.GL41;
 import org.useless.dragonfly.DisplayPos;
 import org.useless.dragonfly.data.block.mojang.BlockModelMojangData;
 import org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData;
@@ -55,18 +51,10 @@ public class StaticBlockModelMojang implements StaticBlockModel {
     public boolean renderStandalone(@NotNull BlockModelGeneric<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, double x, double y, double z, int metadata, int lightmapCoord, @NotNull BlockColor color) {
         if (this.compiled.elements.length == 0) return false;
 
-        GLRenderer.pushFrame();
-        GLRenderer.setShader(Shaders.TERRAIN);
-        GL41.glActiveTexture(GL41.GL_TEXTURE2);
-        TextureRegistry.worldAtlas.layerTextureMap.get("emissive").bind();
-//        GL41.glActiveTexture(GL41.GL_TEXTURE3);
-//        TextureRegistry.worldAtlas.layerTextureMap.get("maskColor").bind();
-        GL41.glActiveTexture(GL41.GL_TEXTURE0);
         tessellator.startDrawingQuads();
         for (int i = 0; i < this.compiled.elements.length; i++) {
             C_Element element = this.compiled.elements[i];
 
-            tessellator.setColor1i(0xFFFFFFFF);
             tessellator.setLightmapCoord1i(lightmapCoord);
             for (int face = 0; face < element.faces; face++) {
                 IconCoordinate coordinate = element.textures[face];
@@ -97,7 +85,6 @@ public class StaticBlockModelMojang implements StaticBlockModel {
             }
         }
         tessellator.draw();
-        GLRenderer.popFrame();
         return true;
     }
 
diff --git a/game/client/src/main/java/org/useless/dragonfly/models/entity/StaticEntityModel.java b/game/client/src/main/java/org/useless/dragonfly/models/entity/StaticEntityModel.java
index a57695dc8..aa9619f2a 100644
--- a/game/client/src/main/java/org/useless/dragonfly/models/entity/StaticEntityModel.java
+++ b/game/client/src/main/java/org/useless/dragonfly/models/entity/StaticEntityModel.java
@@ -9,4 +9,5 @@ public interface StaticEntityModel {
     @NotNull AABBdc visibleBounds();
     void translateToBone(@NotNull String boneId);
     void render();
+    void delete();
 }
diff --git a/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java b/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java
index 2b2969cd3..a74e34b68 100644
--- a/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java
+++ b/game/client/src/main/java/org/useless/dragonfly/models/entity/mojang/StaticEntityModelMojang.java
@@ -4,11 +4,18 @@ import com.mojang.logging.LogUtils;
 import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 import net.minecraft.client.render.renderer.DrawMode;
 import net.minecraft.client.render.renderer.GLRenderer;
+import net.minecraft.client.render.renderer.Shaders;
+import net.minecraft.client.render.tessellator.RenderBuffer;
 import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.client.render.uniform.UniformBlockManager;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.MathHelper;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.joml.Math;
+import org.joml.Matrix4f;
+import org.joml.Vector3d;
+import org.joml.Vector3dc;
 import org.joml.primitives.AABBd;
 import org.joml.primitives.AABBdc;
 import org.lwjgl.BufferUtils;
@@ -22,23 +29,25 @@ import org.useless.dragonfly.models.entity.BoneTransform;
 import org.useless.dragonfly.models.entity.StaticEntityModel;
 
 import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
 import java.util.Map;
 
 public class StaticEntityModelMojang implements StaticEntityModel {
+    public static final int MAX_BONES = 128;
     private static final BoneTransform DUMMY_TRANSFORM = new BoneTransform();
-    private static final TessellatorEntity entityTessellator = new TessellatorEntity(8192);
+    private static final TessellatorEntity entityTessellator = new TessellatorEntity(16384);
     public final @NotNull Map<@NotNull String, @NotNull BoneTransform> transformMap = new Object2ObjectOpenHashMap<>();
     public final @NotNull BoneTransform @NotNull [] transforms;
-    public final @NotNull Bone @NotNull [] bones;
+    public final @NotNull BoneEntry @NotNull [] bones;
     public final EntityGeometryMojangData data;
     public final double inflation;
     protected final @NotNull AABBd visBounds;
 
+    private final @NotNull RenderBuffer renderBuffer;
+
     public StaticEntityModelMojang(final @NotNull EntityGeometryMojangData data, final double inflation) {
         this.data = data;
         this.transforms = new BoneTransform[this.data.bones.size()];
-        this.bones = new Bone[this.data.bones.size()];
+        this.bones = new BoneEntry[this.data.bones.size()];
         this.inflation = inflation;
 
         int i = 0;
@@ -46,7 +55,7 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             final BoneTransform transform = new BoneTransform();
             this.transformMap.put(entry.getKey(), transform);
             this.transforms[i] = transform;
-            this.bones[i] = entry.getValue();
+            this.bones[i] = new BoneEntry(entry.getValue(), i);
             i++;
         }
 
@@ -58,6 +67,12 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             (this.data.vBoundsOffset[1] + this.data.vBoundsHeight / 2),
             (this.data.vBoundsOffset[2] + this.data.vBoundsWidth / 2)
         );
+
+        entityTessellator.startDrawingQuads();
+        for (BoneEntry bone : this.bones) {
+            renderBone(entityTessellator, bone);
+        }
+        this.renderBuffer = entityTessellator.record(GL41.glGenVertexArrays(), GL41.glGenBuffers());
     }
 
     @Override
@@ -81,49 +96,73 @@ public class StaticEntityModelMojang implements StaticEntityModel {
     public void translateToBone(@NotNull final String boneId) {
         final Bone bone = this.data.bones.get(boneId);
         if (bone == null) return;
-        boneTransform(bone);
+        boneTransform(bone, mat.identity());
+        GLRenderer.modelM4f().mul(mat);
         GLRenderer.modelM4f().translate((float) bone.pivot[0], (float) bone.pivot[1], (float) bone.pivot[2]);
     }
-
+    private static final Matrix4f hiddenMat = new Matrix4f()
+        .set(0, 0, 0, 0,
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            0, 0, 0, 0);
     @Override
     public void render() {
-        GLRenderer.getShader().bind();
-        GLRenderer.globalSetUniforms(GLRenderer.getShader());
-        for (int i = 0; i < this.bones.length; i++) {
-            final Bone bone = this.bones[i];
-            GLRenderer.pushFrame();
-            if (!boneTransform(bone)) {
-                GL41.glUniformMatrix4fv(GLRenderer.getShader().getUniform("model"), false, GLRenderer.modelM4f().get(this.mat4fBuf));
-                renderBone(entityTessellator, bone);
+        GLRenderer.pushFrame();
+        GLRenderer.setShader(Shaders.ENTITY);
+        GLRenderer.globalSetUniforms(Shaders.ENTITY);
+        Shaders.ENTITY.uniformVec2f("uLightmap", GLRenderer.getLightmapBlock(), GLRenderer.getLightmapSky());
+        {
+            GL41.glBindBuffer(GL41.GL_UNIFORM_BUFFER, UniformBlockManager.BLOCK_ENTITY_BONES.ubo);
+            UniformBlockManager.BLOCK_ENTITY_BONES.buffer.clear();
+            int i = 0;
+            for (BoneEntry entry : this.bones) {
+                if (boneTransform(entry.bone(), mat.identity())) {
+                    UniformBlockManager.BLOCK_ENTITY_BONES.adapter.bufferData(hiddenMat, entry.index() * 16 * 4, UniformBlockManager.BLOCK_ENTITY_BONES.buffer);
+                } else {
+                    UniformBlockManager.BLOCK_ENTITY_BONES.adapter.bufferData(mat, entry.index() * 16 * 4, UniformBlockManager.BLOCK_ENTITY_BONES.buffer);
+                }
+                i++;
             }
-            GLRenderer.popFrame();
+            GL41.glBufferSubData(GL41.GL_UNIFORM_BUFFER, 0, UniformBlockManager.BLOCK_ENTITY_BONES.buffer.limit(i * 16 * 4));
+            GL41.glBindBuffer(GL41.GL_UNIFORM_BUFFER, 0);
         }
+
+        GL41.glBindVertexArray(this.renderBuffer.vao());
+        GL41.glBindBuffer(GL41.GL_ARRAY_BUFFER, this.renderBuffer.vbo());
+        GL41.glDrawArrays(this.renderBuffer.drawMode().cap, this.renderBuffer.offset(), this.renderBuffer.count());
+        GL41.glBindVertexArray(0);
+        GLRenderer.popFrame();
+    }
+
+    @Override
+    public void delete() {
+        this.renderBuffer.delete();
     }
 
-    protected boolean boneTransform(@NotNull final Bone bone) {
+    private static final @NotNull Matrix4f mat = new Matrix4f();
+    protected boolean boneTransform(@NotNull final Bone bone, @NotNull Matrix4f dest) {
         boolean hidden = false;
         final Bone parent = bone.parent != null ? this.data.bones.get(bone.parent) : null;
         if (parent != null) {
-            hidden |= boneTransform(parent);
+            hidden |= boneTransform(parent, dest);
         }
         final BoneTransform transform = this.transformMap.get(bone.name);
         hidden |= !transform.visible;
-        GLRenderer.modelM4f().translate((float) bone.pivot[0], (float) bone.pivot[1], (float) bone.pivot[2]);
-        GLRenderer.modelM4f().translate((float) transform.posX, (float) transform.posY, (float) transform.posZ);
-        GLRenderer.modelM4f().rotateZ((float) (-transform.rotZ - Math.toRadians(bone.rotation[2])));
-        GLRenderer.modelM4f().rotateY((float) (transform.rotY + Math.toRadians(bone.rotation[1])));
-        GLRenderer.modelM4f().rotateX((float) (-transform.rotX - Math.toRadians(bone.rotation[0])));
-        GLRenderer.modelM4f().translate((float) -bone.pivot[0], (float) -bone.pivot[1], (float) -bone.pivot[2]);
-        GLRenderer.modelM4f().scale((float) transform.scaleX, (float) transform.scaleY, (float) transform.scaleZ);
+        dest.translate((float) bone.pivot[0], (float) bone.pivot[1], (float) bone.pivot[2]);
+        dest.translate((float) transform.posX, (float) transform.posY, (float) transform.posZ);
+        dest.rotateZ((float) (-transform.rotZ - Math.toRadians(bone.rotation[2])));
+        dest.rotateY((float) (transform.rotY + Math.toRadians(bone.rotation[1])));
+        dest.rotateX((float) (-transform.rotX - Math.toRadians(bone.rotation[0])));
+        dest.translate((float) -bone.pivot[0], (float) -bone.pivot[1], (float) -bone.pivot[2]);
+        dest.scale((float) transform.scaleX, (float) transform.scaleY, (float) transform.scaleZ);
         return hidden;
     }
 
-    private final FloatBuffer mat4fBuf = BufferUtils.createFloatBuffer(16);
-
     private final double[] uvsBuffer = new double[8];
 
-    protected void renderBone(@NotNull final TessellatorEntity tessellator, @NotNull final Bone bone) {
-        tessellator.startDrawingQuads();
+    protected void renderBone(final @NotNull  TessellatorEntity tessellator, final @NotNull BoneEntry entry) {
+        tessellator.setBone(entry.index());
+        Bone bone = entry.bone();
         for (final Cube cube : bone.cubes) {
             final double minX = cube.origin[0] - (cube.inflate + bone.inflate + this.inflation);
             final double minY = cube.origin[1] - (cube.inflate + bone.inflate + this.inflation);
@@ -133,364 +172,187 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             final double maxY = minY + cube.size[1] + (cube.inflate + bone.inflate + this.inflation) * 2;
             final double maxZ = minZ + cube.size[2] + (cube.inflate + bone.inflate + this.inflation) * 2;
 
-            if (cube.rotation == null) {
-                // Top
-                Face face = cube.faces[Direction.UP.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMin;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMax;
-
-                    this.uvsBuffer[1] = vMin;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMax;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(0, 1, 0);
-                    tessellator.addVertexWithUV(minX, maxY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(minX, maxY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, maxY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8]);
-                }
-
-                // Bottom
-                face = cube.faces[Direction.DOWN.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(0, -1, 0);
-                    tessellator.addVertexWithUV(minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, minY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, minY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(minX, minY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8]);
-                }
-
-                // Front
-                face = cube.faces[Direction.NORTH.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(0, 0, -1);
-                    tessellator.addVertexWithUV(minX, minY, minZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, minY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(minX, maxY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8]);
-                }
+            // Top
+            Face face = cube.faces[Direction.UP.getId()];
+            if (face != null) {
+                final double uMin = (face.uv[0]) / this.data.textureWidth;
+                final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
+                final double vMin = (face.uv[1]) / this.data.textureHeight;
+                final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
+
+                this.uvsBuffer[0] = uMin;
+                this.uvsBuffer[2] = uMin;
+                this.uvsBuffer[4] = uMax;
+                this.uvsBuffer[6] = uMax;
+
+                this.uvsBuffer[1] = vMin;
+                this.uvsBuffer[3] = vMax;
+                this.uvsBuffer[5] = vMax;
+                this.uvsBuffer[7] = vMin;
+
+                tessellator.setNormal(0, 1, 0);
+                addRotatedVertex(tessellator, minX, maxY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, minX, maxY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, maxY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
 
-                // Back
-                face = cube.faces[Direction.SOUTH.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMax;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMin;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMin;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMax;
-
-                    tessellator.setNormal(0, 0, 1);
-                    tessellator.addVertexWithUV(minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(minX, maxY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, maxY, maxZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, minY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8]);
-                }
-
-                // Right
-                face = cube.faces[Direction.WEST.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMax;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMin;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMin;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMax;
-
-                    tessellator.setNormal(1, 0, 0);
-                    tessellator.addVertexWithUV(maxX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, maxY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(maxX, minY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8]);
-                }
-
-                // Left
-                face = cube.faces[Direction.EAST.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(-1, 0, 0);
-                    tessellator.addVertexWithUV(minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(minX, minY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(minX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8]);
-                    tessellator.addVertexWithUV(minX, maxY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8]);
-                }
-            } else {
-                // Top
-                Face face = cube.faces[Direction.UP.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMin;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMax;
-
-                    this.uvsBuffer[1] = vMin;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMax;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(0, 1, 0);
-                    addRotatedVertex(tessellator, minX, maxY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, minX, maxY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, maxY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-
-                }
+            }
 
-                // Bottom
-                face = cube.faces[Direction.DOWN.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(0, -1, 0);
-                    addRotatedVertex(tessellator, minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, minY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, minY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, minX, minY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                }
+            // Bottom
+            face = cube.faces[Direction.DOWN.getId()];
+            if (face != null) {
+                final double uMin = (face.uv[0]) / this.data.textureWidth;
+                final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
+                final double vMin = (face.uv[1]) / this.data.textureHeight;
+                final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
+
+                this.uvsBuffer[0] = uMin;
+                this.uvsBuffer[2] = uMax;
+                this.uvsBuffer[4] = uMax;
+                this.uvsBuffer[6] = uMin;
+
+                this.uvsBuffer[1] = vMax;
+                this.uvsBuffer[3] = vMax;
+                this.uvsBuffer[5] = vMin;
+                this.uvsBuffer[7] = vMin;
+
+                tessellator.setNormal(0, -1, 0);
+                addRotatedVertex(tessellator, minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, minY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, minY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, minX, minY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+            }
 
-                // Front
-                face = cube.faces[Direction.NORTH.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(0, 0, -1);
-                    addRotatedVertex(tessellator, minX, minY, minZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, minY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, minX, maxY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                }
+            // Front
+            face = cube.faces[Direction.NORTH.getId()];
+            if (face != null) {
+                final double uMin = (face.uv[0]) / this.data.textureWidth;
+                final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
+                final double vMin = (face.uv[1]) / this.data.textureHeight;
+                final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
+
+                this.uvsBuffer[0] = uMin;
+                this.uvsBuffer[2] = uMax;
+                this.uvsBuffer[4] = uMax;
+                this.uvsBuffer[6] = uMin;
+
+                this.uvsBuffer[1] = vMax;
+                this.uvsBuffer[3] = vMax;
+                this.uvsBuffer[5] = vMin;
+                this.uvsBuffer[7] = vMin;
+
+                tessellator.setNormal(0, 0, -1);
+                addRotatedVertex(tessellator, minX, minY, minZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, minY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, minX, maxY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+            }
 
-                // Back
-                face = cube.faces[Direction.SOUTH.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMax;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMin;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMin;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMax;
-
-                    tessellator.setNormal(0, 0, 1);
-                    addRotatedVertex(tessellator, minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, minX, maxY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, maxY, maxZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, minY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                }
+            // Back
+            face = cube.faces[Direction.SOUTH.getId()];
+            if (face != null) {
+                final double uMin = (face.uv[0]) / this.data.textureWidth;
+                final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
+                final double vMin = (face.uv[1]) / this.data.textureHeight;
+                final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
+
+                this.uvsBuffer[0] = uMax;
+                this.uvsBuffer[2] = uMax;
+                this.uvsBuffer[4] = uMin;
+                this.uvsBuffer[6] = uMin;
+
+                this.uvsBuffer[1] = vMax;
+                this.uvsBuffer[3] = vMin;
+                this.uvsBuffer[5] = vMin;
+                this.uvsBuffer[7] = vMax;
+
+                tessellator.setNormal(0, 0, 1);
+                addRotatedVertex(tessellator, minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, minX, maxY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, maxY, maxZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, minY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+            }
 
-                // Right
-                face = cube.faces[Direction.WEST.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMax;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMin;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMin;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMax;
-
-                    tessellator.setNormal(1, 0, 0);
-                    addRotatedVertex(tessellator, maxX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, maxY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, maxX, minY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                }
+            // Right
+            face = cube.faces[Direction.WEST.getId()];
+            if (face != null) {
+                final double uMin = (face.uv[0]) / this.data.textureWidth;
+                final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
+                final double vMin = (face.uv[1]) / this.data.textureHeight;
+                final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
+
+                this.uvsBuffer[0] = uMax;
+                this.uvsBuffer[2] = uMax;
+                this.uvsBuffer[4] = uMin;
+                this.uvsBuffer[6] = uMin;
+
+                this.uvsBuffer[1] = vMax;
+                this.uvsBuffer[3] = vMin;
+                this.uvsBuffer[5] = vMin;
+                this.uvsBuffer[7] = vMax;
+
+                tessellator.setNormal(1, 0, 0);
+                addRotatedVertex(tessellator, maxX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, maxY, maxZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, maxX, minY, minZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+            }
 
-                // Left
-                face = cube.faces[Direction.EAST.getId()];
-                if (face != null) {
-                    final double uMin = (face.uv[0]) / this.data.textureWidth;
-                    final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
-                    final double vMin = (face.uv[1]) / this.data.textureHeight;
-                    final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
-
-                    this.uvsBuffer[0] = uMin;
-                    this.uvsBuffer[2] = uMax;
-                    this.uvsBuffer[4] = uMax;
-                    this.uvsBuffer[6] = uMin;
-
-                    this.uvsBuffer[1] = vMax;
-                    this.uvsBuffer[3] = vMax;
-                    this.uvsBuffer[5] = vMin;
-                    this.uvsBuffer[7] = vMin;
-
-                    tessellator.setNormal(-1, 0, 0);
-                    addRotatedVertex(tessellator, minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, minX, minY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, minX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                    addRotatedVertex(tessellator, minX, maxY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
-                }
+            // Left
+            face = cube.faces[Direction.EAST.getId()];
+            if (face != null) {
+                final double uMin = (face.uv[0]) / this.data.textureWidth;
+                final double uMax = (face.uv[0] + face.uv_size[0]) / this.data.textureWidth;
+                final double vMin = (face.uv[1]) / this.data.textureHeight;
+                final double vMax = (face.uv[1] + face.uv_size[1]) / this.data.textureHeight;
+
+                this.uvsBuffer[0] = uMin;
+                this.uvsBuffer[2] = uMax;
+                this.uvsBuffer[4] = uMax;
+                this.uvsBuffer[6] = uMin;
+
+                this.uvsBuffer[1] = vMax;
+                this.uvsBuffer[3] = vMax;
+                this.uvsBuffer[5] = vMin;
+                this.uvsBuffer[7] = vMin;
+
+                tessellator.setNormal(-1, 0, 0);
+                addRotatedVertex(tessellator, minX, minY, maxZ, this.uvsBuffer[(face.uv_rotation * 2) % 8], this.uvsBuffer[(1 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, minX, minY, minZ, this.uvsBuffer[(2 + face.uv_rotation * 2) % 8], this.uvsBuffer[(3 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, minX, maxY, minZ, this.uvsBuffer[(4 + face.uv_rotation * 2) % 8], this.uvsBuffer[(5 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
+                addRotatedVertex(tessellator, minX, maxY, maxZ, this.uvsBuffer[(6 + face.uv_rotation * 2) % 8], this.uvsBuffer[(7 + face.uv_rotation * 2) % 8], cube.pivot, cube.rotation);
             }
         }
-        tessellator.draw();
     }
 
-    protected static void addRotatedVertex(@NotNull final TessellatorEntity tessellator, final double x, final double y, final double z, final double u, final double v, final double @NotNull [] pivot, final double @NotNull [] rotation) {
-        double _x = x - pivot[0];
-        double _y = y - pivot[1];
-        double _z = z - pivot[2];
-
-        float sin;
-        float cos;
-        double nx;
-        double ny;
-        double nz;
-
-        // X
-        sin = MathHelper.sin((float) (-rotation[0] * MathHelper.DEG_TO_RAD));
-        cos = MathHelper.cos((float) (-rotation[0] * MathHelper.DEG_TO_RAD));
-        nx = _x;
-        ny = _y * cos - _z * sin;
-        nz = _z * cos + _y * sin;
-        _x = nx;
-        _y = ny;
-        _z = nz;
-
-        // Y
-        sin = MathHelper.sin((float) (-rotation[1] * MathHelper.DEG_TO_RAD));
-        cos = MathHelper.cos((float) (-rotation[1] * MathHelper.DEG_TO_RAD));
-        nx = _x * cos - _z * sin;
-        ny = _y;
-        nz = _z * cos + _x * sin;
-        _x = nx;
-        _y = ny;
-        _z = nz;
-
-        // Z
-        sin = MathHelper.sin((float) (-rotation[2] * MathHelper.DEG_TO_RAD));
-        cos = MathHelper.cos((float) (-rotation[2] * MathHelper.DEG_TO_RAD));
-        nx = _x * cos - _y * sin;
-        ny = _y * cos + _x * sin;
-        nz = _z;
-        _x = nx;
-        _y = ny;
-        _z = nz;
-
-
-        tessellator.addVertexWithUV(_x + pivot[0], _y + pivot[1], _z + pivot[2], u, v);
+    private static final @NotNull Vector3d q = new Vector3d();
+    protected static void addRotatedVertex(@NotNull final TessellatorEntity tessellator, final double x, final double y, final double z, final double u, final double v, final @NotNull Vector3dc pivot, final @Nullable Vector3dc rotation) {
+        if (rotation == null) {
+            tessellator.addVertexWithUV(x, y, z, u, v);
+        } else {
+            q.set(x, y, z)
+                .sub(pivot)
+                .rotateX(-rotation.x() * MathHelper.DEG_TO_RAD)
+                .rotateY(-rotation.y() * MathHelper.DEG_TO_RAD)
+                .rotateZ(-rotation.z() * MathHelper.DEG_TO_RAD)
+                .add(pivot);
+            tessellator.addVertexWithUV(q, u, v);
+        }
+    }
+
+    public record BoneEntry(@NotNull Bone bone, int index) {
+
     }
 
     public static class TessellatorEntity {
         private static final Logger LOGGER = LogUtils.getLogger();
-        private static final int VERT_SIZE = 5 * Float.BYTES + 3;
+        private static final int VERT_SIZE = 5 * Float.BYTES + 7;
         public ByteBuffer data;
 
         public boolean drawing;
 
+        public int boneIndex = 0;
+
         public byte normalX = 0;
         public byte normalY = -128;
         public byte normalZ = 0;
@@ -506,18 +368,7 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             this.vao = GL41.glGenVertexArrays();
             this.vbo = GL41.glGenBuffers();
 
-            GL41.glBindVertexArray(this.vao);
-            GL41.glBindBuffer(GL41.GL_ARRAY_BUFFER, this.vbo);
-
-            GL41.glVertexAttribPointer(0, 3, GL41.GL_FLOAT, false, VERT_SIZE, 0);
-            GL41.glVertexAttrib4f(1, 1f, 1f, 1f, 1f);
-            GL41.glVertexAttribPointer(2, 2, GL41.GL_FLOAT, false, VERT_SIZE, Float.BYTES * 3);
-            GL41.glVertexAttrib2f(3, 15.5f/16f, 15.5f/16f);
-            GL41.glVertexAttribPointer(4, 3, GL41.GL_BYTE, true, VERT_SIZE, Float.BYTES * 5);
-
-            GL41.glEnableVertexAttribArray(0);
-            GL41.glEnableVertexAttribArray(2);
-            GL41.glEnableVertexAttribArray(4);
+            enable(this.vao, this.vbo);
         }
 
         public void startDrawingQuads() {
@@ -538,15 +389,20 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             this.data.clear();
         }
 
+        public void addVertexWithUV(@NotNull Vector3dc pos, double u, double v) {
+            addVertexWithUV(pos.x(), pos.y(), pos.z(), u, v);
+        }
+
         public void addVertexWithUV(double x, double y, double z, double u, double v) {
             if(!this.drawing) {
-                throw new IllegalStateException("Entity Tessellator already drawing!");
+                throw new IllegalStateException("Entity Tessellator not drawing!");
             }
             checkCanFit(64);
 
             this.data.putFloat((float) x).putFloat((float) y).putFloat((float) z);
             this.data.putFloat((float) u).putFloat((float) v);
             this.data.put(this.normalX).put(this.normalY).put(this.normalZ);
+            this.data.putFloat(this.boneIndex + 0.05f);
 
             this.vertexCount++;
 
@@ -574,9 +430,17 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             }
         }
 
+        public void setBone(int boneIndex) {
+            if(!this.drawing) {
+                throw new IllegalStateException("Entity Tessellator not drawing!");
+            }
+
+            this.boneIndex = (byte) boneIndex;
+        }
+
         public void setNormal(double x, double y, double z) {
             if(!this.drawing) {
-                throw new IllegalStateException("Entity Tessellator already drawing!");
+                throw new IllegalStateException("Entity Tessellator not drawing!");
             }
 
             this.normalX = (byte) (x * 127.0);
@@ -584,21 +448,31 @@ public class StaticEntityModelMojang implements StaticEntityModel {
             this.normalZ = (byte) (z * 127.0);
         }
 
-        public void draw() {
+        public @NotNull RenderBuffer record(int vao, int vbo) {
             if(!this.drawing) {
-                throw new IllegalStateException("Entity Tessellator already drawing!");
+                throw new IllegalStateException("Entity Tessellator not drawing!");
             }
-
             this.drawing = false;
 
-            if (this.vertexCount == 0) return;
-
-            GL41.glBindVertexArray(this.vao);
-            GL41.glVertexAttrib2f(3, GLRenderer.getLightmapBlock(), GLRenderer.getLightmapSky());
-            GL41.glBindBuffer(GL41.GL_ARRAY_BUFFER, this.vbo);
-            GL41.glBufferData(GL41.GL_ARRAY_BUFFER, this.data.flip(), GL41.GL_STREAM_DRAW);
-            GL41.glDrawArrays(Tessellator.QUAD_EMULATION ? DrawMode.TRIANGLES.cap : DrawMode.QUADS.cap, 0, this.vertexCount);
+            enable(vao, vbo);
+            GL41.glBufferData(GL41.GL_ARRAY_BUFFER, this.data.flip(), GL41.GL_STATIC_DRAW);
             GL41.glBindVertexArray(0);
+            return new RenderBuffer(vao, vbo, 0, this.vertexCount, Tessellator.QUAD_EMULATION ? DrawMode.TRIANGLES : DrawMode.QUADS);
+        }
+
+        public void enable(int vao, int vbo) {
+            GL41.glBindVertexArray(vao);
+            GL41.glBindBuffer(GL41.GL_ARRAY_BUFFER, vbo);
+
+            GL41.glVertexAttribPointer(0, 3, GL41.GL_FLOAT, false, VERT_SIZE, 0);
+            GL41.glVertexAttribPointer(1, 2, GL41.GL_FLOAT, false, VERT_SIZE, Float.BYTES * 3);
+            GL41.glVertexAttribPointer(2, 3, GL41.GL_BYTE, true, VERT_SIZE, Float.BYTES * 5);
+            GL41.glVertexAttribPointer(3, 1, GL41.GL_FLOAT, false, VERT_SIZE, Float.BYTES * 5 + 3);
+
+            GL41.glEnableVertexAttribArray(0);
+            GL41.glEnableVertexAttribArray(1);
+            GL41.glEnableVertexAttribArray(2);
+            GL41.glEnableVertexAttribArray(3);
         }
     }
 }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/grass_snowy.json b/game/client/src/main/resources/assets/minecraft/models/block/grass_snowy.json
new file mode 100644
index 000000000..c338eab0b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/grass_snowy.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/grass/top",
+    "bottom": "minecraft:block/grass/bottom",
+    "side": "minecraft:block/grass/snowy_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/igneous.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/igneous.emiss.png
index 72fd137df..cae60c73b 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/igneous.emiss.png and b/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/igneous.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/crystal.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/crystal.emiss.png
new file mode 100644
index 000000000..c382195c5
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/crystal.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/overlay.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/overlay.emiss.png
new file mode 100644
index 000000000..a967e867b
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/overlay.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/stalk.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/stalk.emiss.png
new file mode 100644
index 000000000..6960c5c15
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/nether_crystal/stalk.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/torch_coal.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/torch_coal.emiss.png
new file mode 100644
index 000000000..e68141eed
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/torch_coal.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/torch_redstone_active.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/torch_redstone_active.emiss.png
new file mode 100644
index 000000000..b3fd18724
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/torch_redstone_active.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/misc/white.png b/game/client/src/main/resources/assets/minecraft/textures/misc/white.png
new file mode 100644
index 000000000..45e30fdb4
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/misc/white.png differ
diff --git a/game/client/src/main/resources/shaders/aurora.fsh b/game/client/src/main/resources/shaders/aurora.fsh
new file mode 100644
index 000000000..0baabf72b
--- /dev/null
+++ b/game/client/src/main/resources/shaders/aurora.fsh
@@ -0,0 +1,31 @@
+#version 410 core
+
+out vec4 FragColor;
+
+in vec4 Color;
+in vec2 TexCoord;
+
+uniform float uAlphaTest;
+uniform vec4 uColor;
+
+layout (std140) uniform Matrices {
+    mat4 projection;
+    mat4 projectionInv;
+    mat4 view;
+    mat4 viewInv;
+} matrices;
+
+uniform sampler2D colortex;
+
+
+void main() {
+    vec4 texColor = texture(colortex, TexCoord);
+
+    vec4 oColor = texColor * Color * uColor;
+    vec4 litColor = vec4(oColor.rgb, oColor.a);
+
+    FragColor = litColor;
+    if (FragColor.a < uAlphaTest) {
+        discard;
+    }
+}
diff --git a/game/client/src/main/resources/shaders/aurora.vsh b/game/client/src/main/resources/shaders/aurora.vsh
new file mode 100644
index 000000000..dc194b67a
--- /dev/null
+++ b/game/client/src/main/resources/shaders/aurora.vsh
@@ -0,0 +1,27 @@
+#version 410 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec3 aPosO;
+layout (location = 2) in vec4 aColor;
+layout (location = 3) in vec4 aColorO;
+layout (location = 4) in vec2 aUV;
+
+out vec4 Color;
+out vec2 TexCoord;
+out vec2 LightMapCoord;
+
+uniform mat4 model;
+uniform float uPartialTick;
+
+layout (std140) uniform Matrices {
+    mat4 projection;
+    mat4 projectionInv;
+    mat4 view;
+    mat4 viewInv;
+} matrices;
+
+void main() {
+    gl_Position = matrices.projection * matrices.view * model * vec4(mix(aPosO, aPos, uPartialTick), 1);
+
+    TexCoord = aUV;
+    Color = mix(aColorO, aColor, uPartialTick);
+}
diff --git a/game/client/src/main/resources/shaders/clouds.fsh b/game/client/src/main/resources/shaders/clouds.fsh
index 7af39eadc..a482602c3 100644
--- a/game/client/src/main/resources/shaders/clouds.fsh
+++ b/game/client/src/main/resources/shaders/clouds.fsh
@@ -23,6 +23,7 @@ layout (std140) uniform Matrices {
 	mat4 viewInv;
 } matrices;
 
+uniform float uAlphaTest;
 uniform int isEyeInLiquid;
 uniform vec2 uViewPortSize;
 
@@ -40,7 +41,7 @@ void main() {
 	vec4 tex = texture(colortex, TexCoord);
 	
 	// Alpha test
-	if(tex.a < 0.1) {
+	if(tex.a < uAlphaTest) {
 		discard;
 	}
 	
diff --git a/game/client/src/main/resources/shaders/color_world.fsh b/game/client/src/main/resources/shaders/color_world.fsh
index 7f3d1bcb4..dfd85c2ff 100644
--- a/game/client/src/main/resources/shaders/color_world.fsh
+++ b/game/client/src/main/resources/shaders/color_world.fsh
@@ -6,6 +6,7 @@ in vec4 Color;
 in vec2 LightMapCoord;
 in vec3 Light;
 
+uniform float uAlphaTest;
 uniform vec4 uColor;
 uniform vec2 uViewPortSize;
 
@@ -70,7 +71,7 @@ void main() {
     vec4 litColor = vec4(oColor.rgb * clamp(Light, 0, 1), oColor.a);
 
     FragColor = computeFog(oColor);
-    if (FragColor.a < 0.1) {
+    if (FragColor.a < uAlphaTest) {
         discard;
     }
 }
diff --git a/game/client/src/main/resources/shaders/entity.fsh b/game/client/src/main/resources/shaders/entity.fsh
new file mode 100644
index 000000000..380af1944
--- /dev/null
+++ b/game/client/src/main/resources/shaders/entity.fsh
@@ -0,0 +1,82 @@
+#version 410 core
+
+out vec4 FragColor;
+
+in vec2 TexCoord;
+in vec3 Light;
+
+uniform float uAlphaTest;
+uniform vec4 uColor;
+uniform vec2 uLightmap;
+uniform vec2 uViewPortSize;
+
+layout (std140) uniform FogState {
+    vec4 color;
+    int mode;
+    float start;
+    float end;
+    float density;
+} fogState;
+
+layout (std140) uniform Matrices {
+    mat4 projection;
+    mat4 projectionInv;
+    mat4 view;
+    mat4 viewInv;
+} matrices;
+
+uniform sampler2D colortex;
+uniform sampler2D lighttex;
+
+float distance() {
+    vec4 fragPos = matrices.projectionInv * vec4((gl_FragCoord.xy / uViewPortSize) * 2.0 - 1.0, gl_FragCoord.z * 2.0 - 1.0, 1.0);
+    fragPos /= fragPos.w;
+
+    return length(fragPos.xyz);
+}
+
+// Taken from https://github.com/hughsk/glsl-fog
+float fogFactorLinear() {
+    return 1.0 - clamp(((fogState.end - (distance())) / (fogState.end - fogState.start)), 0.0, 1.0);
+}
+
+float fogFactorExp() {
+    return 1.0 - clamp(exp(-fogState.density * (distance())), 0.0, 1.0);
+}
+
+float fogFactorExp2() {
+    float LOG2 = -1.442695;
+    float d = fogState.density * (distance());
+    return 1.0 - clamp(exp2(d * d * LOG2), 0.0, 1.0);
+}
+
+
+vec4 computeFog(vec4 color) {
+    float f = 0;
+    if (fogState.mode == 0) { // Linear
+        f = fogFactorLinear();
+    }
+    else if (fogState.mode == 1) { // EXP
+        f = fogFactorExp();
+    }
+    else if (fogState.mode == 2) { // EXP2
+        f = fogFactorExp2();
+    }
+    return vec4(mix(color.rgb, fogState.color.rgb, f), color.a);
+}
+
+void main() {
+    vec4 lightColor = texture(lighttex, uLightmap);
+    vec4 texColor = texture(colortex, TexCoord);
+
+    vec4 oColor = texColor * lightColor * uColor;
+    vec4 litColor = vec4(oColor.rgb * clamp(Light, 0, 1), oColor.a);
+
+    vec4 fColor = computeFog(litColor);
+
+
+    FragColor = fColor;
+    if (FragColor.a < uAlphaTest) {
+        discard;
+    }
+}
diff --git a/game/client/src/main/resources/shaders/entity.vsh b/game/client/src/main/resources/shaders/entity.vsh
new file mode 100644
index 000000000..fb562c06c
--- /dev/null
+++ b/game/client/src/main/resources/shaders/entity.vsh
@@ -0,0 +1,40 @@
+#version 410 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec2 aUV;
+layout (location = 2) in vec3 aNormal;
+layout (location = 3) in float abone;
+
+out vec2 TexCoord;
+out vec3 Light;
+
+uniform mat4 normalTransform;
+uniform vec4 lightModelAmbient;
+uniform vec4 lightSourcePosition1;
+uniform vec4 lightSourcePosition2;
+uniform vec4 lightSourceDiffuse1;
+uniform vec4 lightSourceDiffuse2;
+
+uniform mat4 model;
+uniform mat4 texture;
+
+layout (std140) uniform Matrices {
+    mat4 projection;
+    mat4 projectionInv;
+    mat4 view;
+    mat4 viewInv;
+} matrices;
+
+layout (std140) uniform Bones {
+    mat4 transforms[128];
+} bones;
+
+void main() {
+    mat4 bone = bones.transforms[int(abone)];
+    gl_Position = matrices.projection * matrices.view * model * bone * vec4(aPos, 1);
+    TexCoord = (texture * vec4(aUV, 0.0, 1.0)).xy;
+
+    vec4 norm = normalize(normalTransform * model * bone * vec4(aNormal, 0));
+    float dir1 = max(0.0, dot(norm, lightSourcePosition1));
+    float dir2 = max(0.0, dot(norm, lightSourcePosition2));
+    Light = (lightModelAmbient + lightSourceDiffuse1 * (dir1 + dir2)).xyz;
+}
diff --git a/game/client/src/main/resources/shaders/font.fsh b/game/client/src/main/resources/shaders/font.fsh
index 69ed2922c..d80227c35 100644
--- a/game/client/src/main/resources/shaders/font.fsh
+++ b/game/client/src/main/resources/shaders/font.fsh
@@ -5,6 +5,7 @@ in vec4 Color;
 in vec2 TexCoord;
 in vec2 Lightmap;
 
+uniform float uAlphaTest;
 uniform vec4 uColor;
 
 uniform sampler2D colortex;
@@ -12,7 +13,7 @@ uniform sampler2D lighttex;
 
 void main() {
     FragColor = texture(colortex, TexCoord) * texture(lighttex, Lightmap) * Color * uColor;
-    if (FragColor.a < 0.1) {
+    if (FragColor.a < uAlphaTest) {
         discard;
     }
 }
\ No newline at end of file
diff --git a/game/client/src/main/resources/shaders/lines.fsh b/game/client/src/main/resources/shaders/lines.fsh
index 228db697d..81ac31e41 100644
--- a/game/client/src/main/resources/shaders/lines.fsh
+++ b/game/client/src/main/resources/shaders/lines.fsh
@@ -1,12 +1,14 @@
 #version 410 core
 out vec4 FragColor;
 
+uniform float uAlphaTest;
+
 in vec4 Color;
 uniform vec4 uColor;
 
 void main() {
     FragColor = Color * uColor;
-    if (FragColor.a < 0.1) {
+    if (FragColor.a < uAlphaTest) {
         discard;
     }
 }
diff --git a/game/client/src/main/resources/shaders/particle.fsh b/game/client/src/main/resources/shaders/particle.fsh
index 66678e4fa..0208364de 100644
--- a/game/client/src/main/resources/shaders/particle.fsh
+++ b/game/client/src/main/resources/shaders/particle.fsh
@@ -5,12 +5,14 @@ in vec4 Color;
 in vec2 TexCoord;
 in vec2 Lightmap;
 
+uniform float uAlphaTest;
+
 uniform sampler2D colortex;
 uniform sampler2D lighttex;
 
 void main() {
     FragColor = texture(colortex, TexCoord) * texture(lighttex, Lightmap) * Color;
-    if (FragColor.a < 0.1) {
+    if (FragColor.a < uAlphaTest) {
         discard;
     }
 }
\ No newline at end of file
diff --git a/game/client/src/main/resources/shaders/terrain.fsh b/game/client/src/main/resources/shaders/terrain.fsh
index 5d742d0ea..fda0727cb 100644
--- a/game/client/src/main/resources/shaders/terrain.fsh
+++ b/game/client/src/main/resources/shaders/terrain.fsh
@@ -8,6 +8,7 @@ in vec2 LightMapCoord;
 in vec3 Light;
 in vec3 Norm;
 
+uniform float uAlphaTest;
 uniform vec4 uColor;
 uniform vec2 uViewPortSize;
 
@@ -87,7 +88,7 @@ void main() {
 
 
     FragColor = fColor;
-    if (FragColor.a < 0.1) {
+    if (FragColor.a < uAlphaTest) {
         discard;
     }
 }
diff --git a/game/client/src/main/resources/shaders/world.fsh b/game/client/src/main/resources/shaders/world.fsh
index 802eb8b50..990459bfb 100644
--- a/game/client/src/main/resources/shaders/world.fsh
+++ b/game/client/src/main/resources/shaders/world.fsh
@@ -7,6 +7,7 @@ in vec2 TexCoord;
 in vec2 LightMapCoord;
 in vec3 Light;
 
+uniform float uAlphaTest;
 uniform vec4 uColor;
 uniform vec2 uViewPortSize;
 
@@ -76,7 +77,7 @@ void main() {
 
 
     FragColor = fColor;
-    if (FragColor.a < 0.1) {
+    if (FragColor.a < uAlphaTest) {
         discard;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/NextTickListEntry.java b/game/core/src/main/java/net/minecraft/core/NextTickListEntry.java
index 9725c8391..c4681562b 100644
--- a/game/core/src/main/java/net/minecraft/core/NextTickListEntry.java
+++ b/game/core/src/main/java/net/minecraft/core/NextTickListEntry.java
@@ -2,6 +2,7 @@ package net.minecraft.core;
 
 
 import com.mojang.nbt.tags.CompoundTag;
+import net.minecraft.core.block.Block;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
@@ -14,20 +15,20 @@ public class NextTickListEntry
     private static long counter = 0L;
 
     public @NotNull TilePos tilePos;
-    public int blockId;
+    public @NotNull Block<?> block;
     public long delay;
     private final long entryId;
 
-    public NextTickListEntry(final @NotNull TilePosc tilePos, final int blockId) {
+    public NextTickListEntry(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         this.entryId = counter++;
         this.tilePos = new TilePos(tilePos);
-        this.blockId = blockId;
+        this.block = block;
     }
 
     @Override
     public boolean equals(final @Nullable Object obj) {
         if (obj instanceof final @NotNull NextTickListEntry entry) {
-            return this.tilePos.equals(entry.tilePos) && this.blockId == entry.blockId;
+            return this.tilePos.equals(entry.tilePos) && this.block == entry.block;
         } else {
             return false;
         }
@@ -35,7 +36,7 @@ public class NextTickListEntry
 
     @Override
     public int hashCode() {
-        return (this.tilePos.x() * 128 * 1024 + this.tilePos.z() * 128 + this.tilePos.y()) * 256 + this.blockId;
+        return (this.tilePos.x() * 128 * 1024 + this.tilePos.z() * 128 + this.tilePos.y()) * 256 + this.block.id();
     }
 
     public @NotNull NextTickListEntry setDelay(final long delay) {
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 ffcd2c3d3..5089647be 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
@@ -261,7 +261,7 @@ public final class Block<T extends BlockLogic>
 
     @Override
     public @NotNull Item asItem() {
-        return Item.itemsList[this.id];
+        return Objects.requireNonNull(Item.itemsList[this.id]);
     }
 
     @Override
@@ -270,8 +270,7 @@ public final class Block<T extends BlockLogic>
     }
 
     public static boolean getIsLitInteriorSurface(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = source.getBlock(tilePos);
-        return block != null && block.isLitInteriorSurface;
+        return source.getBlockType(tilePos).isLitInteriorSurface;
     }
 
     @Deprecated
@@ -408,8 +407,8 @@ public final class Block<T extends BlockLogic>
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
-        this.logic.onNeighborChanged(world, tilePos, id);
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        this.logic.onNeighborChanged(world, tilePos, block);
     }
 
     @Override
@@ -594,6 +593,34 @@ public final class Block<T extends BlockLogic>
         return this.logic.getAttachedSide(source, tilePos);
     }
 
+    public boolean shouldTick() {
+        return Blocks.shouldTick[this.id];
+    }
+
+    public boolean solid() {
+        return Blocks.solid[this.id];
+    }
+
+    public boolean isEntityTile() {
+        return Blocks.isEntityTile[this.id];
+    }
+
+    public int lightBlock() {
+        return Blocks.lightBlock[this.id];
+    }
+
+    public boolean translucent() {
+        return Blocks.translucent[this.id];
+    }
+
+    public int lightEmission() {
+        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());
     }
@@ -601,4 +628,9 @@ public final class Block<T extends BlockLogic>
     public static @Nullable BlockLogic getLogicClass(final @Nullable  Block<?> block) {
         return block == null ? null : block.getLogic();
     }
+
+    @Override
+    public @NotNull String toString() {
+        return this.namespaceId().toString();
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java b/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java
index 28afea31c..a3bd4dac6 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockInterface.java
@@ -27,6 +27,7 @@ import org.joml.primitives.AABBd;
 import org.joml.primitives.AABBdc;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.Random;
 
 interface BlockInterface {
@@ -167,11 +168,11 @@ interface BlockInterface {
         this.animationTick(world, new TilePos(x, y, z), rand);
     }
 
-    void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id);
+    void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block);
 
     @Deprecated
     default void onNeighborBlockChange(final @NotNull World world, final int x, final int y, final int z, final int id) {
-        this.onNeighborChanged(world, new TilePos(x, y, z), id);
+        this.onNeighborChanged(world, new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)));
     }
 
     int tickDelay();
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java
index 0fc4f0620..77fa14be5 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java
@@ -118,7 +118,7 @@ public class BlockLogic implements BlockInterface, IItemConvertible {
 
     @Override
     public @NotNull AABBdc getBounds() {
-        return this.bounds/*.AABB_copy()*/;
+        return this.bounds;
     }
 
     @Override
@@ -199,7 +199,7 @@ public class BlockLogic implements BlockInterface, IItemConvertible {
     public void animationTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand) { }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) { }
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) { }
 
     @Override
     public int tickDelay() {
@@ -483,7 +483,7 @@ public class BlockLogic implements BlockInterface, IItemConvertible {
 
     @Override
     public boolean isEquivalent(final @NotNull World world, final @NotNull TilePosc thisPos, final @NotNull TilePosc thatPos) {
-        final @Nullable Block<?> bBlock = world.getBlock(thatPos);
+        final @Nullable Block<?> bBlock = world.getBlockType(thatPos);
 
         final int thisMeta = world.getBlockData(thisPos);
         final int otherMeta = world.getBlockData(thatPos);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java
index 3d92fcdec..c273b10ea 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java
@@ -53,7 +53,7 @@ public class BlockLogicActivator
             final double pz = direction.getOffsetZ() * 0.6D + 0.5D;
 
             if (itemStack == null) {
-                final @Nullable Block<?> block = world.getBlock(tilePos.add(direction, new TilePos()));
+                final @Nullable Block<?> block = world.getBlockType(tilePos.add(direction, new TilePos()));
 
                 if (block != null) {
                     block.onActivatorInteracted(world, tilePos.add(direction, new TilePos()), activator, direction);
@@ -73,13 +73,13 @@ public class BlockLogicActivator
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final int meta = world.getBlockData(tilePos);
         final boolean hasSignal = this.getNeighborSignal(world, tilePos, BlockLogicRotatable.getDirectionFromMeta(meta));
         final boolean isPowered = (meta & MASK_POWERED) != 0;
 
         if (hasSignal && !isPowered) {
-            world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay());
+            world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay());
             world.setBlockDataNotify(tilePos, meta | MASK_POWERED);
         } else if (!hasSignal && isPowered) {
             world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED);
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
new file mode 100644
index 000000000..bc9aa1af8
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAir.java
@@ -0,0 +1,139 @@
+package net.minecraft.core.block;
+
+import net.minecraft.core.block.entity.TileEntity;
+import net.minecraft.core.block.material.Material;
+import net.minecraft.core.block.material.Materials;
+import net.minecraft.core.block.support.ISupport;
+import net.minecraft.core.block.support.PartialSupport;
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.enums.EnumDropCause;
+import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.util.phys.HitResult;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.WorldSource;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Vector3dc;
+import org.joml.primitives.AABBdc;
+
+import java.util.List;
+
+public class BlockLogicAir
+    extends BlockLogic {
+    public BlockLogicAir(final @NotNull Block<?> block) {
+        super(block, Materials.AIR);
+    }
+
+    @Override
+    public boolean isCubeShaped() {
+        return false;
+    }
+
+    @Override
+    public boolean canPlaceOnSurface() {
+        return false;
+    }
+
+    @Override
+    public boolean canPlaceOnSurfaceOnCondition(final @NotNull World world, final @NotNull TilePosc tilePos) {
+        return false;
+    }
+
+    @Override
+    public boolean renderAsNormalBlockOnCondition(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) {
+        return false;
+    }
+
+    @Override
+    public boolean canPlaceOnSurface(final @NotNull World world, final @NotNull TilePosc tilePos) {
+        return false;
+    }
+
+    @Override
+    public @NotNull ItemStack @Nullable [] getBreakResult(final @NotNull World world, final @NotNull EnumDropCause dropCause, final int data, final @Nullable TileEntity tileEntity) {
+        return null;
+    }
+
+    @Override
+    public @NotNull ItemStack @Nullable [] getBreakResult(final @NotNull World world, final @NotNull EnumDropCause dropCause, final @NotNull TilePosc tilePos, final int data, final @Nullable TileEntity tileEntity) {
+        return null;
+    }
+
+    @Override
+    public void getCollisionAABBs(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull AABBdc aabb, final @NotNull List<@NotNull AABBdc> aabbList) {
+        // Do nothing
+    }
+
+    @Override
+    public boolean collidesWithEntity(final @NotNull Entity entity, final @NotNull World world, final @NotNull TilePosc tilePos) {
+        return false;
+    }
+
+    @Override
+    public @Nullable AABBdc getCollisionAABB(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) {
+        return null;
+    }
+
+    @Override
+    public boolean isSolidRender() {
+        return false;
+    }
+
+    @Override
+    public boolean canCollideCheck(final int data, final boolean shouldCollideWithFluids) {
+        return false;
+    }
+
+    @Override
+    public boolean isCollidable() {
+        return false;
+    }
+
+    @Override
+    public float getStrength(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final @NotNull Player player) {
+        return 0.0f;
+    }
+
+    @Override
+    public boolean getImmovable() {
+        return false;
+    }
+
+    @Override
+    public float getBlastResistance(final @Nullable Entity entity) {
+        return 0.0f;
+    }
+
+    @Override
+    public @Nullable HitResult collisionRayTrace(final @NotNull World world, final @NotNull TilePosc tilePos, @NotNull final Vector3dc start, @NotNull final Vector3dc end, final boolean useSelectionAABB) {
+        return null;
+    }
+
+    @Override
+    public boolean canPlaceOnSide(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) {
+        return false;
+    }
+
+    @Override
+    public boolean canPlaceAt(final @NotNull World world, final @NotNull TilePosc tilePos) {
+        return false;
+    }
+
+    @Override
+    public void onHarvest(final @NotNull World world, final @NotNull Player player, final @NotNull TilePosc tilePos, final int data, final @Nullable TileEntity tileEntity) {
+        // Do nothing
+    }
+
+    @Override
+    public void dropWithCause(final @NotNull World world, final @NotNull EnumDropCause dropCause, final @NotNull TilePosc tilePos, final int data, final @Nullable TileEntity tileEntity, final @Nullable Player player) {
+        // Do nothing
+    }
+
+    @Override
+    public @NotNull ISupport getSupport(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) {
+        return PartialSupport.INSTANCE;
+    }
+}
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAlgae.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAlgae.java
index 2d12717ca..150e16702 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicAlgae.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAlgae.java
@@ -37,20 +37,20 @@ public class BlockLogicAlgae
     public void onEntityCollision(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Entity entity) {
         if (entity instanceof EntityBoat) {
             world.playBlockEvent(null, tilePos, LevelListener.EVENT_BLOCK_BREAK, this.block.id());
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
     @Override
     public boolean canPlaceAt(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        final int blockId = world.getBlockId(tilePos);
-        return blockId == 0 && Blocks.hasTag(world.getBlockId(tilePos.add(Direction.DOWN, new TilePos())), BlockTags.IS_WATER) && world.getBlockData(tilePos.add(Direction.DOWN, new TilePos())) == 0;
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        return block == Blocks.AIR && world.getBlockType(tilePos.add(Direction.DOWN, new TilePos())).hasTag(BlockTags.IS_WATER) && world.getBlockData(tilePos.add(Direction.DOWN, new TilePos())) == 0;
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
-        if (!Blocks.hasTag(world.getBlockId(tilePos.add(Direction.DOWN, new TilePos())), BlockTags.IS_WATER) || world.getBlockData(tilePos.add(Direction.DOWN, new TilePos())) != 0) {
-            world.setBlockId(tilePos, 0);
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        if (!world.getBlockType(tilePos.add(Direction.DOWN, new TilePos())).hasTag(BlockTags.IS_WATER) || world.getBlockData(tilePos.add(Direction.DOWN, new TilePos())) != 0) {
+            world.setBlockType(tilePos, Blocks.AIR);
         }
     }
 
@@ -99,9 +99,9 @@ public class BlockLogicAlgae
                 for (int j = 0; j < i / 16; j++) {
                     checkX += rand.nextInt(3) - 1;
                     checkZ += rand.nextInt(3) - 1;
-                    final int bId = world.getBlockId(queryPos.set(checkX, checkY - 1, checkZ));
+                    final @NotNull Block<?> block = world.getBlockType(queryPos.set(checkX, checkY - 1, checkZ));
                     final int bMeta = world.getBlockData(queryPos.set(checkX, checkY - 1, checkZ));
-                    if (bId != Blocks.FLUID_WATER_FLOWING.id() && bId != Blocks.FLUID_WATER_STILL.id()) {
+                    if (block != Blocks.FLUID_WATER_FLOWING && block != Blocks.FLUID_WATER_STILL) {
                         continue outer;
                     }
                     if (bMeta != 0) {
@@ -109,11 +109,11 @@ public class BlockLogicAlgae
                     }
                 }
 
-                if (world.getBlockId(queryPos.set(checkX, checkY, checkZ)) != 0) {
+                if (world.getBlockType(queryPos.set(checkX, checkY, checkZ)) != Blocks.AIR) {
                     continue;
                 }
                 if (rand.nextFloat() > 0.75) {
-                    world.setBlockIdNotify(queryPos.set(checkX, checkY, checkZ), this.block.id());
+                    world.setBlockTypeNotify(queryPos.set(checkX, checkY, checkZ), this.block);
                 }
             }
             return true;
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 62c083fdc..43067d9e0 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
@@ -93,7 +93,7 @@ public class BlockLogicBasket extends BlockLogic {
     public void onPlacedByWorld(final @NotNull World world, final @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
         for (final @NotNull Direction d : Direction.directions) {
-            world.notifyBlocksOfNeighborChange(tilePos.add(d, queryPos), this.id());
+            world.notifyBlocksOfNeighborChange(tilePos.add(d, queryPos), this.block);
         }
     }
 
@@ -101,7 +101,7 @@ public class BlockLogicBasket extends BlockLogic {
     public void onRemoved(final @NotNull World world, final @NotNull TilePosc tilePos, final int data) {
         TilePos queryPos = new TilePos();
         for (final @NotNull Direction d : Direction.directions) {
-            world.notifyBlocksOfNeighborChange(tilePos.add(d, queryPos), this.id());
+            world.notifyBlocksOfNeighborChange(tilePos.add(d, queryPos), this.block);
         }
     }
 
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 f77fe0923..8e88945a9 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
@@ -49,7 +49,7 @@ public class BlockLogicBed
 
         // Check if bed is not complete
         if (!isBlockHeadOfBed(data)) {
-            if (world.getBlock(footPos) != this.block) {
+            if (world.getBlockType(footPos) != this.block) {
                 return true;
             }
             data = world.getBlockData(tilePos);
@@ -57,9 +57,9 @@ public class BlockLogicBed
 
         // Explode in invalid dimensions
         if (!world.worldType.mayRespawn()) {
-            world.setBlockIdNotify(tilePos, 0);
-            if (world.getBlockId(footPos) == this.block.id()) {
-                world.setBlockIdNotify(footPos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
+            if (world.getBlockType(footPos) == this.block) {
+                world.setBlockTypeNotify(footPos, Blocks.AIR);
             }
             player.addStat(Achievements.SLEEP_NETHER, 1);
             world.createExplosion(null, tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F, 5F, true, false);
@@ -110,7 +110,7 @@ public class BlockLogicBed
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         this.removeOtherHalf(world, tilePos);
     }
 
@@ -123,11 +123,11 @@ public class BlockLogicBed
         final int data = world.getBlockData(tilePos);
         final int direction = getDirection(data);
         if (isBlockHeadOfBed(data)) {
-            if (world.getBlockId(tilePos.sub(headBlockToFootBlockMap[direction].getDirection(), new TilePos())) != this.block.id()) {
-                world.setBlockIdNotify(tilePos, 0);
+            if (world.getBlockType(tilePos.sub(headBlockToFootBlockMap[direction].getDirection(), new TilePos())) != this.block) {
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
             }
-        } else if (world.getBlockId(tilePos.add(headBlockToFootBlockMap[direction].getDirection(), new TilePos())) != this.block.id()) {
-            world.setBlockIdNotify(tilePos, 0);
+        } else if (world.getBlockType(tilePos.add(headBlockToFootBlockMap[direction].getDirection(), new TilePos())) != this.block) {
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBedrock.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBedrock.java
index b45fac098..166dc3ba5 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBedrock.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBedrock.java
@@ -16,7 +16,7 @@ public class BlockLogicBedrock
 
     @Override
     public void onPlacedByWorld(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        if (world.getBlock(tilePos.add(Direction.DOWN, new TilePos())) == Blocks.GLOWSTONE) {
+        if (world.getBlockType(tilePos.add(Direction.DOWN, new TilePos())) == Blocks.GLOWSTONE) {
             Blocks.PORTAL_DRIFT.getLogic().tryToCreatePortal(world, tilePos, DyeColor.SILVER);
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBrazier.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBrazier.java
index 277f90080..c70e4b011 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBrazier.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBrazier.java
@@ -63,20 +63,19 @@ public class BlockLogicBrazier
         final @Nullable ItemStack heldItem = player.getHeldItem();
         if (heldItem != null && heldItem.getItem() instanceof ItemFireStriker && !this.burning) {
             TilePos queryPos = new TilePos();
-            Block<?> b;
-            if ((b = world.getBlock(tilePos.add(Direction.EAST, queryPos))) != null && b.getLogic() instanceof BlockLogicFluid ||
-                (b = world.getBlock(tilePos.add(Direction.WEST, queryPos))) != null && b.getLogic() instanceof BlockLogicFluid ||
-                (b = world.getBlock(tilePos.add(Direction.SOUTH, queryPos))) != null && b.getLogic() instanceof BlockLogicFluid ||
-                (b = world.getBlock(tilePos.add(Direction.NORTH, queryPos))) != null && b.getLogic() instanceof BlockLogicFluid) {
+            if (world.getBlockType(tilePos.add(Direction.EAST, queryPos)).getLogic() instanceof BlockLogicFluid ||
+                world.getBlockType(tilePos.add(Direction.WEST, queryPos)).getLogic() instanceof BlockLogicFluid ||
+                world.getBlockType(tilePos.add(Direction.SOUTH, queryPos)).getLogic() instanceof BlockLogicFluid ||
+                world.getBlockType(tilePos.add(Direction.NORTH, queryPos)).getLogic() instanceof BlockLogicFluid) {
                 return false;
             }
-            world.setBlockIdDataNotify(tilePos, Blocks.BRAZIER_ACTIVE.id(), 0);
+            world.setBlockTypeNotify(tilePos, Blocks.BRAZIER_ACTIVE);
             heldItem.damageItem(1, player);
             world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, tilePos.x() + 0.5D, tilePos.y() + 0.5D, tilePos.z() + 0.5D, "fire.ignite", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
             return true;
         }
         if (heldItem == null && this.burning) {
-            world.setBlockIdDataNotify(tilePos, Blocks.BRAZIER_INACTIVE.id(), 0);
+            world.setBlockTypeNotify(tilePos, Blocks.BRAZIER_INACTIVE);
             return true;
         }
 
@@ -86,7 +85,7 @@ public class BlockLogicBrazier
     @Override
     public void onActivatorInteracted(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull TileEntityActivator activator, final @NotNull Direction direction) {
         if (this.burning) {
-            world.setBlockIdDataNotify(tilePos, Blocks.BRAZIER_INACTIVE.id(), 0);
+            world.setBlockTypeNotify(tilePos, Blocks.BRAZIER_INACTIVE);
         }
     }
 
@@ -98,11 +97,10 @@ public class BlockLogicBrazier
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!this.burning) return;
-        final @Nullable Block<?> block = Blocks.blocksList[id];
-        if (block != null && block.getLogic() instanceof BlockLogicFluid) {
-            world.setBlockIdDataNotify(tilePos, Blocks.BRAZIER_INACTIVE.id(), 0);
+        if (block.getLogic() instanceof BlockLogicFluid) {
+            world.setBlockTypeNotify(tilePos, Blocks.BRAZIER_INACTIVE);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java
index 6fbd9ad9e..100b70b02 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicButton.java
@@ -197,7 +197,7 @@ public class BlockLogicButton
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final boolean invalid;
         final int meta = world.getBlockData(tilePos);
         final int side = meta & MASK_DIRECTION;
@@ -212,7 +212,7 @@ public class BlockLogicButton
         };
         if (invalid) {
             this.dropWithCause(world, EnumDropCause.WORLD, tilePos, meta, null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -264,29 +264,29 @@ public class BlockLogicButton
         world.setBlockDataNotify(tilePos, (meta & ~MASK_DIRECTION) | direction | MASK_POWERED);
         world.markBlockDirty(tilePos);
         world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, tilePos.x() + 0.5D, tilePos.y() + 0.5D, tilePos.z() + 0.5D, "random.click", 0.3F, 0.6F);
-        world.notifyBlocksOfNeighborChange(tilePos, this.block.id());
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
 
         switch (direction) {
             case SIDE_WEST:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block);
                 break;
             case SIDE_EAST:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block);
                 break;
             case SIDE_NORTH:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block);
                 break;
             case SIDE_SOUTH:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block);
                 break;
             case SIDE_TOP:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block);
                 break;
             case SIDE_BOTTOM:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block);
                 break;
         }
-        world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay());
         return true;
     }
 
@@ -298,26 +298,26 @@ public class BlockLogicButton
     @Override
     public void onRemoved(final @NotNull World world, final @NotNull TilePosc tilePos, final int data) {
         if ((data & MASK_POWERED) != 0) {
-            world.notifyBlocksOfNeighborChange(tilePos, this.block.id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
             final int direction = data & MASK_DIRECTION;
             switch (direction) {
                 case SIDE_WEST:
-                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block.id());
+                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block);
                     break;
                 case SIDE_EAST:
-                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block.id());
+                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block);
                     break;
                 case SIDE_NORTH:
-                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block.id());
+                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block);
                     break;
                 case SIDE_SOUTH:
-                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block.id());
+                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block);
                     break;
                 case SIDE_TOP:
-                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block.id());
+                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block);
                     break;
                 case SIDE_BOTTOM:
-                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block.id());
+                    world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block);
                     break;
             }
         }
@@ -362,26 +362,26 @@ public class BlockLogicButton
             return;
         }
         world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED);
-        world.notifyBlocksOfNeighborChange(tilePos, this.block.id());
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
         final int direction = meta & MASK_DIRECTION;
         switch (direction) {
             case SIDE_WEST:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.WEST, new TilePos()), this.block);
                 break;
             case SIDE_EAST:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.EAST, new TilePos()), this.block);
                 break;
             case SIDE_NORTH:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.NORTH, new TilePos()), this.block);
                 break;
             case SIDE_SOUTH:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.SOUTH, new TilePos()), this.block);
                 break;
             case SIDE_TOP:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.UP, new TilePos()), this.block);
                 break;
             case SIDE_BOTTOM:
-                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.add(Direction.DOWN, new TilePos()), this.block);
                 break;
         }
 
@@ -397,11 +397,11 @@ public class BlockLogicButton
     @Override
     public void setColor(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull DyeColor color) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataRaw(tilePos, Blocks.BUTTON_PLANKS_PAINTED.id(), meta);
+        world.setBlockTypeDataRaw(tilePos, Blocks.BUTTON_PLANKS_PAINTED, meta);
         world.setBlockData(tilePos, meta);
         Blocks.BUTTON_PLANKS_PAINTED.getLogic().setColor(world, tilePos, color);
         if ((meta & MASK_POWERED) != 0) {
-            world.scheduleBlockUpdate(tilePos, Blocks.BUTTON_PLANKS_PAINTED.id(), this.tickDelay());
+            world.scheduleBlockUpdate(tilePos, Blocks.BUTTON_PLANKS_PAINTED, this.tickDelay());
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicButtonPainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicButtonPainted.java
index 333592202..b899abe2b 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicButtonPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicButtonPainted.java
@@ -47,7 +47,7 @@ public class BlockLogicButtonPainted
 
     @Override
     public void removeDye(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        world.setBlockIdNotify(tilePos, Blocks.BUTTON_PLANKS.id());
+        world.setBlockTypeNotify(tilePos, Blocks.BUTTON_PLANKS);
     }
 
     @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 94fe358bf..2b27ba2b2 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
@@ -37,7 +37,7 @@ public class BlockLogicCactus
 
     @Override
     public void onPlacedByWorld(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        this.onNeighborChanged(world, tilePos, 0);
+        this.onNeighborChanged(world, tilePos, Blocks.AIR);
     }
 
     @Override
@@ -46,13 +46,13 @@ public class BlockLogicCactus
         if (world.isAirBlock(tilePos.add(Direction.UP, queryPos))) {
             int cactusHeight;
             cactusHeight = 1;
-            while (world.getBlockId(tilePos.sub(0, cactusHeight, 0, queryPos)) == this.block.id()) {
+            while (world.getBlockType(tilePos.sub(0, cactusHeight, 0, queryPos)) == this.block) {
                 cactusHeight++;
             }
             if (cactusHeight < 3) {
                 final int data = world.getBlockData(tilePos);
                 if (data == 15) {
-                    world.setBlockIdNotify(tilePos.add(Direction.UP, queryPos), this.block.id());
+                    world.setBlockTypeNotify(tilePos.add(Direction.UP, queryPos), this.block);
                     world.setBlockDataNotify(tilePos, 0);
                 } else {
                     world.setBlockDataNotify(tilePos, data + 1);
@@ -64,11 +64,13 @@ public class BlockLogicCactus
     private void growCactusOnTop(final @NotNull World world, final @NotNull TilePosc tilePos) {
         final @NotNull TilePos offsetPos = new TilePos(tilePos);
 
-        for (offsetPos.y = tilePos.y() + 1; world.getBlockId(offsetPos) == this.block.id(); offsetPos.y++) {
+        offsetPos.y = tilePos.y() + 1;
+        while (world.getBlockType(offsetPos) == this.block) {
+            offsetPos.y++;
         }
 
         if (world.isAirBlock(offsetPos)) {
-            world.setBlockIdNotify(offsetPos, this.block.id());
+            world.setBlockTypeNotify(offsetPos, this.block);
         }
     }
 
@@ -101,10 +103,10 @@ public class BlockLogicCactus
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!this.canStay(world, tilePos)) {
             this.dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -123,8 +125,7 @@ public class BlockLogicCactus
         if (world.getBlockMaterial(tilePos.add(Direction.SOUTH, queryPos)).isSolid()) {
             return false;
         } else {
-            final int idDown = world.getBlockId(tilePos.add(Direction.DOWN, queryPos));
-            return Blocks.hasTag(idDown, BlockTags.GROWS_CACTI);
+            return world.getBlockType(tilePos.add(Direction.DOWN, queryPos)).hasTag(BlockTags.GROWS_CACTI);
         }
     }
 
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 3f8cca862..fc75af867 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
@@ -236,21 +236,21 @@ public class BlockLogicChest
             return;
         }
         TilePos queryPos = new TilePos();
-        final int bN = world.getBlockId(tilePos.north(queryPos));
-        final int bS = world.getBlockId(tilePos.south(queryPos));
-        final int bW = world.getBlockId(tilePos.west(queryPos));
-        final int bE = world.getBlockId(tilePos.east(queryPos));
+        final @NotNull Block<?> bN = world.getBlockType(tilePos.north(queryPos));
+        final @NotNull Block<?> bS = world.getBlockType(tilePos.south(queryPos));
+        final @NotNull Block<?> bW = world.getBlockType(tilePos.west(queryPos));
+        final @NotNull Block<?> bE = world.getBlockType(tilePos.east(queryPos));
         @NotNull Direction direction = Direction.NORTH;
-        if (Blocks.solid[bN] && !Blocks.solid[bS]) {
+        if (bN.solid() && !bS.solid()) {
             direction = Direction.SOUTH;
         }
-        if (Blocks.solid[bS] && !Blocks.solid[bN]) {
+        if (bS.solid() && !bN.solid()) {
             direction = Direction.NORTH;
         }
-        if (Blocks.solid[bW] && !Blocks.solid[bE]) {
+        if (bW.solid() && !bE.solid()) {
             direction = Direction.EAST;
         }
-        if (Blocks.solid[bE] && !Blocks.solid[bW]) {
+        if (bE.solid() && !bW.solid()) {
             direction = Direction.WEST;
         }
 
@@ -258,14 +258,13 @@ public class BlockLogicChest
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
-        super.onNeighborChanged(world, tilePos, id);
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        super.onNeighborChanged(world, tilePos, block);
         this.checkIfOtherHalfExists(world, tilePos);
     }
 
     public static boolean isChest(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> b = world.getBlock(tilePos);
-        return b != null && b.getLogic() instanceof BlockLogicChest;
+        return world.getBlockType(tilePos).getLogic() instanceof BlockLogicChest;
     }
 
     public static boolean isSingleChest(final @NotNull World world, final @NotNull TilePos tilePos) {
@@ -401,7 +400,7 @@ public class BlockLogicChest
     @Override
     public void setColor(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull DyeColor color) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataRaw(tilePos, Blocks.CHEST_PLANKS_OAK_PAINTED.id(), meta);
+        world.setBlockTypeDataRaw(tilePos, Blocks.CHEST_PLANKS_OAK_PAINTED, meta);
         world.setBlockData(tilePos, meta);
         Blocks.CHEST_PLANKS_OAK_PAINTED.getLogic().setColor(world, tilePos, color);
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestLegacy.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestLegacy.java
index 8f4b5120e..a8bf7b2d0 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestLegacy.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestLegacy.java
@@ -35,7 +35,7 @@ public class BlockLogicChestLegacy
     }
 
     public static boolean isLegacyChest(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = world.getBlock(tilePos);
+        final @Nullable Block<?> block = world.getBlockType(tilePos);
         return block == Blocks.CHEST_LEGACY || block == Blocks.CHEST_LEGACY_PAINTED;
     }
 
@@ -58,7 +58,7 @@ public class BlockLogicChestLegacy
             this.updateLegacyChest(world, tilePos);
         }
 
-        return Objects.requireNonNull(world.getBlock(tilePos)).onInteracted(world, tilePos, player, side, xHit, yHit);
+        return Objects.requireNonNull(world.getBlockType(tilePos)).onInteracted(world, tilePos, player, side, xHit, yHit);
     }
 
     private void updateLegacyChest(final @NotNull World world, final @NotNull TilePosc tilePos) {
@@ -210,7 +210,7 @@ public class BlockLogicChestLegacy
         }
         final int legacyChestMeta = world.getBlockData(tilePos);
 
-        final @Nullable Block<?> oldBlock = world.getBlock(tilePos);
+        final @Nullable Block<?> oldBlock = world.getBlockType(tilePos);
         @NotNull Block<?> newBlock = Blocks.CHEST_PLANKS_OAK;
 
         if (oldBlock == Blocks.CHEST_LEGACY_PAINTED) {
@@ -218,7 +218,7 @@ public class BlockLogicChestLegacy
             newMeta = newMeta | (legacyChestMeta << 4);
         }
 
-        world.setBlockIdData(tilePos, newBlock.id(), newMeta);
+        world.setBlockTypeData(tilePos, newBlock, newMeta);
         world.markBlockNeedsUpdate(tilePos);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestPainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestPainted.java
index f36307806..96902d915 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChestPainted.java
@@ -51,7 +51,7 @@ public class BlockLogicChestPainted
     @Override
     public void removeDye(final @NotNull World world, final @NotNull TilePosc tilePos) {
         final int meta = this.stripColorFromMetadata(world.getBlockData(tilePos));
-        world.setBlockIdDataNotify(tilePos, Blocks.CHEST_PLANKS_OAK.id(), meta);
+        world.setBlockTypeDataNotify(tilePos, Blocks.CHEST_PLANKS_OAK, meta);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsPumpkin.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsPumpkin.java
index fd7614437..e042cb912 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsPumpkin.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsPumpkin.java
@@ -46,8 +46,8 @@ public class BlockLogicCropsPumpkin
     }
 
     @Override
-    protected boolean mayPlaceOn(final int blockId) {
-        return blockId == Blocks.FARMLAND_DIRT.id();
+    protected boolean mayPlaceOn(final @NotNull Block<?> block) {
+        return block == Blocks.FARMLAND_DIRT;
     }
 
     @Override
@@ -60,7 +60,7 @@ public class BlockLogicCropsPumpkin
                 if (rand.nextInt((int) (100F / f)) == 0) {
                     meta++;
                     if (meta == 5) {
-                        world.setBlockIdDataNotify(tilePos, Blocks.PUMPKIN.id(), 0);
+                        world.setBlockTypeNotify(tilePos, Blocks.PUMPKIN);
                     } else {
                         world.setBlockDataNotify(tilePos, meta);
                     }
@@ -75,9 +75,9 @@ public class BlockLogicCropsPumpkin
         final @NotNull TilePos queryPos = new TilePos();
         for (localPos.x = tilePos.x() - 1; localPos.x <= tilePos.x() + 1; localPos.x++) {
             for (localPos.z = tilePos.z() - 1; localPos.z <= tilePos.z() + 1; localPos.z++) {
-                final int id = world.getBlockId(localPos.down(queryPos));
+                final @NotNull Block<?> block = world.getBlockType(localPos.down(queryPos));
                 float growthRateMod = 0.0F;
-                if (id == Blocks.FARMLAND_DIRT.id()) {
+                if (block == Blocks.FARMLAND_DIRT) {
                     growthRateMod = 1.0F;
                     if (world.getBlockData(localPos.down(queryPos)) > 0) {
                         growthRateMod = 3F;
@@ -120,7 +120,7 @@ public class BlockLogicCropsPumpkin
     public boolean onBonemealUsed(final @NotNull ItemStack itemStack, final @Nullable Player player, final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side, final double xHit, final double yHit) {
         if (world.getBlockData(tilePos) < 5) {
             if (!world.isClientSide) {
-                world.setBlockIdNotify(tilePos, Blocks.PUMPKIN.id());
+                world.setBlockTypeNotify(tilePos, Blocks.PUMPKIN);
                 if (player == null || player.getGamemode().hasBlockConsumption()) {
                     itemStack.stackSize--;
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsWheat.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsWheat.java
index ffb87b722..9b2fdfbd6 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsWheat.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicCropsWheat.java
@@ -28,8 +28,8 @@ public class BlockLogicCropsWheat extends BlockLogicFlower implements IBonemeala
     }
 
     @Override
-    public boolean mayPlaceOn(final int blockId) {
-        return blockId == Blocks.FARMLAND_DIRT.id();
+    public boolean mayPlaceOn(final @NotNull Block<?> block) {
+        return block == Blocks.FARMLAND_DIRT;
     }
 
     @Override
@@ -49,24 +49,24 @@ public class BlockLogicCropsWheat extends BlockLogicFlower implements IBonemeala
     private float getGrowthRate(final @NotNull World world, final @NotNull TilePosc tilePos) {
         float growthRate = 1.0F;
         TilePos queryPos = new TilePos();
-        final int idNegZ = world.getBlockId(tilePos.north(queryPos));
-        final int idPosZ = world.getBlockId(tilePos.south(queryPos));
-        final int idNegX = world.getBlockId(tilePos.west(queryPos));
-        final int idPosX = world.getBlockId(tilePos.east(queryPos));
-        final int idNegXNegZ = world.getBlockId(tilePos.west(queryPos).north(queryPos));
-        final int idPosXNegZ = world.getBlockId(tilePos.east(queryPos).north(queryPos));
-        final int idPosXPosZ = world.getBlockId(tilePos.east(queryPos).south(queryPos));
-        final int idNegXPosZ = world.getBlockId(tilePos.west(queryPos).south(queryPos));
-        final boolean xNeighbor = idNegX == this.block.id() || idPosX == this.block.id();
-        final boolean zNeighbor = idNegZ == this.block.id() || idPosZ == this.block.id();
-        final boolean diagNeighbor = idNegXNegZ == this.block.id() || idPosXNegZ == this.block.id() || idPosXPosZ == this.block.id() || idNegXPosZ == this.block.id();
+        final @NotNull Block<?> bNegZ = world.getBlockType(tilePos.north(queryPos));
+        final @NotNull Block<?> bPosZ = world.getBlockType(tilePos.south(queryPos));
+        final @NotNull Block<?> bNegX = world.getBlockType(tilePos.west(queryPos));
+        final @NotNull Block<?> bPosX = world.getBlockType(tilePos.east(queryPos));
+        final @NotNull Block<?> bNegXNegZ = world.getBlockType(tilePos.west(queryPos).north(queryPos));
+        final @NotNull Block<?> bPosXNegZ = world.getBlockType(tilePos.east(queryPos).north(queryPos));
+        final @NotNull Block<?> bPosXPosZ = world.getBlockType(tilePos.east(queryPos).south(queryPos));
+        final @NotNull Block<?> bNegXPosZ = world.getBlockType(tilePos.west(queryPos).south(queryPos));
+        final boolean xNeighbor = bNegX == this.block || bPosX == this.block;
+        final boolean zNeighbor = bNegZ == this.block || bPosZ == this.block;
+        final boolean diagNeighbor = bNegXNegZ == this.block || bPosXNegZ == this.block || bPosXPosZ == this.block || bNegXPosZ == this.block;
 
         final @NotNull TilePos localPos = new TilePos(tilePos);
         for (localPos.x = tilePos.x() - 1; localPos.x <= tilePos.x() + 1; localPos.x++) {
             for (localPos.z = tilePos.z() - 1; localPos.z <= tilePos.z() + 1; localPos.z++) {
-                final int id = world.getBlockId(tilePos.down(queryPos));
+                final @NotNull Block<?> block = world.getBlockType(tilePos.down(queryPos));
                 float growthRateMod = 0.0F;
-                if (id == Blocks.FARMLAND_DIRT.id()) {
+                if (block == Blocks.FARMLAND_DIRT) {
                     growthRateMod = 1.0F;
                     if (world.getBlockData(tilePos.down(queryPos)) > 0) {
                         growthRateMod = 3F;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDeadBush.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDeadBush.java
index 9e0fa5e35..b49b765ca 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDeadBush.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDeadBush.java
@@ -18,8 +18,8 @@ public class BlockLogicDeadBush extends BlockLogicFlower {
     }
 
     @Override
-    public boolean mayPlaceOn(final int blockId) {
-        return blockId == Blocks.SAND.id() || blockId == Blocks.DIRT_SCORCHED.id() || BlockTags.GROWS_FLOWERS.appliesTo(Blocks.getBlock(blockId));
+    public boolean mayPlaceOn(final @NotNull Block<?> block) {
+        return block == Blocks.SAND || block == Blocks.DIRT_SCORCHED || block.hasTag(BlockTags.GROWS_FLOWERS);
     }
 
     @Override
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 0f35de874..324e4c224 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
@@ -93,11 +93,11 @@ public class BlockLogicDispenser extends BlockLogicVeryRotatable {
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final boolean hasNeighborSignal = world.hasNeighborSignal(tilePos);
         final int data = world.getBlockData(tilePos);
         if (hasNeighborSignal && (data & MASK_POWERED) == 0) {
-            world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay());
+            world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay());
             world.setBlockData(tilePos, data | MASK_POWERED);
         } else if (!hasNeighborSignal) {
             world.setBlockData(tilePos, data & ~MASK_POWERED);
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 41db209ef..c7cb0675a 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
@@ -136,13 +136,13 @@ public class BlockLogicDoor
         TilePos queryPos = new TilePos();
         final int data = world.getBlockData(tilePos);
         if (this.isTop) {
-            final Block<?> b = world.getBlock(tilePos.down(queryPos));
+            final Block<?> b = world.getBlockType(tilePos.down(queryPos));
             if (b != null && b.getLogic() instanceof BlockLogicDoor blockLogicDoor) {
                 blockLogicDoor.onInteracted(world, tilePos.down(queryPos), player, side, xHit, yHit);
             }
             return true;
         }
-        final @Nullable Block<?> b = world.getBlock(tilePos.up(queryPos));
+        final @Nullable Block<?> b = world.getBlockType(tilePos.up(queryPos));
         if (b != null && b.getLogic() instanceof BlockLogicDoor) {
             world.setBlockDataNotify(tilePos.up(queryPos), data ^ MASK_OPENED);
         }
@@ -150,9 +150,9 @@ public class BlockLogicDoor
         world.setBlockDataNotify(tilePos, openedData);
         if (!this.isSupported(world, tilePos, openedData)) {
             this.dropWithCause(world, EnumDropCause.WORLD, tilePos, openedData, null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
             if (world.getBlockLogic(tilePos.up(queryPos), BlockLogicDoor.class) != null) {
-                world.setBlockIdNotify(tilePos.up(queryPos), 0);
+                world.setBlockTypeNotify(tilePos.up(queryPos), Blocks.AIR);
             }
         }
         world.markBlocksDirty(tilePos.down(queryPos), tilePos);
@@ -174,7 +174,7 @@ public class BlockLogicDoor
 
         TilePos queryPos = new TilePos();
         if (this.isTop) {
-            final @Nullable Block<?> b = world.getBlock(tilePos.down(queryPos));
+            final @Nullable Block<?> b = world.getBlockType(tilePos.down(queryPos));
             if (b != null && b.getLogic() instanceof BlockLogicDoor) {
                 ((BlockLogicDoor) b.getLogic()).onPoweredBlockChange(world, tilePos.down(queryPos), isPowered);
             }
@@ -184,7 +184,7 @@ public class BlockLogicDoor
         if (isOpen == isPowered) {
             return;
         }
-        final @Nullable Block<?> b = world.getBlock(tilePos.up(queryPos));
+        final @Nullable Block<?> b = world.getBlockType(tilePos.up(queryPos));
         if (b != null && b.getLogic() instanceof BlockLogicDoor) {
             world.setBlockDataNotify(tilePos.up(queryPos), data ^ MASK_OPENED);
         }
@@ -194,35 +194,34 @@ public class BlockLogicDoor
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final int data = world.getBlockData(tilePos);
-        final @Nullable Block<?> neighbor = Blocks.getBlock(id);
 
         TilePos queryPos = new TilePos();
         if (this.isTop) {
-            final @Nullable Block<?> b = world.getBlock(tilePos.down(queryPos));
-            if (!(b != null && b.getLogic() instanceof BlockLogicDoor)) {
-                world.setBlockIdNotify(tilePos, 0);
+            final @NotNull Block<?> b = world.getBlockType(tilePos.down(queryPos));
+            if (!(b.getLogic() instanceof BlockLogicDoor)) {
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
             }
-            if (b != null && neighbor != null && neighbor.isSignalSource()) {
-                b.onNeighborChanged(world, tilePos.down(queryPos), id);
+            if (block.isSignalSource()) {
+                b.onNeighborChanged(world, tilePos.down(queryPos), b);
             }
         } else {
             boolean hasCommittedSuicide = false;
-            final @Nullable Block<?> otherBlock = world.getBlock(tilePos.up(queryPos));
-            if (!(otherBlock != null && otherBlock.getLogic() instanceof BlockLogicDoor)) {
-                world.setBlockIdNotify(tilePos, 0);
+            final @NotNull Block<?> otherBlock = world.getBlockType(tilePos.up(queryPos));
+            if (!(otherBlock.getLogic() instanceof BlockLogicDoor)) {
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
                 hasCommittedSuicide = true;
             }
             if (!this.isSupported(world, tilePos, data)) {
                 this.dropWithCause(world, EnumDropCause.WORLD, tilePos, data, null, null);
-                world.setBlockIdNotify(tilePos, 0);
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
                 hasCommittedSuicide = true;
-                if (otherBlock != null && otherBlock.getLogic() instanceof BlockLogicDoor) {
-                    world.setBlockIdNotify(tilePos.up(queryPos), 0);
+                if (otherBlock.getLogic() instanceof BlockLogicDoor) {
+                    world.setBlockTypeNotify(tilePos.up(queryPos), Blocks.AIR);
                 }
             }
-            if (!hasCommittedSuicide && neighbor != null && neighbor.isSignalSource()) {
+            if (!hasCommittedSuicide && block.isSignalSource()) {
                 final boolean hasSignal = world.hasNeighborSignal(tilePos) || world.hasNeighborSignal(tilePos.up(queryPos));
                 this.onPoweredBlockChange(world, tilePos, hasSignal);
             }
@@ -234,11 +233,11 @@ public class BlockLogicDoor
         TilePos queryPos = new TilePos();
         if (this.isTop) {
             if (world.getBlockLogic(tilePos.down(queryPos), BlockLogicDoor.class) != null) {
-                world.setBlockIdNotify(tilePos.down(queryPos), 0);
+                world.setBlockTypeNotify(tilePos.down(queryPos), Blocks.AIR);
             }
         } else {
             if (world.getBlockLogic(tilePos.up(queryPos), BlockLogicDoor.class) != null) {
-                world.setBlockIdNotify(tilePos.up(queryPos), 0);
+                world.setBlockTypeNotify(tilePos.up(queryPos), Blocks.AIR);
             }
         }
     }
@@ -412,14 +411,14 @@ public class BlockLogicDoor
         TilePos queryPos = new TilePos();
         final int data = world.getBlockData(tilePos);
         if (this.isTop) {
-            world.setBlockIdDataRaw(tilePos, Blocks.DOOR_PLANKS_PAINTED_TOP.id(), data);
+            world.setBlockTypeDataRaw(tilePos, Blocks.DOOR_PLANKS_PAINTED_TOP, data);
             Blocks.DOOR_PLANKS_PAINTED_TOP.getLogic().setColor(world, tilePos, color);
-            world.setBlockIdDataRaw(tilePos.down(queryPos), Blocks.DOOR_PLANKS_PAINTED_BOTTOM.id(), data);
+            world.setBlockTypeDataRaw(tilePos.down(queryPos), Blocks.DOOR_PLANKS_PAINTED_BOTTOM, data);
             Blocks.DOOR_PLANKS_PAINTED_BOTTOM.getLogic().setColor(world, tilePos.down(queryPos), color);
         } else {
-            world.setBlockIdDataRaw(tilePos, Blocks.DOOR_PLANKS_PAINTED_BOTTOM.id(), data);
+            world.setBlockTypeDataRaw(tilePos, Blocks.DOOR_PLANKS_PAINTED_BOTTOM, data);
             Blocks.DOOR_PLANKS_PAINTED_BOTTOM.getLogic().setColor(world, tilePos, color);
-            world.setBlockIdDataRaw(tilePos.up(queryPos), Blocks.DOOR_PLANKS_PAINTED_TOP.id(), data);
+            world.setBlockTypeDataRaw(tilePos.up(queryPos), Blocks.DOOR_PLANKS_PAINTED_TOP, data);
             Blocks.DOOR_PLANKS_PAINTED_TOP.getLogic().setColor(world, tilePos.up(queryPos), color);
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoorPainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoorPainted.java
index 46654d5ca..84b830ae8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoorPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicDoorPainted.java
@@ -42,11 +42,11 @@ public class BlockLogicDoorPainted
     @Override
     public void removeDye(final @NotNull World world, final @NotNull TilePosc tilePos) {
         final int data = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, this.isTop ? Blocks.DOOR_PLANKS_OAK_TOP.id() : Blocks.DOOR_PLANKS_OAK_BOTTOM.id(), data & 0xF);
+        world.setBlockTypeDataNotify(tilePos, this.isTop ? Blocks.DOOR_PLANKS_OAK_TOP : Blocks.DOOR_PLANKS_OAK_BOTTOM, data & 0xF);
         if (this.isTop) {
-            world.setBlockIdDataNotify(tilePos.down(new TilePos()), Blocks.DOOR_PLANKS_OAK_BOTTOM.id(), data & 0xF);
+            world.setBlockTypeDataNotify(tilePos.down(new TilePos()), Blocks.DOOR_PLANKS_OAK_BOTTOM, data & 0xF);
         } else {
-            world.setBlockIdDataNotify(tilePos.up(new TilePos()), Blocks.DOOR_PLANKS_OAK_TOP.id(), data & 0xF);
+            world.setBlockTypeDataNotify(tilePos.up(new TilePos()), Blocks.DOOR_PLANKS_OAK_TOP, data & 0xF);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicEdible.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicEdible.java
index 54e75a7ac..3da2eec24 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicEdible.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicEdible.java
@@ -58,7 +58,7 @@ public abstract class BlockLogicEdible
             player.heal(this.getHealAmount(world, tilePos));
             final int data = world.getBlockData(tilePos) + 1;
             if (data >= this.maxBites) {
-                world.setBlockIdNotify(tilePos, 0);
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
             } else {
                 world.setBlockDataNotify(tilePos, data);
                 world.markBlockDirty(tilePos);
@@ -93,9 +93,9 @@ public abstract class BlockLogicEdible
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!this.canStay(world, tilePos)) {
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
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 522ed5823..2f534c8e2 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
@@ -105,7 +105,7 @@ public class BlockLogicFarmland
         final @NotNull TilePos localPos = new TilePos(tilePos);
         for (localPos.x = tilePos.x() - radius; localPos.x <= tilePos.x() + radius; localPos.x++) {
             for (localPos.z = tilePos.z() - radius; localPos.z <= tilePos.z() + radius; localPos.z++) {
-                if (world.getBlockId(localPos.set(localPos.x, tilePos.y() + 1, localPos.z)) == Blocks.CROPS_WHEAT.id()) {
+                if (world.getBlockType(localPos.set(localPos.x, tilePos.y() + 1, localPos.z)) == Blocks.CROPS_WHEAT) {
                     return true;
                 }
             }
@@ -130,7 +130,7 @@ public class BlockLogicFarmland
         for (localPos.x = tilePos.x() - range; localPos.x <= tilePos.x() + range; localPos.x++) {
             for (localPos.y = tilePos.y() - range; localPos.y <= tilePos.y() + range; localPos.y++) {
                 for (localPos.z = tilePos.z() - range; localPos.z <= tilePos.z() + range; localPos.z++) {
-                    if (Blocks.hasTag(world.getBlockId(localPos), BlockTags.IS_WATER)) {
+                    if (world.getBlockType(localPos).hasTag(BlockTags.IS_WATER)) {
                         return true;
                     }
                 }
@@ -149,9 +149,9 @@ public class BlockLogicFarmland
                     return;
                 }
                 if (isWet(world.getBlockData(tilePos))) {
-                    world.setBlockIdNotify(tilePos, Blocks.MUD.id());
+                    world.setBlockTypeNotify(tilePos, Blocks.MUD);
                 } else {
-                    world.setBlockIdNotify(tilePos, Blocks.DIRT.id());
+                    world.setBlockTypeNotify(tilePos, Blocks.DIRT);
                 }
             }
         }
@@ -159,20 +159,20 @@ public class BlockLogicFarmland
 
     @Override
     public void onPlacedByWorld(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay() - world.rand.nextInt(10) + world.rand.nextInt(10));
+        world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay() - world.rand.nextInt(10) + world.rand.nextInt(10));
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final @NotNull Material material = world.getBlockMaterial(tilePos.up(new TilePos()));
         if (material.isSolid() && material != Materials.VEGETABLE) {
             if (isWet(world.getBlockData(tilePos))) {
-                world.setBlockIdNotify(tilePos, Blocks.MUD.id());
+                world.setBlockTypeNotify(tilePos, Blocks.MUD);
             } else {
-                world.setBlockIdNotify(tilePos, Blocks.DIRT.id());
+                world.setBlockTypeNotify(tilePos, Blocks.DIRT);
             }
         } else {
-            world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay() - world.rand.nextInt(10) + world.rand.nextInt(10));
+            world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay() - world.rand.nextInt(10) + world.rand.nextInt(10));
         }
     }
 
@@ -188,8 +188,8 @@ public class BlockLogicFarmland
                 for (localPos.y = tilePos.y() - 1; localPos.y <= tilePos.y() + 1; localPos.y++) {
                     for (localPos.z = tilePos.z() - 1; localPos.z <= tilePos.z() + 1; localPos.z++) {
                         //...And the block is next to another wet mud block, it can become wet
-                        final int bID = world.getBlockId(localPos);
-                        if (bID == Blocks.MUD.id() || (bID == Blocks.FARMLAND_DIRT.id() && BlockLogicFarmland.isWet(world.getBlockData(localPos)))) {
+                        final @NotNull Block<?> block = world.getBlockType(localPos);
+                        if (block == Blocks.MUD || (block == Blocks.FARMLAND_DIRT && BlockLogicFarmland.isWet(world.getBlockData(localPos)))) {
                             return true;
                         }
                     }
@@ -209,7 +209,7 @@ public class BlockLogicFarmland
     @Override
     public void updateTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand, final boolean isRandomTick) {
         if (rand.nextInt(2) != 0) {
-            world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay() - rand.nextInt(10) + rand.nextInt(10));
+            world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay() - rand.nextInt(10) + rand.nextInt(10));
             return;
         }
         final int data = world.getBlockData(tilePos);
@@ -217,14 +217,14 @@ public class BlockLogicFarmland
         if (this.isWaterNearby(world, tilePos, 4) || world.isBlockBeingRainedOn(tilePos.up(new TilePos()))) {
             if (hydration < 15 && this.canBecomeWet(world, tilePos)) {
                 world.setBlockDataNotify(tilePos, setWet(data, hydration + 1));
-                world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay() - rand.nextInt(10) + rand.nextInt(10));
+                world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay() - rand.nextInt(10) + rand.nextInt(10));
             }
         } else {
             if (hydration > 0) {
                 world.setBlockDataNotify(tilePos, setWet(data, hydration - 1));
-                world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay() - rand.nextInt(10) + rand.nextInt(10));
+                world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay() - rand.nextInt(10) + rand.nextInt(10));
             } else if (!this.isCropsNearby(world, tilePos)) {
-                world.setBlockIdNotify(tilePos, Blocks.DIRT.id());
+                world.setBlockTypeNotify(tilePos, Blocks.DIRT);
             }
         }
     }
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 7fba10c2d..9df34cb76 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
@@ -89,8 +89,8 @@ public class BlockLogicFence
 
     public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) {
         TilePos queryPos = new TilePos();
-        final Block<?> b = source.getBlock(tilePos.add(side.getDirection(), queryPos));
-        return Blocks.hasTag(b, BlockTags.FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite());
+        final @NotNull Block<?> b = source.getBlockType(tilePos.add(side.getDirection(), queryPos));
+        return Blocks.hasTag(b, BlockTags.FENCES_CONNECT) || b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite();
     }
 
     @Deprecated
@@ -100,7 +100,7 @@ public class BlockLogicFence
 
     @Override
     public void setColor(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull DyeColor color) {
-        world.setBlockId(tilePos, Blocks.FENCE_PLANKS_OAK_PAINTED.id());
+        world.setBlockType(tilePos, Blocks.FENCE_PLANKS_OAK_PAINTED);
         Blocks.FENCE_PLANKS_OAK_PAINTED.getLogic().setColor(world, tilePos, color);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java
index 8d43bf7ea..072597a2c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceChainlink.java
@@ -18,7 +18,7 @@ public class BlockLogicFenceChainlink extends BlockLogicFenceThin {
     @Override
     public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) {
         TilePos queryPos = new TilePos();
-        final @Nullable Block<?> b = source.getBlock(tilePos.add(side.getDirection(), queryPos));
+        final @Nullable Block<?> b = source.getBlockType(tilePos.add(side.getDirection(), queryPos));
         return Blocks.hasTag(b, BlockTags.CHAINLINK_FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite());
     }
 
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 4072c74cd..c74ebaa0f 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
@@ -119,7 +119,7 @@ public class BlockLogicFenceGate
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final int data = world.getBlockData(tilePos);
         final boolean wasPowered = isPowered(data);
         final boolean hasPower = world.hasNeighborSignal(tilePos) || world.hasDirectSignal(tilePos);
@@ -151,7 +151,7 @@ public class BlockLogicFenceGate
 
     @Override
     public void setColor(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull DyeColor color) {
-        world.setBlockIdDataNotify(tilePos, Blocks.FENCE_GATE_PLANKS_OAK_PAINTED.id(), world.getBlockData(tilePos));
+        world.setBlockTypeDataNotify(tilePos, Blocks.FENCE_GATE_PLANKS_OAK_PAINTED, world.getBlockData(tilePos));
         Blocks.FENCE_GATE_PLANKS_OAK_PAINTED.getLogic().setColor(world, tilePos, color);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGatePainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGatePainted.java
index f280a126d..9e52ed8c7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGatePainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceGatePainted.java
@@ -46,7 +46,7 @@ public class BlockLogicFenceGatePainted extends BlockLogicFenceGate implements I
     @Override
     public void removeDye(final @NotNull World world, final @NotNull TilePosc tilePos) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, Blocks.FENCE_GATE_PLANKS_OAK.id(), meta & ~MASK_COLOR);
+        world.setBlockTypeDataNotify(tilePos, Blocks.FENCE_GATE_PLANKS_OAK, meta & ~MASK_COLOR);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFencePainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFencePainted.java
index 9b3700013..d8a7f1ae4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFencePainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFencePainted.java
@@ -43,7 +43,7 @@ public class BlockLogicFencePainted extends BlockLogicFence implements IPainted
 
     @Override
     public void removeDye(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        world.setBlockIdNotify(tilePos, Blocks.FENCE_PLANKS_OAK.id());
+        world.setBlockTypeNotify(tilePos, Blocks.FENCE_PLANKS_OAK);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java
index 30c787238..1493510e1 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceSteel.java
@@ -18,7 +18,7 @@ public class BlockLogicFenceSteel
     @Override
     public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) {
         TilePos queryPos = new TilePos();
-        final @Nullable Block<?> b = source.getBlock(tilePos.add(side.getDirection(), queryPos));
+        final @Nullable Block<?> b = source.getBlockType(tilePos.add(side.getDirection(), queryPos));
         return Blocks.hasTag(b, BlockTags.CHAINLINK_FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite());
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java
index 4629a5fb3..14058f6be 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceThin.java
@@ -100,13 +100,13 @@ public abstract class BlockLogicFenceThin
 
         TilePos queryPos = new TilePos();
         int oy = 1;
-        while (source.getBlockId(tilePos.add(0, oy, 0, queryPos)) == this.block.id()) {
+        while (source.getBlockType(tilePos.add(0, oy, 0, queryPos)) == this.block) {
             oy++;
         }
         oy--;
 
         boolean drawColumnFromOther = false;
-        while (source.getBlockId(tilePos.add(0, oy, 0, queryPos)) == this.block.id()) {
+        while (source.getBlockType(tilePos.add(0, oy, 0, queryPos)) == this.block) {
             if (this.shouldDrawColumn_do(source, tilePos.add(0, oy, 0, queryPos))) {
                 drawColumnFromOther = true;
                 break;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java
index 83afe05c4..a4c258f97 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFenceWallPaper.java
@@ -18,7 +18,7 @@ public class BlockLogicFenceWallPaper
     @Override
     public boolean canConnectTo(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) {
         TilePos queryPos = new TilePos();
-        final @Nullable Block<?> b = source.getBlock(tilePos.add(side.getDirection(), queryPos));
+        final @Nullable Block<?> b = source.getBlockType(tilePos.add(side.getDirection(), queryPos));
         return Blocks.hasTag(b, BlockTags.FENCES_CONNECT) || (b != null && b.getAttachedSide(source, tilePos.add(side.getDirection(), queryPos)) == side.getOpposite());
     }
 }
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 949369358..9d8bc3ddb 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
@@ -19,6 +19,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.joml.primitives.AABBdc;
 
+import java.util.Objects;
 import java.util.Random;
 
 public class BlockLogicFire
@@ -121,14 +122,14 @@ public class BlockLogicFire
     }
 
     public void setBurnResult(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        world.setBlockIdNotify(tilePos, this.getBurnResultId(world, tilePos));
+        world.setBlockTypeNotify(tilePos, this.getBurnResult(world, tilePos));
     }
 
     @Override
     public void updateTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand, final boolean isRandomTick) {
         TilePos queryPos = new TilePos();
 
-        final @Nullable Block<?> blockUnder = world.getBlock(tilePos.down(queryPos));
+        final @Nullable Block<?> blockUnder = world.getBlockType(tilePos.down(queryPos));
         final boolean infiniBurn = blockUnder != null && blockUnder.hasTag(BlockTags.INFINITE_BURN);
 
         // Extinguish fire
@@ -150,7 +151,7 @@ public class BlockLogicFire
         if (meta < 15) {
             world.setBlockData(tilePos, meta + rand.nextInt(3) / 2);
         }
-        world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay());
 
 
         if (!infiniBurn && !this.canNeighborCatchFire(world, tilePos)) {
@@ -200,9 +201,9 @@ public class BlockLogicFire
                         continue;
                     }
 
-                    if (world.getGameRuleValue(GameRules.DO_FIRE_SPREAD) && this.getBurnResultId(world, localPos) == 0 /* Fix for fire destroying moss blocks */) {
+                    if (world.getGameRuleValue(GameRules.DO_FIRE_SPREAD) && this.getBurnResult(world, localPos) == Blocks.AIR /* Fix for fire destroying moss blocks */) {
                         //Spread Fire with higher meta
-                        world.setBlockIdDataNotify(localPos, this.block.id(), Math.min(meta + rand.nextInt(5) / 4, 15));
+                        world.setBlockTypeDataNotify(localPos, this.block, Math.min(meta + rand.nextInt(5) / 4, 15));
                     }
                 }
             }
@@ -211,13 +212,13 @@ public class BlockLogicFire
 
     private void checkBurn(final @NotNull World world, final @NotNull TilePos tilePos, final int chance, final @NotNull Random random, final int meta) {
         if (!world.getGameRuleValue(GameRules.DO_FIRE_SPREAD)) return;
-        if (random.nextInt(chance) < burnChance[world.getBlockId(tilePos)]) {
-            final boolean isTNT = world.getBlockId(tilePos) == Blocks.TNT.id();
+        if (random.nextInt(chance) < burnChance[world.getBlockType(tilePos).id()]) {
+            final boolean isTNT = world.getBlockType(tilePos) == Blocks.TNT;
 
             if (random.nextInt(meta + 10) < 5 && !world.isBlockBeingRainedOn(tilePos)) {
-                if (this.getBurnResultId(world, tilePos) == 0 /* Fix for fire destroying moss blocks */) {
+                if (this.getBurnResult(world, tilePos) == Blocks.AIR /* Fix for fire destroying moss blocks */) {
                     //Spread Fire with higher meta
-                    world.setBlockIdDataNotify(tilePos, this.block.id(), Math.min(meta + random.nextInt(5) / 4, 15));
+                    world.setBlockTypeDataNotify(tilePos, this.block, Math.min(meta + random.nextInt(5) / 4, 15));
                 }
             } else {
                 this.setBurnResult(world, tilePos);
@@ -256,7 +257,7 @@ public class BlockLogicFire
     }
 
     public static boolean canBurn(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) {
-        return flameChance[source.getBlockId(tilePos)] > 0;
+        return flameChance[source.getBlockType(tilePos).id()] > 0;
     }
 
     public static boolean canBurn(final int blockId) {
@@ -264,7 +265,7 @@ public class BlockLogicFire
     }
 
     public static int getFlammability(final @NotNull World world, final @NotNull TilePosc tilePos, final int currentFlameChance) {
-        final int blockFlameChance = flameChance[world.getBlockId(tilePos)];
+        final int blockFlameChance = flameChance[world.getBlockType(tilePos).id()];
         return Math.max(blockFlameChance, currentFlameChance);
     }
 
@@ -278,32 +279,29 @@ public class BlockLogicFire
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!world.isBlockNormalCube(tilePos.down(new TilePos())) && !this.canNeighborCatchFire(world, tilePos)) {
 
-            world.setBlockIdNotify(tilePos, this.getBurnResultId(world, tilePos));
+            world.setBlockTypeNotify(tilePos, this.getBurnResult(world, tilePos));
         }
     }
 
-    protected int getBurnResultId(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        final int id = world.getBlockId(tilePos);
-        final @Nullable Block<?> stoneBlock = BlockLogicMoss.getStoneBlock(id);
-        if (stoneBlock != null) {
-            return stoneBlock.id();
-        }
-        return 0;
+    protected @NotNull Block<?> getBurnResult(final @NotNull World world, final @NotNull TilePosc tilePos) {
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        final @Nullable Block<?> noMossBlock = BlockLogicMoss.getNoMossBlock(block);
+        return Objects.requireNonNullElse(noMossBlock, Blocks.AIR);
     }
 
     @Override
     public void onPlacedByWorld(final @NotNull World world, final @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
-        if (world.getBlockId(tilePos.down(queryPos)) == Blocks.OBSIDIAN.id() && Blocks.PORTAL_NETHER.getLogic().tryToCreatePortal(world, tilePos, null)) {
+        if (world.getBlockType(tilePos.down(queryPos)) == Blocks.OBSIDIAN && Blocks.PORTAL_NETHER.getLogic().tryToCreatePortal(world, tilePos, null)) {
             return;
         }
         if (!world.isBlockNormalCube(tilePos.down(queryPos)) && !this.canNeighborCatchFire(world, tilePos)) {
-            world.setBlockIdNotify(tilePos, this.getBurnResultId(world, tilePos));
+            world.setBlockTypeNotify(tilePos, this.getBurnResult(world, tilePos));
         } else {
-            world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay());
+            world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay());
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFireCold.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFireCold.java
index 8e98677c2..3b48a1e51 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFireCold.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFireCold.java
@@ -19,7 +19,7 @@ public class BlockLogicFireCold
     @Override
     public void updateTick(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand, final boolean isRandomTick) {
         TilePos queryPos = new TilePos();
-        final @Nullable Block<?> blockUnder = world.getBlock(tilePos.down(queryPos));
+        final @Nullable Block<?> blockUnder = world.getBlockType(tilePos.down(queryPos));
         final boolean infiniBurn = blockUnder != null && blockUnder.hasTag(BlockTags.INFINITE_BURN_COLD);
 
         // Extinguish fire
@@ -42,7 +42,7 @@ public class BlockLogicFireCold
         if (meta < 15) {
             world.setBlockData(tilePos, meta + rand.nextInt(3) / 2);
         }
-        world.scheduleBlockUpdate(tilePos, this.block.id(), this.tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, this.tickDelay());
 
 
         if (!infiniBurn && !this.canNeighborCatchFire(world, tilePos)) {
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 75f5ac56c..378ebe4f0 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
@@ -52,7 +52,7 @@ public class BlockLogicFlower
 
     @Override
     public boolean canPlaceAt(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        return super.canPlaceAt(world, tilePos) && this.mayPlaceOn(world.getBlockId(tilePos.down(new TilePos())));
+        return super.canPlaceAt(world, tilePos) && this.mayPlaceOn(world.getBlockType(tilePos.down(new TilePos())));
     }
 
     @Override
@@ -60,14 +60,13 @@ public class BlockLogicFlower
         return PartialSupport.INSTANCE;
     }
 
-    protected boolean mayPlaceOn(final int blockId) {
-        final @Nullable Block<?> block = Blocks.getBlock(blockId);
-        return block != null && block.hasTag(BlockTags.GROWS_FLOWERS);
+    protected boolean mayPlaceOn(final @NotNull Block<?> block) {
+        return block.hasTag(BlockTags.GROWS_FLOWERS);
     }
 
     @Override
-    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final int id) {
-        super.onNeighborChanged(world, tilePos, id);
+    public void onNeighborChanged(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        super.onNeighborChanged(world, tilePos, block);
         this.checkAlive(world, tilePos);
     }
 
@@ -76,20 +75,20 @@ public class BlockLogicFlower
         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) {
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
     protected final void checkAlive(final @NotNull World world, final @NotNull TilePosc tilePos) {
         if (!this.canStay(world, tilePos)) {
             this.dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
     @Override
     public boolean canStay(final @NotNull World world, final @NotNull TilePosc tilePos) {
-        return (world.getFullBlockLightValue(tilePos) >= 8 || world.canBlockSeeSky(tilePos)) && this.mayPlaceOn(world.getBlockId(tilePos.down(new TilePos())));
+        return (world.getFullBlockLightValue(tilePos) >= 8 || world.canBlockSeeSky(tilePos)) && this.mayPlaceOn(world.getBlockType(tilePos.down(new TilePos())));
     }
 
     public static boolean isPermanent(final int metadata) {
@@ -120,7 +119,7 @@ public class BlockLogicFlower
         final Random rand = world.rand;
         if (!world.isClientSide && this.canBeBonemealed && itemStack.consumeItem(player)) {
             {
-                if (Block.hasLogicClass(world.getBlock(tilePos), BlockLogicFlowerStackable.class)) {
+                if (Block.hasLogicClass(world.getBlockType(tilePos), BlockLogicFlowerStackable.class)) {
                     final int meta = world.getBlockData(tilePos);
                     if (BlockLogicFlowerStackable.getStackCount(meta) < BlockLogicFlowerStackable.MAX_STACK_COUNT) {
                         world.setBlockDataNotify(tilePos, BlockLogicFlowerStackable.setStackCount(meta, BlockLogicFlowerStackable.getStackCount(meta) + 1));
@@ -138,21 +137,21 @@ public class BlockLogicFlower
                     checkX += rand.nextInt(3) - 1;
                     checkY += ((rand.nextInt(3) - 1) * rand.nextInt(3)) / 2;
                     checkZ += rand.nextInt(3) - 1;
-                    final int blockId = world.getBlockId(queryPos.set(checkX, checkY - 1, checkZ));
-                    if (!this.mayPlaceOn(blockId)) {
+                    final @NotNull Block<?> block = world.getBlockType(queryPos.set(checkX, checkY - 1, checkZ));
+                    if (!this.mayPlaceOn(block)) {
                         continue outer;
                     }
                 }
 
-                final @Nullable Block<?> b = world.getBlock(queryPos.set(checkX, checkY, checkZ));
+                final @Nullable Block<?> b = world.getBlockType(queryPos.set(checkX, checkY, checkZ));
                 if (Block.hasLogicClass(b, BlockLogicFlowerStackable.class)) {
                     final int meta = world.getBlockData(queryPos.set(checkX, checkY, checkZ));
                     if (BlockLogicFlowerStackable.getStackCount(meta) < BlockLogicFlowerStackable.MAX_STACK_COUNT) {
                         world.setBlockDataNotify(queryPos.set(checkX, checkY, checkZ), BlockLogicFlowerStackable.setStackCount(meta, BlockLogicFlowerStackable.getStackCount(meta) + 1));
                     }
-                } else if (b == null) {
+                } else if (b.hasTag(BlockTags.PLACE_OVERWRITES)) {
                     if (rand.nextFloat() > 0.75) {
-                        world.setBlockIdNotify(queryPos.set(checkX, checkY, checkZ), this.block.id());
+                        world.setBlockTypeNotify(queryPos.set(checkX, checkY, checkZ), this.block);
                     }
                 }
             }
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 757768063..374ef8cd2 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
@@ -154,12 +154,12 @@ public abstract class BlockLogicFluid extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         checkForHarden(world, tilePos);
     }
 
     private void checkForHarden(final World world, final @NotNull TilePosc tilePos) {
-        if (world.getBlockId(tilePos) != this.block.id()) {
+        if (world.getBlockType(tilePos) != this.block) {
             return;
         }
         TilePos queryPos = new TilePos();
@@ -229,7 +229,7 @@ public abstract class BlockLogicFluid extends BlockLogic {
 
     @Override
     public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
-        final Block<?> bBlock = world.getBlock(thatPos);
+        final Block<?> bBlock = world.getBlockType(thatPos);
 
         final int thisMeta = world.getBlockData(thisPos);
         final int otherMeta = world.getBlockData(thatPos);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java
index f522a14d3..d8ac4e7b0 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluidFlowing.java
@@ -25,7 +25,7 @@ public class BlockLogicFluidFlowing extends BlockLogicFluid {
     }
 
     private void setFluidStill(@NotNull World world, @NotNull TilePosc tilePos) {
-        world.setBlockIdData(tilePos, this.blockStill.id(), world.getBlockData(tilePos));
+        world.setBlockTypeData(tilePos, this.blockStill, world.getBlockData(tilePos));
         world.markBlocksDirty(tilePos, tilePos);
         world.markBlockNeedsUpdate(tilePos);
     }
@@ -67,11 +67,11 @@ public class BlockLogicFluidFlowing extends BlockLogicFluid {
             if (newFlowDecay != localFlowDecay) {
                 localFlowDecay = newFlowDecay;
                 if (localFlowDecay < 0) {
-                    world.setBlockIdNotify(tilePos, 0);
+                    world.setBlockTypeNotify(tilePos, Blocks.AIR);
                 } else {
                     world.setBlockDataNotify(tilePos, localFlowDecay);
-                    world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay());
-                    world.notifyBlocksOfNeighborChange(tilePos, this.block.id());
+                    world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
+                    world.notifyBlocksOfNeighborChange(tilePos, this.block);
                 }
             } else {
                 setFluidStill(world, tilePos);
@@ -80,14 +80,14 @@ public class BlockLogicFluidFlowing extends BlockLogicFluid {
             setFluidStill(world, tilePos);
         }
         if (canSpreadTo(world, tilePos.down(queryPos))) {
-            Block<?> b = world.getBlock(tilePos.down(queryPos));
+            Block<?> b = world.getBlockType(tilePos.down(queryPos));
             if (b != null) {
                 b.dropWithCause(world, EnumDropCause.WORLD, tilePos.down(queryPos), world.getBlockData(tilePos.down(queryPos)), null, null);
             }
             if (localFlowDecay >= 8) {
-                world.setBlockIdDataNotify(tilePos.down(queryPos), this.block.id(), localFlowDecay);
+                world.setBlockTypeDataNotify(tilePos.down(queryPos), this.block, localFlowDecay);
             } else {
-                world.setBlockIdDataNotify(tilePos.down(queryPos), this.block.id(), localFlowDecay + 8);
+                world.setBlockTypeDataNotify(tilePos.down(queryPos), this.block, localFlowDecay + 8);
             }
         } else if (localFlowDecay >= 0 && (localFlowDecay == 0 || isFluidBlocking(world, tilePos.down(queryPos)))) {
             boolean[] spreadFlags = getSpread(world, tilePos);
@@ -115,11 +115,8 @@ public class BlockLogicFluidFlowing extends BlockLogicFluid {
 
     private void flowIntoBlock(@NotNull World world, @NotNull TilePos tilePos, int meta) {
         if (canSpreadTo(world, tilePos)) {
-            int id = world.getBlockId(tilePos);
-            if (id > 0) {
-                this.fluid.onFlowIntoBlock(this, world, tilePos, meta);
-            }
-            world.setBlockIdDataNotify(tilePos, this.block.id(), meta);
+            this.fluid.onFlowIntoBlock(this, world, tilePos, meta);
+            world.setBlockTypeDataNotify(tilePos, this.block, meta);
         }
     }
 
@@ -197,8 +194,8 @@ public class BlockLogicFluidFlowing extends BlockLogicFluid {
     }
 
     private boolean isFluidBlocking(@NotNull World world, @NotNull TilePos tilePos) {
-        Block<?> b = world.getBlock(tilePos);
-        return b != null && !(b.getLogic() instanceof BlockLogicFluid) && !b.hasTag(BlockTags.BROKEN_BY_FLUIDS);
+        Block<?> b = world.getBlockType(tilePos);
+        return !(b.getLogic() instanceof BlockLogicFluid) && !b.hasTag(BlockTags.BROKEN_BY_FLUIDS) && !b.hasTag(BlockTags.PLACE_OVERWRITES);
     }
 
     protected int getHighest(@NotNull World world, @NotNull TilePos tilePos, int currentFlowDecay) {
@@ -230,8 +227,8 @@ public class BlockLogicFluidFlowing extends BlockLogicFluid {
     @Override
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
         super.onPlacedByWorld(world, tilePos);
-        if (world.getBlockId(tilePos) == this.block.id()) {
-            world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay());
+        if (world.getBlockType(tilePos) == this.block) {
+            world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
         }
     }
 }
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 558e50a88..cceaa8ec0 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
@@ -18,10 +18,9 @@ public class BlockLogicFluidStill extends BlockLogicFluid {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
-        super.onNeighborChanged(world, tilePos, id);
-        if (id == Side.TOP.getId()) return;
-        if (world.getBlockId(tilePos) == this.block.id()) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        super.onNeighborChanged(world, tilePos, block);
+        if (world.getBlockType(tilePos) == this.block) {
             setFlowing(world, tilePos);
         }
     }
@@ -29,9 +28,9 @@ public class BlockLogicFluidStill extends BlockLogicFluid {
     private void setFlowing(@NotNull World world, @NotNull TilePosc tilePos) {
         int meta = world.getBlockData(tilePos);
         world.noNeighborUpdate = true;
-        world.setBlockIdData(tilePos, this.blockFlowing.id(), meta);
+        world.setBlockTypeData(tilePos, this.blockFlowing, meta);
         world.markBlocksDirty(tilePos, tilePos);
-        world.scheduleBlockUpdate(tilePos, this.blockFlowing.id(), tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.blockFlowing, tickDelay());
         world.noNeighborUpdate = false;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnace.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnace.java
index 3de77f003..4fd8d1502 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnace.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnace.java
@@ -85,15 +85,15 @@ public class BlockLogicFurnace extends BlockLogicRotatable {
             if (Global.BUILD_CHANNEL.isUnstableBuild()) {
                 throw new RuntimeException(msg);
             }
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
             LOGGER.warn(msg);
             return;
         }
         keepFurnaceInventory = true;
         if (lit) {
-            world.setBlockIdNotify(tilePos, Blocks.FURNACE_STONE_ACTIVE.id());
+            world.setBlockTypeNotify(tilePos, Blocks.FURNACE_STONE_ACTIVE);
         } else {
-            world.setBlockIdNotify(tilePos, Blocks.FURNACE_STONE_IDLE.id());
+            world.setBlockTypeNotify(tilePos, Blocks.FURNACE_STONE_IDLE);
         }
         keepFurnaceInventory = false;
         world.setBlockDataNotify(tilePos, meta);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnaceBlast.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnaceBlast.java
index 692b05482..1bd2a9610 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnaceBlast.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFurnaceBlast.java
@@ -88,15 +88,15 @@ public class BlockLogicFurnaceBlast extends BlockLogicRotatable
 			if(Global.BUILD_CHANNEL.isUnstableBuild()) {
 				throw new RuntimeException(msg);
 			}
-			world.setBlockIdNotify(tilePos, 0);
+			world.setBlockTypeNotify(tilePos, Blocks.AIR);
             LOGGER.warn(msg);
 			return;
 		}
 		keepFurnaceInventory = true;
 		if(lit) {
-			world.setBlockIdNotify(tilePos, Blocks.FURNACE_BLAST_ACTIVE.id());
+			world.setBlockTypeNotify(tilePos, Blocks.FURNACE_BLAST_ACTIVE);
 		} else {
-			world.setBlockIdNotify(tilePos, Blocks.FURNACE_BLAST_IDLE.id());
+			world.setBlockTypeNotify(tilePos, Blocks.FURNACE_BLAST_IDLE);
 		}
 		keepFurnaceInventory = false;
 		world.setBlockDataNotify(tilePos, meta);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrass.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrass.java
index 9abaa9006..53bc266a1 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrass.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicGrass.java
@@ -30,45 +30,47 @@ public class BlockLogicGrass extends BlockLogic {
             return;
         }
         TilePos queryPos = new TilePos();
-        if (world.getBlockLightValue(tilePos.up(queryPos)) < 4 && Blocks.lightBlock[world.getBlockId(tilePos.up(queryPos))] > 2) {
-            world.setBlockIdNotify(tilePos, this.dirt.id());
+        if (world.getBlockLightValue(tilePos.up(queryPos)) < 4 && world.getBlockType(tilePos.up(queryPos)).lightBlock() > 2) {
+            world.setBlockTypeNotify(tilePos, this.dirt);
         } else if (world.getBlockLightValue(tilePos.up(queryPos)) >= 9) {
             for (int i = 0; i < 4; i++) {
                 int checkX = (tilePos.x() + rand.nextInt(3)) - 1;
                 int checkY = (tilePos.y() + rand.nextInt(5)) - 3;
                 int checkZ = (tilePos.x() + rand.nextInt(3)) - 1;
-                if (world.getBlockId(queryPos.set(checkX, checkY, checkZ)) == this.dirt.id() &&
+                if (world.getBlockType(queryPos.set(checkX, checkY, checkZ)) == this.dirt &&
                     world.getBlockLightValue(queryPos.set(checkX, checkY + 1, checkZ)) >= 4 &&
-                    Blocks.lightBlock[world.getBlockId(queryPos.set(checkX, checkY + 1, checkZ))] <= 2) {
-                    world.setBlockIdNotify(queryPos.set(checkX, checkY, checkZ), this.block.id());
+                    world.getBlockType(queryPos.set(checkX, checkY + 1, checkZ)).lightBlock() <= 2) {
+                    world.setBlockTypeNotify(queryPos.set(checkX, checkY, checkZ), this.block);
                 }
             }
-            if (world.getGameRuleValue(GameRules.DO_SEASONAL_GROWTH) && world.getBlockId(tilePos.up(queryPos)) == 0 && world.getSeasonManager().getCurrentSeason() != null && world.getSeasonManager().getCurrentSeason().growFlowers && rand.nextInt(256) == 0) {
-                int idToSpawn = 0;
+            if (world.getGameRuleValue(GameRules.DO_SEASONAL_GROWTH) && world.getBlockType(tilePos.up(queryPos)) == Blocks.AIR && world.getSeasonManager().getCurrentSeason() != null && world.getSeasonManager().getCurrentSeason().growFlowers && rand.nextInt(256) == 0) {
+                @Nullable Block<?> blockToSpawn = null;
                 int r = rand.nextInt(400);
 
                 if (r < 26) {
-                    idToSpawn = Blocks.FLOWER_RED.id();
+                    blockToSpawn = Blocks.FLOWER_RED;
                 } else if (r < 41) {
-                    idToSpawn = Blocks.FLOWER_YELLOW.id();
+                    blockToSpawn = Blocks.FLOWER_YELLOW;
                 } else if (r < 60) {
                     Biome biome = world.getBlockBiome(tilePos.up(queryPos));
                     if (biome == Biomes.OVERWORLD_BIRCH_FOREST || biome == Biomes.OVERWORLD_SEASONAL_FOREST) {
-                        idToSpawn = Blocks.FLOWER_PINK.id();
+                        blockToSpawn = Blocks.FLOWER_PINK;
                     } else if (biome == Biomes.OVERWORLD_MEADOW || biome == Biomes.OVERWORLD_BOREAL_FOREST || biome == Biomes.OVERWORLD_SHRUBLAND) {
-                        idToSpawn = Blocks.FLOWER_PURPLE.id();
+                        blockToSpawn = Blocks.FLOWER_PURPLE;
                     } else if (biome == Biomes.OVERWORLD_FOREST || biome == Biomes.OVERWORLD_SWAMPLAND || biome == Biomes.OVERWORLD_RAINFOREST || biome == Biomes.OVERWORLD_CAATINGA) {
-                        idToSpawn = Blocks.FLOWER_LIGHT_BLUE.id();
+                        blockToSpawn = Blocks.FLOWER_LIGHT_BLUE;
                     }
                 } else {
                     if (rand.nextInt(8) == 0) {
-                        idToSpawn = Blocks.TALLGRASS_FERN.id();
+                        blockToSpawn = Blocks.TALLGRASS_FERN;
                     } else {
-                        idToSpawn = Blocks.TALLGRASS.id();
+                        blockToSpawn = Blocks.TALLGRASS;
                     }
                 }
 
-                world.setBlockIdNotify(tilePos.up(queryPos), idToSpawn);
+                if (blockToSpawn != null) {
+                    world.setBlockTypeNotify(tilePos.up(queryPos), blockToSpawn);
+                }
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicIce.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicIce.java
index cf6f6c31c..251085fcf 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicIce.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicIce.java
@@ -36,16 +36,16 @@ public class BlockLogicIce extends BlockLogicTransparent {
         super.onHarvest(world, player, tilePos, data, tileEntity);
         Material material = world.getBlockMaterial(tilePos.down(new TilePos()));
         if(material.blocksMotion() || material.isLiquid()) {
-            world.setBlockIdNotify(tilePos, Blocks.FLUID_WATER_FLOWING.id());
+            world.setBlockTypeNotify(tilePos, Blocks.FLUID_WATER_FLOWING);
         }
     }
 
     @Override
 	public void updateTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand, boolean isRandomTick)
     {
-        if(world.getSavedLightValue(LightLayer.Block, tilePos) > 11 - Blocks.lightBlock[id()])
+        if(world.getSavedLightValue(LightLayer.Block, tilePos) > 11 - this.block.lightBlock())
         {
-            world.setBlockIdNotify(tilePos, Blocks.FLUID_WATER_STILL.id());
+            world.setBlockTypeNotify(tilePos, Blocks.FLUID_WATER_STILL);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java
index 0614ba8e4..2160d52ec 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java
@@ -60,7 +60,7 @@ public class BlockLogicJar extends BlockLogic implements ISupportable {
     public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) {
         if (player.getHeldItem() == null) {
             if (world.getBlockData(tilePos) == 0) {
-                world.setBlockIdNotify(tilePos, 0);
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
                 world.playSoundAtEntity(player, player, "item.pickup", 1f, 1f);
                 if (!world.isClientSide) {
                     world.dropItem(tilePos, new ItemStack(this.itemSupplier.get(), 1, 0));
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 05eee30f7..5e9e63706 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
@@ -65,7 +65,7 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable {
 
     @Override
     public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) {
-        world.setBlockIdRaw(tilePos, 0);
+        world.setBlockTypeRaw(tilePos, Blocks.AIR);
         world.playSoundAtEntity(player, player, "item.pickup", 1f, 1f);
         if (!world.isClientSide) {
             world.dropItem(tilePos, new ItemStack(this.itemSupplier.get(), 1, 0));
@@ -78,7 +78,7 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable {
     @Override
     public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
         TilePos queryPos = new TilePos();
-        if ((side == Side.BOTTOM || (side != Side.TOP && yHit >= 0.5d)) && (isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(queryPos)), BlockTags.CAN_HANG_OFF))) {
+        if ((side == Side.BOTTOM || (side != Side.TOP && yHit >= 0.5d)) && (isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockType(tilePos.up(queryPos)), BlockTags.CAN_HANG_OFF))) {
             world.setBlockDataNotify(tilePos, MASK_HANGING);
             return;
         }
@@ -86,7 +86,7 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable {
             world.setBlockDataNotify(tilePos, 0);
             return;
         }
-        if (isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(queryPos)), BlockTags.CAN_HANG_OFF)) {
+        if (isSupported(world, tilePos, Side.TOP) || world.getBlockType(tilePos.up(queryPos)).hasTag(BlockTags.CAN_HANG_OFF)) {
             world.setBlockDataNotify(tilePos, MASK_HANGING);
         } else {
             world.setBlockDataNotify(tilePos, 0);
@@ -95,7 +95,7 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable {
 
     @Override
     public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
-        if (isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(new TilePos())), BlockTags.CAN_HANG_OFF)) {
+        if (isSupported(world, tilePos, Side.TOP) || world.getBlockType(tilePos.up(new TilePos())).hasTag(BlockTags.CAN_HANG_OFF)) {
             return true;
         }
 
@@ -103,10 +103,10 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!canStay(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -122,7 +122,7 @@ public class BlockLogicJarButterfly extends BlockLogic implements ISupportable {
     public boolean canStay(@NotNull World world, @NotNull TilePosc tilePos) {
         int meta = world.getBlockData(tilePos);
         if ((meta & MASK_HANGING) != 0) {
-            return isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(new TilePos())), BlockTags.CAN_HANG_OFF);
+            return isSupported(world, tilePos, Side.TOP) || world.getBlockType(tilePos.up(new TilePos())).hasTag(BlockTags.CAN_HANG_OFF);
         }
 
         return isSupported(world, tilePos, Side.BOTTOM);
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 60da91151..a6371b971 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
@@ -55,10 +55,10 @@ public class BlockLogicLadder extends BlockLogic implements ISupportable {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!canExistAt(world, tilePos, world.getBlockData(tilePos))) {
-            dropWithCause(world, EnumDropCause.WORLD, tilePos, id, null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            dropWithCause(world, EnumDropCause.WORLD, tilePos, block.id(), null, null);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java
index f4ff9f0f6..365d71345 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLamp.java
@@ -28,11 +28,11 @@ public class BlockLogicLamp extends BlockLogic implements IPainted {
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
         if (this.isInverted) {
             if (this.isActive && (world.hasDirectSignal(tilePos) || world.hasNeighborSignal(tilePos))) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE, world.getBlockData(tilePos));
             }
         } else {
             if (this.isActive && !(world.hasDirectSignal(tilePos) || world.hasNeighborSignal(tilePos))) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_IDLE, world.getBlockData(tilePos));
             }
         }
     }
@@ -47,34 +47,34 @@ public class BlockLogicLamp extends BlockLogic implements IPainted {
 
         if (this.isInverted) {
             if (hasSignal && this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE, world.getBlockData(tilePos));
             } else if (!hasSignal && !this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_INVERTED_ACTIVE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_INVERTED_ACTIVE, world.getBlockData(tilePos));
             }
         } else {
             if (hasSignal && !this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_ACTIVE.id(), world.getBlockId(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_ACTIVE, world.getBlockData(tilePos));
             } else if (!hasSignal && this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_IDLE, world.getBlockData(tilePos));
             }
         }
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final boolean hasSignal = world.hasDirectSignal(tilePos) || world.hasNeighborSignal(tilePos);
 
         if (this.isInverted) {
             if (hasSignal && this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE, world.getBlockData(tilePos));
             } else if (!hasSignal && !this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_INVERTED_ACTIVE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_INVERTED_ACTIVE, world.getBlockData(tilePos));
             }
         } else {
             if (hasSignal && !this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_ACTIVE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_ACTIVE, world.getBlockData(tilePos));
             } else if (!hasSignal && this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_IDLE, world.getBlockData(tilePos));
             }
         }
     }
@@ -96,15 +96,15 @@ public class BlockLogicLamp extends BlockLogic implements IPainted {
     public void invertLamp(final @NotNull World world, final @NotNull TilePosc tilePos) {
         if (this.isInverted) {
             if (this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_IDLE, world.getBlockData(tilePos));
             } else {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_ACTIVE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_ACTIVE, world.getBlockData(tilePos));
             }
         } else {
             if (this.isActive) {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_INVERTED_IDLE, world.getBlockData(tilePos));
             } else {
-                world.setBlockIdDataNotify(tilePos, Blocks.LAMP_INVERTED_ACTIVE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.LAMP_INVERTED_ACTIVE, world.getBlockData(tilePos));
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLanternFirefly.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLanternFirefly.java
index f049d9d2f..c3de59516 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLanternFirefly.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLanternFirefly.java
@@ -71,7 +71,7 @@ public class BlockLogicLanternFirefly extends BlockLogic implements ISupportable
 
     @Override
     public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) {
-        world.setBlockIdRaw(tilePos, 0);
+        world.setBlockTypeRaw(tilePos, Blocks.AIR);
         world.playSoundAtEntity(player, player, "item.pickup", 1f, 1f);
         if (!world.isClientSide) {
             world.dropItem(tilePos, new ItemStack(this.itemSupplier.get(), 1, 0));
@@ -83,7 +83,7 @@ public class BlockLogicLanternFirefly extends BlockLogic implements ISupportable
 
     @Override
     public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
-        if ((side == Side.BOTTOM || (side != Side.TOP && yHit >= 0.5d)) && (isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(new TilePos())), BlockTags.CAN_HANG_OFF))) {
+        if ((side == Side.BOTTOM || (side != Side.TOP && yHit >= 0.5d)) && (isSupported(world, tilePos, Side.TOP) || world.getBlockType(tilePos.up(new TilePos())).hasTag(BlockTags.CAN_HANG_OFF))) {
             world.setBlockDataNotify(tilePos, MASK_HANGING);
             return;
         }
@@ -91,7 +91,7 @@ public class BlockLogicLanternFirefly extends BlockLogic implements ISupportable
             world.setBlockDataNotify(tilePos, 0);
             return;
         }
-        if (isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(new TilePos())), BlockTags.CAN_HANG_OFF)) {
+        if (isSupported(world, tilePos, Side.TOP) || world.getBlockType(tilePos.up(new TilePos())).hasTag(BlockTags.CAN_HANG_OFF)) {
             world.setBlockDataNotify(tilePos, MASK_HANGING);
         } else {
             world.setBlockDataNotify(tilePos, 0);
@@ -100,7 +100,7 @@ public class BlockLogicLanternFirefly extends BlockLogic implements ISupportable
 
     @Override
     public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
-        if (isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(new TilePos())), BlockTags.CAN_HANG_OFF)) {
+        if (isSupported(world, tilePos, Side.TOP) || world.getBlockType(tilePos.up(new TilePos())).hasTag(BlockTags.CAN_HANG_OFF)) {
             return true;
         }
 
@@ -108,10 +108,10 @@ public class BlockLogicLanternFirefly extends BlockLogic implements ISupportable
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!canStay(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -127,7 +127,7 @@ public class BlockLogicLanternFirefly extends BlockLogic implements ISupportable
     public boolean canStay(@NotNull World world, @NotNull TilePosc tilePos) {
         int meta = world.getBlockData(tilePos);
         if ((meta & MASK_HANGING) != 0) {
-            return isSupported(world, tilePos, Side.TOP) || Blocks.hasTag(world.getBlockId(tilePos.up(new TilePos())), BlockTags.CAN_HANG_OFF);
+            return isSupported(world, tilePos, Side.TOP) || world.getBlockType(tilePos.up(new TilePos())).hasTag(BlockTags.CAN_HANG_OFF);
         }
 
         return isSupported(world, tilePos, Side.BOTTOM);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java
index aa6cc9852..06b608fd0 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerAsh.java
@@ -28,7 +28,7 @@ public class BlockLogicLayerAsh extends BlockLogicLayerBase
         for (int i = 0; i < Direction.horizontalDirections.length; i++) {
             Direction dir = Direction.horizontalDirections[i];
             TilePos dirPos = tilePos.add(dir, new TilePos());
-            if (!((world.isBlockOpaqueCube(dirPos)) || (world.getBlockId(dirPos) == this.block.id() && world.getBlockData(dirPos) >= myMetadata))) return;
+            if (!((world.isBlockOpaqueCube(dirPos)) || (world.getBlockType(dirPos) == this.block && world.getBlockData(dirPos) >= myMetadata))) return;
         }
 
         world.setBlockData(tilePos, myMetadata + 1);
@@ -38,7 +38,7 @@ public class BlockLogicLayerAsh extends BlockLogicLayerBase
     @Override
 	public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos down = tilePos.down(new TilePos());
-        Block<?> b = world.getBlock(down);
+        Block<?> b = world.getBlockType(down);
         if(b == null || !b.isSolidRender()) {
         	return false;
         } else {
@@ -48,16 +48,16 @@ public class BlockLogicLayerAsh extends BlockLogicLayerBase
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         // Remove if no longer valid
         if (!canPlaceAt(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
     @Override
-    public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) {
+    public @NotNull ItemStack @Nullable [] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) {
         return switch (dropCause) {
             case SILK_TOUCH -> new ItemStack[]{new ItemStack(this, data + 1)};
             case PICK_BLOCK -> new ItemStack[]{new ItemStack(this)};
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 33956bcfd..52b510ea7 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
@@ -38,7 +38,7 @@ public class BlockLogicLayerLeaves extends BlockLogicLayerBase {
         for (int i = 0; i < Direction.horizontalDirections.length; i++) {
             TilePos p = tilePos.add(Direction.horizontalDirections[i], new TilePos());
 
-            if (!((world.isBlockOpaqueCube(p)) || (world.getBlockId(p) == this.block.id() && world.getBlockData(p) >= myMetadata))) {
+            if (!((world.isBlockOpaqueCube(p)) || (world.getBlockType(p) == this.block && world.getBlockData(p) >= myMetadata))) {
                 return;
             }
         }
@@ -50,7 +50,7 @@ public class BlockLogicLayerLeaves extends BlockLogicLayerBase {
     @Override
     public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos down = tilePos.down(new TilePos());
-        Block<?> b = world.getBlock(down);
+        Block<?> b = world.getBlockType(down);
         if (b == null || (!b.isSolidRender() && !(b.getLogic() instanceof BlockLogicLeavesBase))) {
             return false;
         } else {
@@ -60,11 +60,11 @@ public class BlockLogicLayerLeaves extends BlockLogicLayerBase {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         // Remove if no longer valid
         if (!canPlaceAt(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -87,7 +87,7 @@ public class BlockLogicLayerLeaves extends BlockLogicLayerBase {
                     if (metadata > 0) {
                         world.setBlockData(tilePos, metadata - 1);
                     } else {
-                        world.setBlockIdNotify(tilePos, 0);
+                        world.setBlockTypeNotify(tilePos, Blocks.AIR);
                     }
                 }
             }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java
index 68834459e..61f712082 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLayerSnow.java
@@ -34,7 +34,7 @@ public class BlockLogicLayerSnow extends BlockLogicLayerBase {
         for (int i = 0; i < Direction.horizontalDirections.length; i++) {
             Direction dir = Direction.horizontalDirections[i];
             TilePos dirPos = tilePos.add(dir, new TilePos());
-            if (!((world.isBlockOpaqueCube(dirPos)) || (world.getBlockId(dirPos) == this.block.id() && world.getBlockData(dirPos) >= myMetadata)))
+            if (!((world.isBlockOpaqueCube(dirPos)) || (world.getBlockType(dirPos) == this.block && world.getBlockData(dirPos) >= myMetadata)))
                 return;
         }
 
@@ -45,8 +45,8 @@ public class BlockLogicLayerSnow extends BlockLogicLayerBase {
     @Override
     public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos down = tilePos.down(new TilePos());
-        Block<?> b = world.getBlock(down);
-        if (b == null || (!b.isSolidRender() && !(b.getLogic() instanceof BlockLogicLeavesBase))) {
+        Block<?> b = world.getBlockType(down);
+        if (!b.isSolidRender() && !(b.getLogic() instanceof BlockLogicLeavesBase)) {
             return false;
         } else {
             Material material = world.getBlockMaterial(down);
@@ -61,11 +61,11 @@ public class BlockLogicLayerSnow extends BlockLogicLayerBase {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         // Remove if no longer valid
         if (!canPlaceAt(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -83,11 +83,11 @@ public class BlockLogicLayerSnow extends BlockLogicLayerBase {
     public void updateTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand, boolean isRandomTick) {
         if (world.getSavedLightValue(LightLayer.Block, tilePos) > 11) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
         if (!world.getBlockBiome(tilePos).hasSurfaceSnow() && world.getSeasonManager().getCurrentSeason() != null && world.getSeasonManager().getCurrentSeason().letWeatherCleanUpSnow) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 }
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 184376156..cb11548b1 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
@@ -70,7 +70,7 @@ public class BlockLogicLeavesBase extends BlockLogic {
                 for (int dy = -radius; dy <= radius; dy++) {
                     for (int dz = -radius; dz <= radius; dz++) {
                         p.set(tilePos.x() + dx, tilePos.y() + dy, tilePos.z() + dz);
-                        Block<?> block = world.getBlock(p);
+                        Block<?> block = world.getBlockType(p);
                         if (block != null && block.getLogic() instanceof BlockLogicLeavesBase) {
                             int meta = world.getBlockData(p);
                             if (!isPermanent(meta)) {
@@ -103,7 +103,7 @@ public class BlockLogicLeavesBase extends BlockLogic {
                 for (int xOffset = -radius; xOffset <= radius; xOffset++) {
                     for (int yOffset = -radius; yOffset <= radius; yOffset++) {
                         for (int zOffset = -radius; zOffset <= radius; zOffset++) {
-                            Block<?> block = world.getBlock(p.set(tilePos.x() + xOffset, tilePos.y() + yOffset, tilePos.z() + zOffset));
+                            Block<?> block = world.getBlockType(p.set(tilePos.x() + xOffset, tilePos.y() + yOffset, tilePos.z() + zOffset));
 
                             int i = (xOffset + halfLength) * xSpan + (yOffset + halfLength) * ySpan + (zOffset + halfLength);
                             if (block != null && block.getLogic() instanceof BlockLogicLog) {
@@ -165,7 +165,7 @@ public class BlockLogicLeavesBase extends BlockLogic {
 
     private void removeLeaves(@NotNull World world, @NotNull TilePosc tilePos) {
         dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-        world.setBlockIdNotify(tilePos, 0);
+        world.setBlockTypeNotify(tilePos, Blocks.AIR);
     }
 
     public static boolean isPermanent(int meta) {
@@ -204,7 +204,7 @@ public class BlockLogicLeavesBase extends BlockLogic {
 
     @Override
     public boolean isEquivalent(@NotNull World world, @NotNull TilePosc thisPos, @NotNull TilePosc thatPos) {
-        Block<?> bBlock = world.getBlock(thatPos);
+        Block<?> bBlock = world.getBlockType(thatPos);
 
         int thisMeta = world.getBlockData(thisPos) & ~MASK_DECAY_DATA;
         int otherMeta = world.getBlockData(thatPos) & ~MASK_DECAY_DATA;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java
index 94dd51f61..39f7684d8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCacao.java
@@ -36,7 +36,7 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone
         TilePos queryPos = new TilePos(tilePos);
         for (int x = tilePos.x() - 1; x < tilePos.x() + 1; x++) {
             for (int z = tilePos.z() - 1; z < tilePos.z() + 1; z++) {
-                if (world.getBlock(queryPos.set(x, tilePos.y(), z)) == null) {
+                if (world.getBlockType(queryPos.set(x, tilePos.y(), z)) == null) {
                     return true;
                 }
             }
@@ -83,7 +83,7 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone
                 dropWithCause(world, EnumDropCause.WORLD, tilePos, meta, null, null);
             }
             world.setBlockDataNotify(tilePos, setGrowthRate(meta, 0));
-            world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CACAO.id(), tickDelay());
+            world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CACAO, tickDelay());
             return true;
         }
         return false;
@@ -99,12 +99,12 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone
                 if (canBeansGrow(world, tilePos)) {
                     if (growthRate < MAX_GROWTH_STATE) {
                         world.setBlockDataNotify(tilePos, setGrowthRate(meta, ++growthRate));
-                        world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CACAO.id(), tickDelay());
+                        world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CACAO, tickDelay());
                     }
                 }
             } else if (growthRate > 0) {
                 world.setBlockDataNotify(tilePos, setGrowthRate(meta, 0));
-                world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CACAO.id(), tickDelay());
+                world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CACAO, tickDelay());
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCherryFlowering.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCherryFlowering.java
index 447ec0dad..fcd2d4395 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCherryFlowering.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesCherryFlowering.java
@@ -58,7 +58,7 @@ public class BlockLogicLeavesCherryFlowering extends BlockLogicLeavesCherry impl
                 dropWithCause(world, EnumDropCause.WORLD, tilePos, meta, null, null);
             }
             world.setBlockDataNotify(tilePos, setGrowthRate(meta, 0));
-            world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CHERRY_FLOWERING.id(), tickDelay());
+            world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CHERRY_FLOWERING, tickDelay());
             return true;
         }
         return false;
@@ -79,12 +79,12 @@ public class BlockLogicLeavesCherryFlowering extends BlockLogicLeavesCherry impl
             if (rand.nextInt(20) == 0) {
                 if ((growthRate) == 0) {
                     world.setBlockDataNotify(tilePos, setGrowthRate(meta, MAX_GROWTH_STATE));
-                    world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CHERRY_FLOWERING.id(), tickDelay());
+                    world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CHERRY_FLOWERING, tickDelay());
                 }
             }
         } else if(growthRate > 0){
             world.setBlockDataNotify(tilePos, meta & MASK_DECAY_DATA);
-            world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CHERRY_FLOWERING.id(), tickDelay());
+            world.scheduleBlockUpdate(tilePos, Blocks.LEAVES_CHERRY_FLOWERING, tickDelay());
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesOak.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesOak.java
index bb2701a04..8adef102e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesOak.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLeavesOak.java
@@ -20,14 +20,15 @@ public class BlockLogicLeavesOak extends BlockLogicLeavesBase {
         if (rand.nextInt(128) == 0 && world.getSeasonManager().getCurrentSeason() != null && world.getSeasonManager().getCurrentSeason().hasFallingLeaves) {
             TilePos queryPos = new TilePos();
             for (int q = -1; q > -16; q--) {
-                int id = world.getBlockId(tilePos.add(0, q, 0, queryPos));
-                if (id != 0) break;
-                if (Blocks.LAYER_LEAVES_OAK.canPlaceAt(world, tilePos.add(0, q, 0, queryPos)) &&
-                    Blocks.blocksList[world.getBlockId(tilePos.add(0, q - 1, 0, queryPos))].getMaterial().blocksMotion()) {
-
-                    world.setBlockIdNotify(tilePos.add(0, q, 0, queryPos), Blocks.LAYER_LEAVES_OAK.id());
+                final @NotNull Block<?> block = world.getBlockType(tilePos.add(0, q, 0, queryPos));
+                if (block != Blocks.AIR) break;
+                if (
+                    Blocks.LAYER_LEAVES_OAK.canPlaceAt(world, tilePos.add(0, q, 0, queryPos)) &&
+                    world.getBlockType(tilePos.add(0, q - 1, 0, queryPos)).getMaterial().blocksMotion()
+                ) {
+                    world.setBlockTypeNotify(tilePos.add(0, q, 0, queryPos), Blocks.LAYER_LEAVES_OAK);
                     break;
-                } else if (world.getBlockId(tilePos.add(0, q, 0, queryPos)) == Blocks.LAYER_LEAVES_OAK.id()) {
+                } else if (world.getBlockType(tilePos.add(0, q, 0, queryPos)) == Blocks.LAYER_LEAVES_OAK) {
                     Blocks.LAYER_LEAVES_OAK.getLogic().accumulate(world, queryPos);
                     break;
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java
index 4b89587b4..d0a5d984c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLever.java
@@ -116,7 +116,7 @@ public class BlockLogicLever extends BlockLogic implements ISupportable {
 
         if (rotation == -1) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         } else {
             world.setBlockDataNotify(tilePos, rotation | (isPowered ? MASK_POWERED : 0));
         }
@@ -162,14 +162,14 @@ public class BlockLogicLever extends BlockLogic implements ISupportable {
 
         if (rotation == -1) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         } else {
             world.setBlockDataNotify(tilePos, rotation | (isPowered ? MASK_POWERED : 0));
         }
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (checkIfAttachedToBlock(world, tilePos)) {
             int rotation = getRotation(world.getBlockData(tilePos));
             boolean shouldBreak = switch (rotation) {
@@ -183,7 +183,7 @@ public class BlockLogicLever extends BlockLogic implements ISupportable {
             };
             if (shouldBreak) {
                 dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-                world.setBlockIdNotify(tilePos, 0);
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
             }
         }
     }
@@ -193,7 +193,7 @@ public class BlockLogicLever extends BlockLogic implements ISupportable {
             return true;
         } else {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
             return false;
         }
     }
@@ -237,17 +237,17 @@ public class BlockLogicLever extends BlockLogic implements ISupportable {
 
         world.markBlocksDirty(tilePos, tilePos);
         world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.5D, (double) tilePos.z() + 0.5D, "random.click", 0.3F, isPowered(meta) ? 0.5F : 0.6F);
-        world.notifyBlocksOfNeighborChange(tilePos, this.block.id());
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
 
         TilePos queryPos = new TilePos();
         switch (rotation) {
-            case ROTATION_EAST -> world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block.id());
-            case ROTATION_WEST -> world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block.id());
-            case ROTATION_SOUTH -> world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block.id());
-            case ROTATION_NORTH -> world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block.id());
+            case ROTATION_EAST -> world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block);
+            case ROTATION_WEST -> world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block);
+            case ROTATION_SOUTH -> world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block);
+            case ROTATION_NORTH -> world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block);
             case ROTATION_TOP_NS, ROTATION_TOP_WE ->
-                world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block.id());
-            default -> world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block.id());
+                world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
+            default -> world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
         }
     }
 
@@ -259,17 +259,17 @@ public class BlockLogicLever extends BlockLogic implements ISupportable {
     @Override
     public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) {
         if (isPowered(data)) {
-            world.notifyBlocksOfNeighborChange(tilePos, this.block.id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
             TilePos queryPos = new TilePos();
             int rotation = getRotation(data);
             switch (rotation) {
-                case ROTATION_EAST -> world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block.id());
-                case ROTATION_WEST -> world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block.id());
-                case ROTATION_SOUTH -> world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block.id());
-                case ROTATION_NORTH -> world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block.id());
+                case ROTATION_EAST -> world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block);
+                case ROTATION_WEST -> world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block);
+                case ROTATION_SOUTH -> world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block);
+                case ROTATION_NORTH -> world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block);
                 case ROTATION_TOP_NS, ROTATION_TOP_WE ->
-                    world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block.id());
-                default -> world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block.id());
+                    world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
+                default -> world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
             }
         }
         super.onRemoved(world, tilePos, data);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLog.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLog.java
index 601e58431..495b14a2e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicLog.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicLog.java
@@ -21,7 +21,7 @@ public class BlockLogicLog extends BlockLogicAxisAligned {
             for (queryPos.x = tilePos.x() - r; queryPos.x <= tilePos.x() + r; queryPos.x++) {
                 for (queryPos.y = tilePos.x() - r; queryPos.y <= tilePos.y() + r; queryPos.y++) {
                     for (queryPos.z = -tilePos.x() - r; queryPos.z <= tilePos.z() + r; queryPos.z++) {
-                        Block<?> block = world.getBlock(queryPos);
+                        Block<?> block = world.getBlockType(queryPos);
                         if (!(block != null && block.getLogic() instanceof BlockLogicLeavesBase)) {
                             continue;
                         }
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 091c26f98..b1ce19e16 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
@@ -41,24 +41,24 @@ public class BlockLogicMatcher extends BlockLogicAxisAligned {
         Axis axis = mob.getPlacementDirection(side, PlacementMode.FACING).getAxis();
 
         world.setBlockDataNotify(tilePos, axisToMeta(axis));
-        world.scheduleBlockUpdate(tilePos, id(), tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     @Override
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
         super.onPlacedByWorld(world, tilePos);
-        world.scheduleBlockUpdate(tilePos, id(), tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     @Override
     public void onPlacedOnSide(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
         super.onPlacedOnSide(world, tilePos, side, xHit, yHit);
-        world.scheduleBlockUpdate(tilePos, id(), tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
-        world.scheduleBlockUpdate(tilePos, id(), tickDelay());
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     public void updateState(@NotNull World world, @NotNull TilePosc tilePos) {
@@ -84,17 +84,17 @@ public class BlockLogicMatcher extends BlockLogicAxisAligned {
 
 
         boolean backMatchesFront;
-        Block<?> fBlock = world.getBlock(front);
+        Block<?> fBlock = world.getBlockType(front);
         if (fBlock == null) {
-            backMatchesFront = world.getBlock(back) == null;
+            backMatchesFront = world.getBlockType(back) == null;
         } else {
             backMatchesFront = fBlock.isEquivalent(world, front, back);
         }
 
         if (!this.isActive && backMatchesFront) {
-            world.setBlockIdDataNotify(tilePos, Blocks.MATCHER_ACTIVE.id(), world.getBlockData(tilePos));
+            world.setBlockTypeDataNotify(tilePos, Blocks.MATCHER_ACTIVE, world.getBlockData(tilePos));
         } else if (this.isActive && !backMatchesFront) {
-            world.setBlockIdDataNotify(tilePos, Blocks.MATCHER.id(), world.getBlockData(tilePos));
+            world.setBlockTypeDataNotify(tilePos, Blocks.MATCHER, world.getBlockData(tilePos));
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java
index 3e52c5c49..db9199595 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java
@@ -23,7 +23,7 @@ public class BlockLogicMeshGold extends BlockLogicMesh {
         if (world.getTileEntity(tilePos) instanceof TileEntityMeshGold meshGold) {
             ItemStack heldItem = player.getHeldItem();
             boolean flag = meshGold.setFilterItem(player, heldItem);
-            world.notifyBlocksOfNeighborChange(tilePos, id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
             if(heldItem != null && heldItem.stackSize <= 0) {
                 player.inventory.setItem(player.inventory.getCurrentSlot(), null);
             }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java
index d96ef8f25..54cd8e48f 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java
@@ -39,9 +39,9 @@ public class BlockLogicMoss extends BlockLogic implements IBonemealable {
                 Direction rDir = Direction.getDirectionById(rand.nextInt(6));
                 TilePos randomPos = tilePos.add(rDir, new TilePos());
                 if (canMossSpread(world, randomPos)) {
-                    Block<?> mossStone = getMossBlock(world.getBlockId(randomPos));
+                    @Nullable Block<?> mossStone = getMossBlock(world.getBlockType(randomPos));
                     if (mossStone != null) {
-                        world.setBlockIdNotify(randomPos, mossStone.id());
+                        world.setBlockTypeNotify(randomPos, mossStone);
                     }
                 }
             }
@@ -69,42 +69,34 @@ public class BlockLogicMoss extends BlockLogic implements IBonemealable {
         return maxBlockLight == 0 && maxSkyLight == 0;
     }
 
-    public static @Nullable Block<?> getMossBlock(int blockId) {
-        return getMossBlock(Blocks.getBlock(blockId));
+    public static @Nullable Block<?> getMossBlock(final @NotNull Block<?> noMossBlock) {
+        return NO_MOSS_TO_MOSS_MAP.get(noMossBlock);
     }
 
-    public static @Nullable Block<?> getMossBlock(@Nullable Block<?> stoneBlock) {
-        return stoneToMossMap.get(stoneBlock);
+    public static @Nullable Block<?> getNoMossBlock(final @NotNull Block<?> mossBlock) {
+        return MOSS_TO_NO_MOSS_MAP.get(mossBlock);
     }
 
-    public static @Nullable Block<?> getStoneBlock(final int blockId) {
-        return getStoneBlock(Blocks.getBlock(blockId));
-    }
-
-    public static @Nullable Block<?> getStoneBlock(@Nullable Block<?> mossBlock) {
-        return mossToStoneMap.get(mossBlock);
-    }
-
-    public static final @NotNull Map<@NotNull Block<?>, @NotNull Block<?>> stoneToMossMap = new HashMap<>();
-    public static final @NotNull Map<@NotNull Block<?>, @NotNull Block<?>> mossToStoneMap = new HashMap<>();
+    public static final @NotNull Map<@NotNull Block<?>, @NotNull Block<?>> NO_MOSS_TO_MOSS_MAP = new HashMap<>();
+    public static final @NotNull Map<@NotNull Block<?>, @NotNull Block<?>> MOSS_TO_NO_MOSS_MAP = new HashMap<>();
 
     public static void initMossMap() {
-        stoneToMossMap.clear();
-        mossToStoneMap.clear();
-
-        stoneToMossMap.put(Blocks.STONE, Blocks.MOSS_STONE);
-        stoneToMossMap.put(Blocks.GRANITE, Blocks.MOSS_GRANITE);
-        stoneToMossMap.put(Blocks.LIMESTONE, Blocks.MOSS_LIMESTONE);
-        stoneToMossMap.put(Blocks.BASALT, Blocks.MOSS_BASALT);
-        stoneToMossMap.put(Blocks.COBBLE_STONE, Blocks.COBBLE_STONE_MOSSY);
-        stoneToMossMap.put(Blocks.COBBLE_BASALT, Blocks.COBBLE_BASALT_MOSSY);
-        stoneToMossMap.put(Blocks.COBBLE_LIMESTONE, Blocks.COBBLE_LIMESTONE_MOSSY);
-        stoneToMossMap.put(Blocks.COBBLE_GRANITE, Blocks.COBBLE_GRANITE_MOSSY);
-        stoneToMossMap.put(Blocks.BRICK_STONE_POLISHED, Blocks.BRICK_STONE_POLISHED_MOSSY);
-        stoneToMossMap.put(Blocks.LOG_OAK, Blocks.LOG_OAK_MOSSY);
-
-        for (Entry<Block<?>, Block<?>> entry : stoneToMossMap.entrySet()) {
-            mossToStoneMap.put(entry.getValue(), entry.getKey());
+        NO_MOSS_TO_MOSS_MAP.clear();
+        MOSS_TO_NO_MOSS_MAP.clear();
+
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.STONE, Blocks.MOSS_STONE);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.GRANITE, Blocks.MOSS_GRANITE);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.LIMESTONE, Blocks.MOSS_LIMESTONE);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.BASALT, Blocks.MOSS_BASALT);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.COBBLE_STONE, Blocks.COBBLE_STONE_MOSSY);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.COBBLE_BASALT, Blocks.COBBLE_BASALT_MOSSY);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.COBBLE_LIMESTONE, Blocks.COBBLE_LIMESTONE_MOSSY);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.COBBLE_GRANITE, Blocks.COBBLE_GRANITE_MOSSY);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.BRICK_STONE_POLISHED, Blocks.BRICK_STONE_POLISHED_MOSSY);
+        NO_MOSS_TO_MOSS_MAP.put(Blocks.LOG_OAK, Blocks.LOG_OAK_MOSSY);
+
+        for (Entry<Block<?>, Block<?>> entry : NO_MOSS_TO_MOSS_MAP.entrySet()) {
+            MOSS_TO_NO_MOSS_MAP.put(entry.getValue(), entry.getKey());
         }
     }
 
@@ -131,9 +123,9 @@ public class BlockLogicMoss extends BlockLogic implements IBonemealable {
                     continue;
                 }
 
-                Block<?> block = getMossBlock(world.getBlockId(randomPos));
+                @Nullable Block<?> block = getMossBlock(world.getBlockType(randomPos));
                 if (block != null) {
-                    world.setBlockIdNotify(randomPos, block.id());
+                    world.setBlockTypeNotify(randomPos, block);
                 }
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMud.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMud.java
index f207de2c9..2adfb8081 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMud.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMud.java
@@ -31,7 +31,7 @@ public class BlockLogicMud extends BlockLogic {
 
     @Override
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
-        world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     private boolean isWaterNearby(final @NotNull World world, final @NotNull TilePosc tilePos, int range) {
@@ -39,7 +39,7 @@ public class BlockLogicMud extends BlockLogic {
         for (queryPos.x = tilePos.x() - range; queryPos.x <= tilePos.x() + range; queryPos.x++) {
             for (queryPos.y = tilePos.y() - range; queryPos.y <= tilePos.y() + range; queryPos.y++) {
                 for (queryPos.z = tilePos.z() - range; queryPos.z <= tilePos.z() + range; queryPos.z++) {
-                    if (Blocks.hasTag(world.getBlockId(queryPos), BlockTags.IS_WATER)) {
+                    if (world.getBlockType(queryPos).hasTag(BlockTags.IS_WATER)) {
                         return true;
                     }
                 }
@@ -54,7 +54,7 @@ public class BlockLogicMud extends BlockLogic {
         for (queryPos.x = tilePos.x() - 1; queryPos.x <= tilePos.x() + 1; queryPos.x++) {
             for (queryPos.y = tilePos.y() - 1; queryPos.y <= tilePos.y() + 1; queryPos.y++) {
                 for (queryPos.z = tilePos.z() - 1; queryPos.z <= tilePos.z() + 1; queryPos.z++) {
-                    if (Blocks.hasTag(world.getBlockId(queryPos), BlockTags.IS_LAVA)) {
+                    if (world.getBlockType(queryPos).hasTag(BlockTags.IS_LAVA)) {
                         return true;
                     }
                 }
@@ -76,8 +76,8 @@ public class BlockLogicMud extends BlockLogic {
                 for (queryPos.y = tilePos.y() - 1; queryPos.y <= tilePos.y() + 1; queryPos.y++) {
                     for (queryPos.z = tilePos.z() - 1; queryPos.z <= tilePos.z() + 1; queryPos.z++) {
                         //...And the block is next to another wet mud block, it can become wet
-                        int bID = world.getBlockId(queryPos);
-                        if (bID == Blocks.MUD.id() || (bID == Blocks.FARMLAND_DIRT.id() && BlockLogicFarmland.isWet(world.getBlockData(queryPos)))) {
+                        final @NotNull Block<?> block = world.getBlockType(queryPos);
+                        if (block == Blocks.MUD || (block == Blocks.FARMLAND_DIRT && BlockLogicFarmland.isWet(world.getBlockData(queryPos)))) {
                             return true;
                         }
                     }
@@ -88,8 +88,8 @@ public class BlockLogicMud extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
-        world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay());
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     @Override
@@ -98,7 +98,7 @@ public class BlockLogicMud extends BlockLogic {
     }
 
     private void tryToFall(@NotNull World world, @NotNull TilePosc tilePos) {
-        if (world.getBlockId(tilePos) == Blocks.MUD_BAKED.id()) {
+        if (world.getBlockType(tilePos) == Blocks.MUD_BAKED) {
             return;
         }
 
@@ -106,7 +106,7 @@ public class BlockLogicMud extends BlockLogic {
         if (canFallBelow(world, tilePos.down(queryPos)) && tilePos.y() >= 0) {
             byte radius = 32;
             if (!world.areBlocksLoaded(tilePos.add(-radius, -radius, -radius, new TilePos()), tilePos.add(radius, radius, radius, new TilePos()))) {
-                world.setBlockIdNotify(tilePos, 0);
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
 
                 int checkX = tilePos.x();
                 int checkY = tilePos.y() - 1;
@@ -115,7 +115,7 @@ public class BlockLogicMud extends BlockLogic {
                     checkY--;
                 }
                 if (checkY > 0) {
-                    world.setBlockIdNotify(queryPos.set(checkX, checkY, checkZ), this.block.id());
+                    world.setBlockTypeNotify(queryPos.set(checkX, checkY, checkZ), this.block);
 
                 }
             } else {
@@ -126,8 +126,8 @@ public class BlockLogicMud extends BlockLogic {
     }
 
     public static boolean canFallBelow(@NotNull World world, @NotNull TilePos tilePos) {
-        int blockId = world.getBlockId(tilePos);
-        return blockId == 0 || blockId == Blocks.FIRE.id() || Blocks.hasTag(blockId, BlockTags.IS_WATER) || Blocks.hasTag(blockId, BlockTags.IS_LAVA);
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        return block == Blocks.AIR || block == Blocks.FIRE || block.hasTag(BlockTags.IS_WATER) || block.hasTag(BlockTags.IS_LAVA);
     }
 
 
@@ -137,8 +137,8 @@ public class BlockLogicMud extends BlockLogic {
         if (this.isHardened) {
             if (!isLavaNearby(world, tilePos)) {
                 if (canBecomeWet(world, tilePos)) {
-                    world.setBlockId(tilePos, Blocks.MUD.id());
-                    world.notifyBlockChange(tilePos, Blocks.MUD.id());
+                    world.setBlockType(tilePos, Blocks.MUD);
+                    world.notifyBlockChange(tilePos, Blocks.MUD);
                     return;
                 }
             }
@@ -151,8 +151,8 @@ public class BlockLogicMud extends BlockLogic {
                 for (int l = 0; l < 8; l++) {
                     world.spawnParticle("largesmoke", (double) tilePos.x() + Math.random(), (double) tilePos.y() + Math.random(), (double) tilePos.z() + Math.random(), 0.0D, 0.0D, 0.0D, 0);
                 }
-                world.setBlockId(tilePos, Blocks.MUD_BAKED.id());
-                world.notifyBlockChange(tilePos, Blocks.MUD_BAKED.id());
+                world.setBlockType(tilePos, Blocks.MUD_BAKED);
+                world.notifyBlockChange(tilePos, Blocks.MUD_BAKED);
                 return;
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMushroom.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMushroom.java
index 21235eedd..efe3b95a1 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMushroom.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMushroom.java
@@ -27,15 +27,15 @@ public class BlockLogicMushroom extends BlockLogicFlower {
             if (world.isAirBlock(checkPos) && canStay(world, checkPos)) {
                 checkPos.set(tilePos.x() + rand.nextInt(3) - 1, checkPos.y, tilePos.z() + rand.nextInt(3) - 1);
                 if (world.isAirBlock(checkPos) && canStay(world, checkPos)) {
-                    world.setBlockIdNotify(checkPos, this.block.id());
+                    world.setBlockTypeNotify(checkPos, this.block);
                 }
             }
         }
     }
 
     @Override
-    protected boolean mayPlaceOn(int blockId) {
-        return Blocks.solid[blockId];
+    protected boolean mayPlaceOn(final @NotNull Block<?> block) {
+        return block.solid();
     }
 
     @Override
@@ -43,7 +43,7 @@ public class BlockLogicMushroom extends BlockLogicFlower {
         if (tilePos.y() < 0 || tilePos.y() >= world.getHeightBlocks()) {
             return false;
         } else {
-            return world.getFullBlockLightValue(tilePos) < 13 && mayPlaceOn(world.getBlockId(tilePos.down(new TilePos())));
+            return world.getFullBlockLightValue(tilePos) < 13 && mayPlaceOn(world.getBlockType(tilePos.down(new TilePos())));
         }
     }
 
@@ -65,16 +65,16 @@ public class BlockLogicMushroom extends BlockLogicFlower {
                     checkX += rand.nextInt(3) - 1;
                     checkY += ((rand.nextInt(3) - 1) * rand.nextInt(3)) / 2;
                     checkZ += rand.nextInt(3) - 1;
-                    if (world.getFullBlockLightValue(queryPos.set(checkX, checkY, checkZ)) >= 13 || !mayPlaceOn(world.getBlockId(queryPos.set(checkX, checkY - 1, checkZ)))) {
+                    if (world.getFullBlockLightValue(queryPos.set(checkX, checkY, checkZ)) >= 13 || !mayPlaceOn(world.getBlockType(queryPos.set(checkX, checkY - 1, checkZ)))) {
                         continue outer;
                     }
                 }
 
-                if (world.getBlockId(queryPos.set(checkX, checkY, checkZ)) != 0) {
+                if (world.getBlockType(queryPos.set(checkX, checkY, checkZ)) != Blocks.AIR) {
                     continue;
                 }
                 if (rand.nextFloat() > 0.85) {
-                    world.setBlockIdNotify(queryPos.set(checkX, checkY, checkZ), this.block.id());
+                    world.setBlockTypeNotify(queryPos.set(checkX, checkY, checkZ), this.block);
                 }
             }
             return true;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicNetherrackIgneous.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicNetherrackIgneous.java
index eb01c7bd0..f5d14676d 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicNetherrackIgneous.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicNetherrackIgneous.java
@@ -40,20 +40,20 @@ public class BlockLogicNetherrackIgneous extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
-        world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay() + world.rand.nextInt(5) - world.rand.nextInt(5));
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay() + world.rand.nextInt(5) - world.rand.nextInt(5));
     }
 
     @Override
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
-        world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay() + world.rand.nextInt(5) - world.rand.nextInt(5));
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay() + world.rand.nextInt(5) - world.rand.nextInt(5));
     }
 
     public boolean canMelt(@NotNull World world, @NotNull TilePosc tilePos) {
         boolean canMelt = false;
         TilePos queryPos = new TilePos();
         for (Direction dir : Direction.directions) {
-            Block<?> block = world.getBlock(tilePos.add(dir, queryPos));
+            Block<?> block = world.getBlockType(tilePos.add(dir, queryPos));
             Material adjacentMaterial = block == null ? Materials.AIR : block.getMaterial();
             if (adjacentMaterial == Materials.WATER) {
                 return false;
@@ -66,7 +66,7 @@ public class BlockLogicNetherrackIgneous extends BlockLogic {
     @Override
     public void updateTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand, boolean isRandomTick) {
         if (canMelt(world, tilePos)) {
-            world.setBlockIdNotify(tilePos, Blocks.FLUID_LAVA_FLOWING.id());
+            world.setBlockTypeNotify(tilePos, Blocks.FLUID_LAVA_FLOWING);
         }
     }
 }
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 c5d2d7fcd..2b18f377e 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
@@ -31,7 +31,7 @@ public class BlockLogicNote extends BlockLogic {
 
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         boolean powered = world.hasNeighborSignal(tilePos);
         int data = world.getBlockData(tilePos);
         if (isPowered(data) && !powered) {
@@ -73,7 +73,7 @@ public class BlockLogicNote extends BlockLogic {
         if (world.isBlockOpaqueCube(tilePos.up(new TilePos()))) {
             return;
         }
-        world.triggerEvent(tilePos, Instrument.getInstrumentFromBlock(world.getBlock(tilePos.down(new TilePos()))).index, getNote(world.getBlockData(tilePos)));
+        world.triggerEvent(tilePos, Instrument.getInstrumentFromBlock(world.getBlockType(tilePos.down(new TilePos()))).index, getNote(world.getBlockData(tilePos)));
     }
 
     public static int setNote(int data, int note) {
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
index 606dda590..7721943c7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
@@ -65,15 +65,15 @@ public class BlockLogicOreRedstone extends BlockLogic {
     private void lightRedstone(@NotNull World world, @NotNull TilePosc tilePos) {
         spawnParticles(world, tilePos);
         if (!this.illuminated) {
-            world.scheduleBlockUpdate(tilePos, this.illuminatedBlock.id(), 20 + world.rand.nextInt(9 * 20));
-            world.setBlockIdNotify(tilePos, this.illuminatedBlock.id());
+            world.scheduleBlockUpdate(tilePos, this.illuminatedBlock, 20 + world.rand.nextInt(9 * 20));
+            world.setBlockTypeNotify(tilePos, this.illuminatedBlock);
         }
     }
 
     @Override
     public void updateTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand, boolean isRandomTick) {
         if (this.illuminated) {
-            world.setBlockIdNotify(tilePos, this.normalBlock.id());
+            world.setBlockTypeNotify(tilePos, this.normalBlock);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java
index 64a0ff38c..6305aa3ed 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOverlayPebbles.java
@@ -35,7 +35,7 @@ public class BlockLogicOverlayPebbles extends BlockLogic {
 
     @Override
     public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
-        Block<?> block = world.getBlock(tilePos.down(new TilePos()));
+        Block<?> block = world.getBlockType(tilePos.down(new TilePos()));
         return block != null && block.getMaterial().isSolid();
     }
 
@@ -55,10 +55,10 @@ public class BlockLogicOverlayPebbles extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!canStay(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPathDirt.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPathDirt.java
index 3077d4b15..ac4241ffa 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPathDirt.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPathDirt.java
@@ -38,13 +38,13 @@ public class BlockLogicPathDirt extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
-        super.onNeighborChanged(world, tilePos, id);
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        super.onNeighborChanged(world, tilePos, block);
         TilePos up = tilePos.up(new TilePos());
         Material material = world.getBlockMaterial(up);
-        Block<?> b = world.getBlock(up);
+        Block<?> b = world.getBlockType(up);
         if (material.isSolid() && b != Blocks.FENCE_GATE_PLANKS_OAK && b != Blocks.FENCE_GATE_PLANKS_OAK_PAINTED && b != Blocks.SIGN_WALL_PLANKS_OAK) {
-            world.setBlockIdNotify(tilePos, Blocks.DIRT.id());
+            world.setBlockTypeNotify(tilePos, Blocks.DIRT);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanks.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanks.java
index 51223d2ea..9d5ab5549 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanks.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanks.java
@@ -13,7 +13,7 @@ public class BlockLogicPlanks extends BlockLogic implements IPaintable {
 
     @Override
     public void setColor(@NotNull World world, @NotNull TilePosc tilePos, @NotNull DyeColor color) {
-        world.setBlockId(tilePos, Blocks.PLANKS_OAK_PAINTED.id());
+        world.setBlockType(tilePos, Blocks.PLANKS_OAK_PAINTED);
         Blocks.PLANKS_OAK_PAINTED.getLogic().setColor(world, tilePos, color);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanksPainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanksPainted.java
index 2dfba223b..60d30cd09 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanksPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPlanksPainted.java
@@ -47,7 +47,7 @@ public class BlockLogicPlanksPainted extends BlockLogic implements IPainted
 
     @Override
     public void removeDye(@NotNull World world, @NotNull TilePosc tilePos) {
-        world.setBlockIdNotify(tilePos, Blocks.PLANKS_OAK.id());
+        world.setBlockTypeNotify(tilePos, Blocks.PLANKS_OAK);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPortal.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPortal.java
index e9be8f585..078026940 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPortal.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPortal.java
@@ -98,7 +98,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
 
         // Sink to minimum Y
         for (int ry = 0; ry > -maxDims; ry--) {
-            if (world.getBlockId(tempPos.set(p.x, p.y + ry, p.z)) == this.portalFrame.id()) {
+            if (world.getBlockType(tempPos.set(p.x, p.y + ry, p.z)) == this.portalFrame) {
                 foundBottom = true;
                 p.y += ry;
                 break;
@@ -112,7 +112,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
         if (!swapOrientation) {
             // Find orientation and minimum bound
             for (int rx = 0; rx > -maxDims; rx--) {
-                if (world.getBlockId(tempPos.set(p.x + rx, p.y, p.z)) == this.portalFrame.id()) {
+                if (world.getBlockType(tempPos.set(p.x + rx, p.y, p.z)) == this.portalFrame) {
                     axis = Axis.X;
                     p.x += rx;
                     break;
@@ -121,7 +121,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
 
             if (axis == Axis.NONE) {
                 for (int rz = 0; rz > -maxDims; rz--) {
-                    if (world.getBlockId(tempPos.set(p.x, p.y, p.z + rz)) == this.portalFrame.id()) {
+                    if (world.getBlockType(tempPos.set(p.x, p.y, p.z + rz)) == this.portalFrame) {
                         axis = Axis.Z;
                         p.z += rz;
                         break;
@@ -131,7 +131,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
         } else {
             // Find orientation and minimum bound
             for (int rz = 0; rz > -maxDims; rz--) {
-                if (world.getBlockId(tempPos.set(p.x, p.y, p.z + rz)) == this.portalFrame.id()) {
+                if (world.getBlockType(tempPos.set(p.x, p.y, p.z + rz)) == this.portalFrame) {
                     axis = Axis.Z;
                     p.z += rz;
                     break;
@@ -140,7 +140,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
 
             if (axis == Axis.NONE) {
                 for (int rx = 0; rx > -maxDims; rx--) {
-                    if (world.getBlockId(tempPos.set(p.x + rx, p.y, p.z)) == this.portalFrame.id()) {
+                    if (world.getBlockType(tempPos.set(p.x + rx, p.y, p.z)) == this.portalFrame) {
                         axis = Axis.X;
                         p.x += rx;
                         break;
@@ -156,7 +156,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
             case X: {
                 // Find in X direction
                 for (int rx = 1; rx < maxDims; rx++) {
-                    if (world.getBlockId(tempPos.set(p.x + rx, p.y, p.z)) == this.portalFrame.id()) {
+                    if (world.getBlockType(tempPos.set(p.x + rx, p.y, p.z)) == this.portalFrame) {
                         maxBoundA = rx;
                         break;
                     }
@@ -167,7 +167,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
             default: {
                 // Find in Z direction
                 for (int rz = 1; rz < maxDims; rz++) {
-                    if (world.getBlockId(tempPos.set(p.x, p.y, p.z + rz)) == this.portalFrame.id()) {
+                    if (world.getBlockType(tempPos.set(p.x, p.y, p.z + rz)) == this.portalFrame) {
                         maxBoundA = rz;
                         break;
                     }
@@ -186,7 +186,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
             if (p.y + ry >= world.getHeightBlocks())
                 return swapOrientation ? null : getPortalDims(world, tilePos, true, expectMiddle);
 
-            if (world.getBlockId(tempPos.set(p.x + (axis == Axis.X ? 1 : 0), p.y + ry, p.z + (axis == Axis.Z ? 1 : 0))) == this.portalFrame.id()) {
+            if (world.getBlockType(tempPos.set(p.x + (axis == Axis.X ? 1 : 0), p.y + ry, p.z + (axis == Axis.Z ? 1 : 0))) == this.portalFrame) {
                 maxBoundY = ry;
                 break;
             }
@@ -200,14 +200,14 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
             for (int ry = 0; ry <= maxBoundY; ry++) {
                 // Check edges are correct
                 if (ra == 0 || ra == maxBoundA || ry == 0 || ry == maxBoundY) {
-                    if (world.getBlockId(tempPos.set(p.x + (axis == Axis.X ? ra : 0), p.y + ry, p.z + (axis == Axis.Z ? ra : 0))) != this.portalFrame.id()) {
+                    if (world.getBlockType(tempPos.set(p.x + (axis == Axis.X ? ra : 0), p.y + ry, p.z + (axis == Axis.Z ? ra : 0))) != this.portalFrame) {
                         return swapOrientation ? null : getPortalDims(world, tilePos, true, expectMiddle);
                     }
                 } else // Check interior is empty/fire
                 {
-                    int id = world.getBlockId(tempPos.set(p.x + (axis == Axis.X ? ra : 0), p.y + ry, p.z + (axis == Axis.Z ? ra : 0)));
+                    final @NotNull Block<?> block = world.getBlockType(tempPos.set(p.x + (axis == Axis.X ? ra : 0), p.y + ry, p.z + (axis == Axis.Z ? ra : 0)));
 
-                    if (id != 0 && id != this.portalTrigger.id() && id != this.block.id()) {
+                    if (block != Blocks.AIR && block != this.portalTrigger && block != this.block) {
                         return swapOrientation ? null : getPortalDims(world, tilePos, true, expectMiddle);
                     }
                 }
@@ -218,9 +218,9 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
         if (expectMiddle) {
             for (int ra = 1; ra < maxBoundA; ra++) {
                 for (int ry = 1; ry < maxBoundY; ry++) {
-                    int id = world.getBlockId(tempPos.set(p.x + (axis == Axis.X ? ra : 0), p.y + ry, p.z + (axis == Axis.Z ? ra : 0)));
+                    final @NotNull Block<?> block = world.getBlockType(tempPos.set(p.x + (axis == Axis.X ? ra : 0), p.y + ry, p.z + (axis == Axis.Z ? ra : 0)));
 
-                    if (id != this.block.id()) {
+                    if (block != this.block) {
                         return swapOrientation ? null : getPortalDims(world, tilePos, true, true);
                     }
                 }
@@ -246,7 +246,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
                         p.x = bounds.pos.x + ra;
                         p.y = bounds.pos.y + ry;
                         p.z = bounds.pos.z;
-                        world.setBlockIdData(p, this.block.id(), ORIENTATION_X & 0x1);
+                        world.setBlockTypeData(p, this.block, ORIENTATION_X & 0x1);
                     }
                 }
 
@@ -266,7 +266,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
                         p.x = bounds.pos.x;
                         p.y = bounds.pos.y + ry;
                         p.z = bounds.pos.z + ra;
-                        world.setBlockIdData(p, this.block.id(), ORIENTATION_Z & 0x1);
+                        world.setBlockTypeData(p, this.block, ORIENTATION_Z & 0x1);
                     }
 
                 }
@@ -287,11 +287,11 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         Bounds bounds = getPortalDims(world, tilePos, true);
 
         if (bounds == null) {
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -334,7 +334,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
             double xd = (rand.nextDouble() - 0.5D) * 0.5D;
             double yd = (rand.nextDouble() - 0.5D) * 0.5D;
             double zd = (rand.nextDouble() - 0.5D) * 0.5D;
-            if (world.getBlockId(tilePos.add(Direction.WEST, queryPos)) == this.block.id() || world.getBlockId(tilePos.add(Direction.EAST, queryPos)) == this.block.id()) {
+            if (world.getBlockType(tilePos.add(Direction.WEST, queryPos)) == this.block || world.getBlockType(tilePos.add(Direction.EAST, queryPos)) == this.block) {
                 pz = (double) tilePos.z() + 0.5D + 0.25D * (double) i1;
                 zd = rand.nextFloat() * 2.0D * (double) i1;
             } else {
@@ -365,7 +365,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
     @Override
     public void removeDye(@NotNull World world, @NotNull TilePosc tilePos) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, Blocks.STAIRS_PLANKS_OAK.id(), stripColorFromMetadata(meta));
+        world.setBlockDataNotify(tilePos, stripColorFromMetadata(meta));
     }
 
     @Override
@@ -378,7 +378,7 @@ public class BlockLogicPortal extends BlockLogicTransparent implements IPainted
     public void setColor(@NotNull World world, @NotNull TilePosc tilePos, @NotNull DyeColor color) {
         Bounds bounds = getPortalDims(world, tilePos, true);
         if (bounds == null) {
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
             return;
         }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java
index a246074d2..5a0ab3cdd 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlate.java
@@ -71,10 +71,10 @@ public class BlockLogicPressurePlate<T extends Entity> extends BlockLogic implem
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!isSupported(world, tilePos, sideFromMeta(world.getBlockData(tilePos)))) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -135,19 +135,19 @@ public class BlockLogicPressurePlate<T extends Entity> extends BlockLogic implem
         }
         if (isSteppedOn && !isPressed) {
             world.setBlockDataNotify(tilePos, meta | MASK_POWERED);
-            world.notifyBlocksOfNeighborChange(tilePos, id());
-            world.notifyBlocksOfNeighborChange(tilePos.add(dir, new TilePos()), id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.add(dir, new TilePos()), this.block);
             world.markBlocksDirty(tilePos, tilePos);
             world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.1D, (double) tilePos.z() + 0.5D, "random.click", 0.3F, 0.6F);
         } else if (!isSteppedOn && isPressed) {
             world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED);
-            world.notifyBlocksOfNeighborChange(tilePos, id());
-            world.notifyBlocksOfNeighborChange(tilePos.add(dir, new TilePos()), id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.add(dir, new TilePos()), this.block);
             world.markBlocksDirty(tilePos, tilePos);
             world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.1D, (double) tilePos.z() + 0.5D, "random.click", 0.3F, 0.5F);
         }
         if (isSteppedOn) {
-            world.scheduleBlockUpdate(tilePos, id(), tickDelay());
+            world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
         }
     }
 
@@ -155,8 +155,8 @@ public class BlockLogicPressurePlate<T extends Entity> extends BlockLogic implem
     public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) {
         if (isPressed(data)) {
             Side side = sideFromMeta(world.getBlockData(tilePos));
-            world.notifyBlocksOfNeighborChange(tilePos, id());
-            world.notifyBlocksOfNeighborChange(tilePos.add(side.getDirection(), new TilePos()), id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.add(side.getDirection(), new TilePos()), this.block);
         }
         super.onRemoved(world, tilePos, data);
     }
@@ -224,24 +224,24 @@ public class BlockLogicPressurePlate<T extends Entity> extends BlockLogic implem
             world.setBlockData(tilePos, setSide(meta, side));
         } else {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, meta, null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
 
     }
 
     @Override
     public boolean canBePainted() {
-        return id() == Blocks.PRESSURE_PLATE_PLANKS_OAK.id();
+        return this.block == Blocks.PRESSURE_PLATE_PLANKS_OAK;
     }
 
     @Override
     public void setColor(@NotNull World world, @NotNull TilePosc tilePos, @NotNull DyeColor color) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataRaw(tilePos, Blocks.PRESSURE_PLATE_PLANKS_OAK_PAINTED.id(), meta);
+        world.setBlockTypeDataRaw(tilePos, Blocks.PRESSURE_PLATE_PLANKS_OAK_PAINTED, meta);
         world.setBlockData(tilePos, meta);
         Blocks.PRESSURE_PLATE_PLANKS_OAK_PAINTED.getLogic().setColor(world, tilePos, color);
         if (isPressed(meta)) {
-            world.scheduleBlockUpdate(tilePos, Blocks.PRESSURE_PLATE_PLANKS_OAK_PAINTED.id(), tickDelay());
+            world.scheduleBlockUpdate(tilePos, Blocks.PRESSURE_PLATE_PLANKS_OAK_PAINTED, tickDelay());
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlatePainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlatePainted.java
index be23d76c8..710a8a884 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlatePainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPressurePlatePainted.java
@@ -46,7 +46,7 @@ public class BlockLogicPressurePlatePainted<T extends Entity> extends BlockLogic
 
     @Override
     public void removeDye(@NotNull World world, @NotNull TilePosc tilePos) {
-        world.setBlockIdNotify(tilePos, Blocks.PRESSURE_PLATE_PLANKS_OAK.id());
+        world.setBlockTypeNotify(tilePos, Blocks.PRESSURE_PLATE_PLANKS_OAK);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java
index 4469a97e8..c1cbb98a1 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumice.java
@@ -25,7 +25,7 @@ public class BlockLogicPumice extends BlockLogic {
         super.onPlacedByWorld(world, tilePos);
         byte radius = 2;
         if (this.isWet && (inWater(world, tilePos) || world.dimension.id == Dimension.DRIFT.id)) {
-            world.setBlockIdNotify(tilePos, Blocks.PUMICE_DRY.id());
+            world.setBlockTypeNotify(tilePos, Blocks.PUMICE_DRY);
             world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, tilePos.x() + 0.5D, tilePos.y() + 0.5D, tilePos.z() + 0.5D, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F);
             for (int l = 0; l < 8; l++) {
                 world.spawnParticle("largesmoke", (double) tilePos.x() + Math.random(), (double) tilePos.y() + Math.random(), (double) tilePos.z() + Math.random(), 0.0D, 0.0D, 0.0D, 0);
@@ -36,13 +36,13 @@ public class BlockLogicPumice extends BlockLogic {
             for (queryPos.x = tilePos.x() - radius; queryPos.x <= tilePos.x() + radius; queryPos.x++) {
                 for (queryPos.y = tilePos.y() - radius; queryPos.y <= tilePos.y() + radius; queryPos.y++) {
                     for (queryPos.z = tilePos.z() - radius; queryPos.z <= tilePos.z() + radius; queryPos.z++) {
-                        if (Blocks.hasTag(world.getBlockId(queryPos), BlockTags.IS_LAVA)) {
-                            world.setBlockIdNotify(queryPos, 0);
+                        if (world.getBlockType(queryPos).hasTag(BlockTags.IS_LAVA)) {
+                            world.setBlockTypeNotify(queryPos, Blocks.AIR);
                         }
                     }
                 }
             }
-            world.setBlockIdNotify(tilePos, Blocks.PUMICE_WET.id());
+            world.setBlockTypeNotify(tilePos, Blocks.PUMICE_WET);
         }
     }
 
@@ -50,23 +50,23 @@ public class BlockLogicPumice extends BlockLogic {
     public boolean inLava(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
         return
-            Blocks.hasTag(world.getBlockId(tilePos.east(queryPos)), BlockTags.IS_LAVA) ||
-                Blocks.hasTag(world.getBlockId(tilePos.west(queryPos)), BlockTags.IS_LAVA) ||
-                Blocks.hasTag(world.getBlockId(tilePos.up(queryPos)), BlockTags.IS_LAVA) ||
-                Blocks.hasTag(world.getBlockId(tilePos.down(queryPos)), BlockTags.IS_LAVA) ||
-                Blocks.hasTag(world.getBlockId(tilePos.south(queryPos)), BlockTags.IS_LAVA) ||
-                Blocks.hasTag(world.getBlockId(tilePos.north(queryPos)), BlockTags.IS_LAVA);
+            world.getBlockType(tilePos.east(queryPos)).hasTag(BlockTags.IS_LAVA) ||
+            world.getBlockType(tilePos.west(queryPos)).hasTag(BlockTags.IS_LAVA) ||
+            world.getBlockType(tilePos.up(queryPos)).hasTag(BlockTags.IS_LAVA) ||
+            world.getBlockType(tilePos.down(queryPos)).hasTag(BlockTags.IS_LAVA) ||
+            world.getBlockType(tilePos.south(queryPos)).hasTag(BlockTags.IS_LAVA) ||
+            world.getBlockType(tilePos.north(queryPos)).hasTag(BlockTags.IS_LAVA);
     }
 
     public boolean inWater(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
         return
-            Blocks.hasTag(world.getBlockId(tilePos.east(queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.west(queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.up(queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.down(queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.south(queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.north(queryPos)), BlockTags.IS_WATER);
+            world.getBlockType(tilePos.east(queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.west(queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.up(queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.down(queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.south(queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.north(queryPos)).hasTag(BlockTags.IS_WATER);
     }
 
     @Override
@@ -77,7 +77,7 @@ public class BlockLogicPumice extends BlockLogic {
             for (queryPos.x = tilePos.x() - radius; queryPos.x <= tilePos.x() + radius; queryPos.x++) {
                 for (queryPos.y = tilePos.y() - radius; queryPos.y <= tilePos.y() + radius; queryPos.y++) {
                     for (queryPos.z = tilePos.z() - radius; queryPos.z <= tilePos.z() + radius; queryPos.z++) {
-                        world.notifyBlocksOfNeighborChange(queryPos, world.getBlockId(queryPos));
+                        world.notifyBlocksOfNeighborChange(queryPos, world.getBlockType(queryPos));
                     }
 
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java
index ec8d659db..b54fa7cf8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkin.java
@@ -30,7 +30,7 @@ public class BlockLogicPumpkin extends BlockLogicVeryRotatable
         ItemStack heldItem = player.getHeldItem();
         if (heldItem != null && heldItem.getItem() instanceof ItemToolSword){
             heldItem.damageItem(1,player);
-            world.setBlockIdDataNotify(tilePos, Blocks.PUMPKIN_CARVED_IDLE.id(), player.getHorizontalPlacementDirection(Direction.getHorizontalDirection(player).getSide()).getOpposite().getId());
+            world.setBlockTypeDataNotify(tilePos, Blocks.PUMPKIN_CARVED_IDLE, player.getHorizontalPlacementDirection(Direction.getHorizontalDirection(player).getSide()).getOpposite().getId());
             return true;
         }
         return false;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java
index 67112f100..381ab4251 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicPumpkinRedstone.java
@@ -20,7 +20,7 @@ public class BlockLogicPumpkinRedstone extends BlockLogicVeryRotatable {
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
         for (Direction dir : Direction.directions){
-            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), id());
+            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block);
         }
     }
 
@@ -28,7 +28,7 @@ public class BlockLogicPumpkinRedstone extends BlockLogicVeryRotatable {
     public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) {
         TilePos queryPos = new TilePos();
         for (Direction dir : Direction.directions){
-            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), id());
+            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block);
         }
     }
 
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 6f48849b8..029969654 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
@@ -88,12 +88,12 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
         performRailTurn(world, tilePos, true);
         if (this.block == Blocks.RAIL_POWERED) {
-            onNeighborChanged(world, tilePos, id());
+            onNeighborChanged(world, tilePos, this.block);
         }
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (world.isClientSide) {
             return;
         }
@@ -103,7 +103,7 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
 
         if (!isSupported(world, tilePos, Side.BOTTOM)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
             return;
         } else if (!isRailValid(world, tilePos)) {
             switch (railDirection) {
@@ -122,8 +122,6 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
             }
         }
 
-        Block<?> block = Blocks.getBlock(id);
-
         if (this.block == Blocks.RAIL_POWERED) {
             TilePos queryPos = new TilePos();
 
@@ -145,9 +143,9 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
             }
 
             if (changedMeta) {
-                world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), id());
+                world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
                 if (railDirection.isSloped()) {
-                    world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), id());
+                    world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
                 }
             }
         } else if (block != null && block.isSignalSource() && new Rail(world, tilePos).getAdjacentTracks() == 3) {
@@ -197,8 +195,8 @@ public class BlockLogicRail extends BlockLogic implements ISupportable {
     }
 
     private boolean isConnectedPoweredRail2(@NotNull World world, @NotNull TilePos tilePos, boolean forward, int distance, @NotNull Axis axis) {
-        int blockId = world.getBlockId(tilePos);
-        if (blockId == Blocks.RAIL_POWERED.id()) {
+        final @NotNull Block<?> block = world.getBlockType(tilePos);
+        if (block == Blocks.RAIL_POWERED) {
             int meta = world.getBlockData(tilePos);
             boolean isPoweredFlagSet = (meta & MASK_POWERED) != 0;
             RailDirection direction = getRailDirection(world, tilePos);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java
index cb63be6bc..0276813f0 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRailDetector.java
@@ -76,19 +76,19 @@ public class BlockLogicRailDetector extends BlockLogicRail {
         if (minecartPresent && !isPowered) {
             // Set rail to powered
             world.setBlockDataNotify(tilePos, meta | MASK_POWERED);
-            world.notifyBlocksOfNeighborChange(tilePos, id());
-            world.notifyBlocksOfNeighborChange(tilePos.down(new TilePos()), id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.down(new TilePos()), this.block);
             world.markBlockDirty(tilePos);
         } else if (!minecartPresent && isPowered) {
             // Set rail to unpowered
             world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED);
-            world.notifyBlocksOfNeighborChange(tilePos, id());
-            world.notifyBlocksOfNeighborChange(tilePos.down(new TilePos()), id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.down(new TilePos()), this.block);
             world.markBlockDirty(tilePos);
         }
         if (minecartPresent) {
             // Schedule update if minecart in rail
-            world.scheduleBlockUpdate(tilePos, id(), tickDelay());
+            world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
         }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java
index d8b6957d8..4c3c82a61 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRedstone.java
@@ -35,7 +35,7 @@ public class BlockLogicRedstone extends BlockLogic {
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
         for (Direction dir : Direction.directions) {
-            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), id());
+            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block);
         }
     }
 
@@ -43,7 +43,7 @@ public class BlockLogicRedstone extends BlockLogic {
     public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) {
         TilePos queryPos = new TilePos();
         for (Direction dir : Direction.directions) {
-            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), id());
+            world.notifyBlocksOfNeighborChange(tilePos.add(dir, queryPos), this.block);
         }
     }
 
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 f769c2e54..4fc091ab0 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
@@ -73,12 +73,12 @@ public class BlockLogicRepeater extends BlockLogic {
         int meta = world.getBlockData(tilePos);
         boolean powered = isGettingPower(world, tilePos, meta);
         if (this.isRepeaterPowered && !powered) {
-            world.setBlockIdDataNotify(tilePos, Blocks.REPEATER_IDLE.id(), meta);
+            world.setBlockTypeDataNotify(tilePos, Blocks.REPEATER_IDLE, meta);
         } else if (!this.isRepeaterPowered) {
-            world.setBlockIdDataNotify(tilePos, Blocks.REPEATER_ACTIVE.id(), meta);
+            world.setBlockTypeDataNotify(tilePos, Blocks.REPEATER_ACTIVE, meta);
             if (!powered) {
                 int tickDelay = (meta & MASK_TICK_DELAY) >> 2;
-                world.scheduleBlockUpdate(tilePos, Blocks.REPEATER_ACTIVE.id(), tickDelayMap[tickDelay] * 2);
+                world.scheduleBlockUpdate(tilePos, Blocks.REPEATER_ACTIVE, tickDelayMap[tickDelay] * 2);
             }
         }
     }
@@ -95,7 +95,7 @@ public class BlockLogicRepeater extends BlockLogic {
     public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) {
         Side back = getSideFromMeta(data);
         Side front = back.getOpposite();
-        world.notifyBlocksOfNeighborChange(tilePos.add(front.getDirection(), new TilePos()), id());
+        world.notifyBlocksOfNeighborChange(tilePos.add(front.getDirection(), new TilePos()), this.block);
     }
 
     @Override
@@ -122,19 +122,19 @@ public class BlockLogicRepeater extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!canStay(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
             return;
         }
         int meta = world.getBlockData(tilePos);
         boolean powered = isGettingPower(world, tilePos, meta);
         int tickDelay = (meta & MASK_TICK_DELAY) >> 2;
         if (this.isRepeaterPowered && !powered) {
-            world.scheduleBlockUpdate(tilePos, id(), tickDelayMap[tickDelay] * 2);
+            world.scheduleBlockUpdate(tilePos, this.block, tickDelayMap[tickDelay] * 2);
         } else if (!this.isRepeaterPowered && powered) {
-            world.scheduleBlockUpdate(tilePos, id(), tickDelayMap[tickDelay] * 2);
+            world.scheduleBlockUpdate(tilePos, this.block, tickDelayMap[tickDelay] * 2);
         }
     }
 
@@ -143,7 +143,7 @@ public class BlockLogicRepeater extends BlockLogic {
         if (direction.isVertical()) return false;
 
         TilePos p = tilePos.add(direction.getDirection(), new TilePos());
-        return world.hasSignal(p, direction) || (world.getBlockId(p) == Blocks.WIRE_REDSTONE.id() && (world.getBlockData(p) & BlockLogicWireRedstone.MASK_POWER) != 0);
+        return world.hasSignal(p, direction) || (world.getBlockType(p) == Blocks.WIRE_REDSTONE && (world.getBlockData(p) & BlockLogicWireRedstone.MASK_POWER) != 0);
     }
 
 
@@ -169,7 +169,7 @@ public class BlockLogicRepeater extends BlockLogic {
         int l = mob.getHorizontalPlacementDirection(side).index;
         world.setBlockDataNotify(tilePos, l);
         if (isGettingPower(world, tilePos, l)) {
-            world.scheduleBlockUpdate(tilePos, id(), 1);
+            world.scheduleBlockUpdate(tilePos, this.block, 1);
         }
     }
 
@@ -179,7 +179,7 @@ public class BlockLogicRepeater extends BlockLogic {
         int l = side.getDirection().index;
         world.setBlockDataNotify(tilePos, l);
         if (isGettingPower(world, tilePos, l)) {
-            world.scheduleBlockUpdate(tilePos, id(), 1);
+            world.scheduleBlockUpdate(tilePos, this.block, 1);
         }
     }
 
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 9079469f3..ec32f16f5 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
@@ -56,12 +56,12 @@ public class BlockLogicRope
     @Override
     public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
-        boolean hasBlockNegX = source.getBlockId(tilePos.add(-1, 0, 0, queryPos)) == this.id();
-        boolean hasBlockPosX = source.getBlockId(tilePos.add(1, 0, 0, queryPos)) == this.id();
-        boolean hasBlockNegY = source.getBlockId(tilePos.add(0, -1, 0, queryPos)) == this.id();
-        boolean hasBlockPosY = source.getBlockId(tilePos.add(0, 1, 0, queryPos)) == this.id() || source.isBlockOpaqueCube(tilePos.add(0, 1, 0, queryPos));
-        boolean hasBlockNegZ = source.getBlockId(tilePos.add(0, 0, -1, queryPos)) == this.id();
-        boolean hasBlockPosZ = source.getBlockId(tilePos.add(0, 0, 1, queryPos)) == this.id();
+        boolean hasBlockNegX = source.getBlockType(tilePos.add(-1, 0, 0, queryPos)) == this.block;
+        boolean hasBlockPosX = source.getBlockType(tilePos.add(1, 0, 0, queryPos)) == this.block;
+        boolean hasBlockNegY = source.getBlockType(tilePos.add(0, -1, 0, queryPos)) == this.block;
+        boolean hasBlockPosY = source.getBlockType(tilePos.add(0, 1, 0, queryPos)) == this.block || source.isBlockOpaqueCube(tilePos.add(0, 1, 0, queryPos));
+        boolean hasBlockNegZ = source.getBlockType(tilePos.add(0, 0, -1, queryPos)) == this.block;
+        boolean hasBlockPosZ = source.getBlockType(tilePos.add(0, 0, 1, queryPos)) == this.block;
 
         float minX = 5 / 16.0f;
         float maxX = 11 / 16.0f;
@@ -103,7 +103,7 @@ public class BlockLogicRope
     }
 
     public void pickUpRope(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player) {
-        if (world.isClientSide || world.getBlock(tilePos) != this.block) {
+        if (world.isClientSide || world.getBlockType(tilePos) != this.block) {
             return;
         }
 
@@ -113,7 +113,7 @@ public class BlockLogicRope
         int y = tilePos.y();
         // Find the position of the lowest rope
         while (tilePos.y() > 0) {
-            Block<?> block = world.getBlock(tilePos.down(queryPos));
+            Block<?> block = world.getBlockType(tilePos.down(queryPos));
             if (block != this.block) {
                 break;
             }
@@ -140,7 +140,7 @@ public class BlockLogicRope
             if (ropesCollected >= freeSpace) {
                 break;
             }
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
             ropesCollected++;
         }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java
index 7b699fbe7..b446cf34a 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRotatable.java
@@ -40,21 +40,21 @@ public abstract class BlockLogicRotatable extends BlockLogic {
             return;
         }
         TilePos queryPos = new TilePos();
-        int bN = world.getBlockId(tilePos.north(queryPos));
-        int bS = world.getBlockId(tilePos.south(queryPos));
-        int bW = world.getBlockId(tilePos.west(queryPos));
-        int bE = world.getBlockId(tilePos.east(queryPos));
+        final @NotNull Block<?> bN = world.getBlockType(tilePos.north(queryPos));
+        final @NotNull Block<?> bS = world.getBlockType(tilePos.south(queryPos));
+        final @NotNull Block<?> bW = world.getBlockType(tilePos.west(queryPos));
+        final @NotNull Block<?> bE = world.getBlockType(tilePos.east(queryPos));
         Direction direction = Direction.NORTH;
-        if (Blocks.solid[bN] && !Blocks.solid[bS]) {
+        if (bN.solid() && !bS.solid()) {
             direction = Direction.SOUTH;
         }
-        if (Blocks.solid[bS] && !Blocks.solid[bN]) {
+        if (bS.solid() && !bN.solid()) {
             direction = Direction.NORTH;
         }
-        if (Blocks.solid[bW] && !Blocks.solid[bE]) {
+        if (bW.solid() && !bE.solid()) {
             direction = Direction.EAST;
         }
-        if (Blocks.solid[bE] && !Blocks.solid[bW]) {
+        if (bE.solid() && !bW.solid()) {
             direction = Direction.WEST;
         }
         world.setBlockDataNotify(tilePos, setDirection(world.getBlockData(tilePos), direction));
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSand.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSand.java
index fd717f85d..f30407594 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSand.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSand.java
@@ -20,13 +20,13 @@ public class BlockLogicSand extends BlockLogic {
     @Override
 	public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos)
     {
-        world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     @Override
-	public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id)
+	public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block)
     {
-        world.scheduleBlockUpdate(tilePos, this.block.id(), tickDelay());
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     @Override
@@ -39,15 +39,13 @@ public class BlockLogicSand extends BlockLogic {
         if(canFallBelow(world, tilePos.down(queryPos)) && tilePos.y() >= 0) {
             byte radius = 32;
             if(fallInstantly || !world.areBlocksLoaded(tilePos.add(-radius, -radius, -radius, new TilePos()), tilePos.add(radius, radius, radius, new TilePos()))) {
-                world.setBlockIdNotify(tilePos, 0);
-                int checkX = tilePos.x();
-                int checkY = tilePos.y() - 1;
-                int checkZ = tilePos.z();
-                while (canFallBelow(world, queryPos.set(checkX, checkY, checkZ)) && checkY > 0) {
-                    checkY--;
+                world.setBlockTypeNotify(tilePos, Blocks.AIR);
+                final @NotNull TilePos check = tilePos.down(new TilePos());
+                while (canFallBelow(world, check) && check.y > 0) {
+                    check.down();
                 }
-                if(checkY > 0) {
-                    world.setBlockIdNotify(queryPos.set(checkX, checkY, checkZ), this.block.id());
+                if(check.y > 0) {
+                    world.setBlockTypeNotify(check, this.block);
                 }
             } else {
                 EntityFallingBlock entityFallingBlock = new EntityFallingBlock(world, tilePos.x() + 0.5, tilePos.y() + 0.5, tilePos.z() + 0.5, this.block.id(), 0, null);
@@ -63,7 +61,7 @@ public class BlockLogicSand extends BlockLogic {
     }
 
     public static boolean canFallBelow(@NotNull World world, @NotNull TilePos tilePos) {
-        Block<?> block = world.getBlock(tilePos);
+        Block<?> block = world.getBlockType(tilePos);
         return block == null || block.hasTag(BlockTags.PLACE_OVERWRITES);
     }
 
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 70566c07e..ec896c299 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
@@ -23,8 +23,8 @@ public abstract class BlockLogicSaplingBase extends BlockLogicFlower implements
     }
 
     @Override
-    public boolean mayPlaceOn(int blockId) {
-        return blockId == Blocks.SAND.id() || super.mayPlaceOn(blockId);
+    public boolean mayPlaceOn(final @NotNull Block<?> block) {
+        return block == Blocks.SAND || super.mayPlaceOn(block);
     }
 
     @Override
@@ -36,8 +36,8 @@ public abstract class BlockLogicSaplingBase extends BlockLogicFlower implements
         TilePos queryPos = new TilePos();
 
         if (!this.canGrowOnSand) {
-            if (world.getBlockId(tilePos.down(queryPos)) == Blocks.SAND.id()) {
-                world.setBlockIdNotify(tilePos, Blocks.DEADBUSH.id());
+            if (world.getBlockType(tilePos.down(queryPos)) == Blocks.SAND) {
+                world.setBlockTypeNotify(tilePos, Blocks.DEADBUSH);
             }
         }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBirch.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBirch.java
index fa5d545e0..7f301c887 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBirch.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBirch.java
@@ -18,12 +18,12 @@ public class BlockLogicSaplingBirch extends BlockLogicSaplingBase {
     @Override
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
 
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         WorldFeature tree = new WorldFeatureTree(Blocks.LEAVES_BIRCH.id(), Blocks.LOG_BIRCH.id(), 5);
 
         if (!tree.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-            world.setBlockId(tilePos, id());
+            world.setBlockType(tilePos, this.block);
         }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCacao.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCacao.java
index 6f3846cea..b0763fa0e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCacao.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCacao.java
@@ -17,10 +17,10 @@ public class BlockLogicSaplingCacao extends BlockLogicSaplingBase {
     @Override
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
         WorldFeature treeSmall = new WorldFeatureTree(Blocks.LEAVES_CACAO.id(), Blocks.LOG_OAK_MOSSY.id(), 4);
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         if (!treeSmall.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-            world.setBlockId(tilePos, id());
+            world.setBlockType(tilePos, this.block);
         }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCherry.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCherry.java
index baa36b440..5331479a7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCherry.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingCherry.java
@@ -19,11 +19,11 @@ public class BlockLogicSaplingCherry extends BlockLogicSaplingBase {
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
         WorldFeature treeBig = new WorldFeatureCherryTreeFancy(Blocks.LEAVES_CHERRY.id(), Blocks.LOG_CHERRY.id());
         WorldFeature treeSmall = new WorldFeatureTreeCherry(Blocks.LEAVES_CHERRY.id(), Blocks.LOG_CHERRY.id(), 4);
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         if (!treeSmall.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
             if (!treeBig.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-                world.setBlockId(tilePos, id());
+                world.setBlockType(tilePos, this.block);
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingEucalyptus.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingEucalyptus.java
index 5a5341728..d1ee7e8f4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingEucalyptus.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingEucalyptus.java
@@ -17,12 +17,12 @@ public class BlockLogicSaplingEucalyptus extends BlockLogicSaplingBase {
     @Override
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
 
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         WorldFeature tree = new WorldFeatureTreeEucalyptus(Blocks.LEAVES_EUCALYPTUS.id(), Blocks.LOG_EUCALYPTUS.id());
         tree.init(1.0D, 1.0D, 1.0D);
         if (!tree.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-            world.setBlockId(tilePos, id());
+            world.setBlockType(tilePos, this.block);
         }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingOak.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingOak.java
index 441e77d3c..e74a51110 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingOak.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingOak.java
@@ -19,11 +19,11 @@ public class BlockLogicSaplingOak extends BlockLogicSaplingBase {
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
         WorldFeature treeBig = new WorldFeatureTreeFancy(Blocks.LEAVES_OAK.id(), Blocks.LOG_OAK.id());
         WorldFeature treeSmall = new WorldFeatureTree(Blocks.LEAVES_OAK.id(), Blocks.LOG_OAK.id(), 4);
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         if (!treeSmall.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
             if (!treeBig.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-                world.setBlockId(tilePos, id());
+                world.setBlockType(tilePos, this.block);
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPalm.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPalm.java
index f6b7351f0..02361d0de 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPalm.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPalm.java
@@ -18,7 +18,7 @@ public class BlockLogicSaplingPalm extends BlockLogicSaplingBase {
 
     @Override
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
-        boolean big = world.getBlockId(tilePos.down(new TilePos())) != Blocks.SAND.id();
+        boolean big = world.getBlockType(tilePos.down(new TilePos())) != Blocks.SAND;
 
         new WorldFeatureTreePalm(Blocks.LOG_PALM, Blocks.LEAVES_PALM, big, true, false).place(world, random, tilePos.x(), tilePos.y(), tilePos.z());
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPine.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPine.java
index ce99a00f2..0ee9a00dc 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPine.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingPine.java
@@ -38,11 +38,11 @@ public class BlockLogicSaplingPine extends BlockLogicSaplingBase {
         WorldFeature treeBig = new WorldFeatureTreeTaigaTall(Blocks.LEAVES_PINE.id(), Blocks.LOG_PINE.id());
         WorldFeature treeSmall = new WorldFeatureTreeTaigaBushy(Blocks.LEAVES_PINE.id(), Blocks.LOG_PINE.id());
 
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         if (!treeSmall.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
             if (!treeBig.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-                world.setBlockId(tilePos, id());
+                world.setBlockType(tilePos, this.block);
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingRetro.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingRetro.java
index 653b78f5f..6d3858fe7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingRetro.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingRetro.java
@@ -20,11 +20,11 @@ public class BlockLogicSaplingRetro extends BlockLogicSaplingBase {
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
         WorldFeature treeBig = new WorldFeatureTreeFancy(Blocks.LEAVES_OAK_RETRO.id(), Blocks.LOG_OAK.id());
         WorldFeature treeSmall = new WorldFeatureTree(Blocks.LEAVES_OAK_RETRO.id(), Blocks.LOG_OAK.id(), 4);
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         if (!treeSmall.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
             if (!treeBig.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-                world.setBlockId(tilePos, id());
+                world.setBlockType(tilePos, this.block);
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingShrub.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingShrub.java
index a6907c3b7..38dad5469 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingShrub.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingShrub.java
@@ -17,12 +17,12 @@ public class BlockLogicSaplingShrub extends BlockLogicSaplingBase {
     @Override
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
 
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
 
         WorldFeature tree = new WorldFeatureTreeShrub(Blocks.LEAVES_SHRUB.id(), Blocks.LOG_OAK.id());
 
         if (!tree.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-            world.setBlockId(tilePos, id());
+            world.setBlockType(tilePos, this.block);
         }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingThorn.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingThorn.java
index f34a16586..4f835f70a 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingThorn.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingThorn.java
@@ -18,11 +18,11 @@ public class BlockLogicSaplingThorn extends BlockLogicSaplingBase {
     @Override
     public void growTree(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random random) {
 
-        world.setBlockId(tilePos, 0);
+        world.setBlockType(tilePos, Blocks.AIR);
         WorldFeature treeFeature = new WorldFeatureTreeThorn(1, Blocks.LOG_THORN.id(), 0, Blocks.LEAVES_THORN.id(), 0);
 
         if (!treeFeature.place(world, random, tilePos.x(), tilePos.y(), tilePos.z())) {
-            world.setBlockId(tilePos, id());
+            world.setBlockType(tilePos, this.block);
         }
     }
 }
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 9fc5376de..dc87952e5 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
@@ -90,7 +90,7 @@ public class BlockLogicSign extends BlockLogic implements IPaintable {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         TilePos queryPos = new TilePos();
         boolean isUnstable = false;
         if (this.isFreeStanding) {
@@ -108,9 +108,9 @@ public class BlockLogicSign extends BlockLogic implements IPaintable {
         }
         if (isUnstable) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
-        super.onNeighborChanged(world, tilePos, id);
+        super.onNeighborChanged(world, tilePos, block);
     }
 
     @Override
@@ -151,7 +151,7 @@ public class BlockLogicSign extends BlockLogic implements IPaintable {
 
     @Override
     public void setColor(@NotNull World world, @NotNull TilePosc tilePos, @NotNull DyeColor color) {
-        world.setBlockIdRaw(tilePos, this.isFreeStanding ? Blocks.SIGN_POST_PLANKS_OAK_PAINTED.id() : Blocks.SIGN_WALL_PLANKS_OAK_PAINTED.id());
+        world.setBlockTypeRaw(tilePos, this.isFreeStanding ? Blocks.SIGN_POST_PLANKS_OAK_PAINTED : Blocks.SIGN_WALL_PLANKS_OAK_PAINTED);
         world.setBlockDataNotify(tilePos, color.blockMeta << 4 | (world.getBlockData(tilePos) & MASK_SIDE));
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java
index be8881bb9..9dfd95b90 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java
@@ -147,8 +147,8 @@ public class BlockLogicSlab extends BlockLogic
     @Override
 	public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
-        return world.getBlockId(tilePos.down(queryPos)) == id() ||
-                world.getBlockId(tilePos.up(queryPos)) == id() ||
+        return world.getBlockType(tilePos.down(queryPos)) == this.block ||
+                world.getBlockType(tilePos.up(queryPos)) == this.block ||
                 super.canPlaceAt(world, tilePos);
     }
 
@@ -189,7 +189,7 @@ public class BlockLogicSlab extends BlockLogic
 
     @Override
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
-        onNeighborChanged(world, tilePos, 0);
+        onNeighborChanged(world, tilePos, Blocks.AIR);
         this.modelBlock.onPlacedByWorld(world, tilePos);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPaintable.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPaintable.java
index fe9294690..c2ef28df4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPaintable.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPaintable.java
@@ -13,7 +13,7 @@ public class BlockLogicSlabPaintable extends BlockLogicSlab implements IPaintabl
     @Override
     public void setColor(@NotNull World world, @NotNull TilePosc tilePos, @NotNull DyeColor color) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, Blocks.SLAB_PLANKS_PAINTED.id(), meta);
+        world.setBlockTypeDataNotify(tilePos, Blocks.SLAB_PLANKS_PAINTED, meta);
         Blocks.SLAB_PLANKS_PAINTED.getLogic().setColor(world, tilePos, color);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPainted.java
index deef4ed75..d9b9cf79b 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlabPainted.java
@@ -53,7 +53,7 @@ public class BlockLogicSlabPainted extends BlockLogicSlab implements IPainted
 	@Override
 	public void removeDye(@NotNull World world, @NotNull TilePosc tilePos) {
 		final int meta = world.getBlockData(tilePos);
-		world.setBlockIdDataNotify(tilePos, Blocks.PLANKS_OAK.id(), meta & 0xF);
+		world.setBlockTypeDataNotify(tilePos, Blocks.PLANKS_OAK, meta & 0xF);
 	}
 
 	@Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSnow.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSnow.java
index 2f9fb5b45..5b8aae3eb 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSnow.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSnow.java
@@ -25,7 +25,7 @@ public class BlockLogicSnow extends BlockLogic
 	public void updateTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand, boolean isRandomTick) {
         if(world.getSavedLightValue(LightLayer.Block, tilePos) > 11) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java
index 6f6fc42de..88bba9d1e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java
@@ -52,7 +52,7 @@ public class BlockLogicSpikes extends BlockLogic
     }
 
 	@Override
-	public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+	public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
 		if(world.isClientSide) {
 			return;
 		}
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java
index 2405b7b65..507c71d73 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSponge.java
@@ -25,7 +25,7 @@ public class BlockLogicSponge extends BlockLogic {
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
         super.onPlacedByWorld(world, tilePos);
         if ((world.dimension == Dimension.NETHER || inHot(world, tilePos)) && this.isWet) {
-            world.setBlockIdNotify(tilePos, Blocks.SPONGE_DRY.id());
+            world.setBlockTypeNotify(tilePos, Blocks.SPONGE_DRY);
             world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, tilePos.x() + 0.5D, tilePos.y() + 0.5D, tilePos.z() + 0.5D, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F);
             for (int l = 0; l < 8; l++) {
                 world.spawnParticle("largesmoke", (double) tilePos.x() + Math.random(), (double) tilePos.y() + Math.random(), (double) tilePos.z() + Math.random(), 0.0D, 0.0D, 0.0D, 0);
@@ -37,14 +37,14 @@ public class BlockLogicSponge extends BlockLogic {
             for (queryPos.x = tilePos.x() - radius; queryPos.x <= tilePos.x() + radius; queryPos.x++) {
                 for (queryPos.y = tilePos.y() - radius; queryPos.y <= tilePos.y() + radius; queryPos.y++) {
                     for (queryPos.z = tilePos.z() - radius; queryPos.z <= tilePos.z() + radius; queryPos.z++) {
-                        if (Blocks.hasTag(world.getBlockId(queryPos), BlockTags.IS_WATER)) {
-                            world.setBlockIdNotify(queryPos, 0);
+                        if (world.getBlockType(queryPos).hasTag(BlockTags.IS_WATER)) {
+                            world.setBlockTypeNotify(queryPos, Blocks.AIR);
 
                         }
                     }
                 }
             }
-            world.setBlockIdNotify(tilePos, Blocks.SPONGE_WET.id());
+            world.setBlockTypeNotify(tilePos, Blocks.SPONGE_WET);
         }
     }
 
@@ -53,7 +53,7 @@ public class BlockLogicSponge extends BlockLogic {
         TilePos queryPos = new TilePos();
         for (int i = 0; i < Direction.directions.length; i++) {
             Direction dir = Direction.directions[i];
-            Block<?> b = world.getBlock(tilePos.add(dir, queryPos));
+            Block<?> b = world.getBlockType(tilePos.add(dir, queryPos));
             if (Blocks.hasTag(b, BlockTags.IS_WATER)) return true;
         }
         return false;
@@ -63,7 +63,7 @@ public class BlockLogicSponge extends BlockLogic {
         TilePos queryPos = new TilePos();
         for (int i = 0; i < Direction.directions.length; i++) {
             Direction dir = Direction.directions[i];
-            Block<?> b = world.getBlock(tilePos.add(dir, queryPos));
+            Block<?> b = world.getBlockType(tilePos.add(dir, queryPos));
             if (b == Blocks.COBBLE_NETHERRACK_IGNEOUS || Blocks.hasTag(b, BlockTags.IS_LAVA)) return true;
         }
         return false;
@@ -77,7 +77,7 @@ public class BlockLogicSponge extends BlockLogic {
             for (queryPos.x = tilePos.x() - radius; queryPos.x <= tilePos.x() + radius; queryPos.x++) {
                 for (queryPos.y = tilePos.y() - radius; queryPos.y <= tilePos.y() + radius; queryPos.y++) {
                     for (queryPos.z = tilePos.z() - radius; queryPos.z <= tilePos.z() + radius; queryPos.z++) {
-                        world.notifyBlocksOfNeighborChange(queryPos, world.getBlockId(queryPos));
+                        world.notifyBlocksOfNeighborChange(queryPos, world.getBlockType(queryPos));
                     }
 
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java
index e25b4302d..e4379a2b9 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java
@@ -307,7 +307,7 @@ public class BlockLogicStairs extends BlockLogic {
 
     @Override
     public void onPlacedByWorld(@NotNull World world, @NotNull TilePosc tilePos) {
-        onNeighborChanged(world, tilePos, 0);
+        onNeighborChanged(world, tilePos, Blocks.AIR);
         this.modelBlock.onPlacedByWorld(world, tilePos);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPaintable.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPaintable.java
index f6ee94654..9a58ebe03 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPaintable.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPaintable.java
@@ -13,7 +13,7 @@ public class BlockLogicStairsPaintable extends BlockLogicStairs implements IPain
     @Override
     public void setColor(@NotNull World world, @NotNull TilePosc tilePos, @NotNull DyeColor color) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, Blocks.STAIRS_PLANKS_PAINTED.id(), meta);
+        world.setBlockTypeDataNotify(tilePos, Blocks.STAIRS_PLANKS_PAINTED, meta);
         Blocks.STAIRS_PLANKS_PAINTED.getLogic().setColor(world, tilePos, color);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPainted.java
index dc039ffc1..979b15c42 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairsPainted.java
@@ -28,7 +28,7 @@ public class BlockLogicStairsPainted extends BlockLogicStairs implements IPainte
     @Override
     public void removeDye(@NotNull World world, @NotNull TilePosc tilePos) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, Blocks.STAIRS_PLANKS_OAK.id(), stripColorFromMetadata(meta));
+        world.setBlockTypeDataNotify(tilePos, Blocks.STAIRS_PLANKS_OAK, stripColorFromMetadata(meta));
     }
 
     @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 4e1953668..3b424bbb8 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
@@ -166,7 +166,7 @@ public class BlockLogicStatue extends BlockLogic {
 
     public @Nullable TileEntityStatue getTileEntity(final @NotNull World world, final @NotNull TilePosc tilePos) {
         TilePosc entPos = this.isBottom ? tilePos : tilePos.down(new TilePos());
-        final @Nullable Block<?> block = world.getBlock(entPos);
+        final @Nullable Block<?> block = world.getBlockType(entPos);
         if (block == null || !(block.getLogic() instanceof BlockLogicStatue)) {
             return null;
         }
@@ -205,15 +205,15 @@ public class BlockLogicStatue extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         final Block<?> otherBlock;
         if (!this.isBottom) {
-            otherBlock = world.getBlock(tilePos.down(new TilePos()));
+            otherBlock = world.getBlockType(tilePos.down(new TilePos()));
         } else {
-            otherBlock = world.getBlock(tilePos.up(new TilePos()));
+            otherBlock = world.getBlockType(tilePos.up(new TilePos()));
         }
-        if (!(otherBlock != null && otherBlock.getLogic() instanceof BlockLogicStatue)) {
-            world.setBlockIdNotify(tilePos, 0);
+        if (!(otherBlock.getLogic() instanceof BlockLogicStatue)) {
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStone.java
index 49b6c6f1b..958923672 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStone.java
@@ -43,7 +43,7 @@ public class BlockLogicStone extends BlockLogic {
     public void animationTick(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Random rand) {
 
         Chunk chunk = world.getChunk(tilePos);
-        if (tilePos.y() <= 32 && chunk.getChunkRandom(0x3ad8025fL).nextInt(10) == 0 && world.getBlockId(tilePos.down(new TilePos())) == 0) {
+        if (tilePos.y() <= 32 && chunk.getChunkRandom(0x3ad8025fL).nextInt(10) == 0 && world.getBlockType(tilePos.down(new TilePos())) == Blocks.AIR) {
             if (rand.nextInt(50) == 0)
                 world.spawnParticle("slimechunk", tilePos.x(), tilePos.y(), tilePos.z(), 0.0D, 0.0D, 0.0D, 0);
         }
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 8dd27b5f6..6358240cf 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
@@ -37,14 +37,14 @@ public class BlockLogicSugarcane extends BlockLogic implements IBonemealable {
         if (world.isAirBlock(up)) {
             int reedHeight = 0;
             TilePos p = new TilePos(tilePos);
-            while (world.getBlockId(p) == id()) { // Stop natural reed growth if reed is already 3 blocks tall
+            while (world.getBlockType(p) == this.block) { // Stop natural reed growth if reed is already 3 blocks tall
                 p.y--;
                 if (++reedHeight >= 3) return;
             }
 
             int data = world.getBlockData(tilePos);
             if (data >= 15) {
-                world.setBlockIdNotify(up, id());
+                world.setBlockTypeNotify(up, this.block);
                 world.setBlockDataNotify(tilePos, 0);
             } else {
                 world.setBlockDataNotify(tilePos, data + 1);
@@ -54,18 +54,18 @@ public class BlockLogicSugarcane extends BlockLogic implements IBonemealable {
 
     public void growReedOnTop(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos p = new TilePos(tilePos);
-        while (world.getBlockId(p) == id()) {
+        while (world.getBlockType(p) == this.block) {
             p.y++;
         }
         if (world.isAirBlock(p)) {
-            world.setBlockIdNotify(p, id());
+            world.setBlockTypeNotify(p, this.block);
         }
     }
 
     @Override
     public boolean canPlaceAt(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
-        Block<?> blockBelow = world.getBlock(tilePos.down(queryPos));
+        Block<?> blockBelow = world.getBlockType(tilePos.down(queryPos));
         if (blockBelow == null) {
             return false;
         } else if (blockBelow.id() == id()) {
@@ -74,21 +74,21 @@ public class BlockLogicSugarcane extends BlockLogic implements IBonemealable {
             return false;
         }
         return
-            Blocks.hasTag(world.getBlockId(tilePos.down(queryPos).add(Direction.WEST, queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.down(queryPos).add(Direction.EAST, queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.down(queryPos).add(Direction.NORTH, queryPos)), BlockTags.IS_WATER) ||
-                Blocks.hasTag(world.getBlockId(tilePos.down(queryPos).add(Direction.SOUTH, queryPos)), BlockTags.IS_WATER);
+            world.getBlockType(tilePos.down(queryPos).add(Direction.WEST, queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.down(queryPos).add(Direction.EAST, queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.down(queryPos).add(Direction.NORTH, queryPos)).hasTag(BlockTags.IS_WATER) ||
+            world.getBlockType(tilePos.down(queryPos).add(Direction.SOUTH, queryPos)).hasTag(BlockTags.IS_WATER);
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         checkCanStay(world, tilePos);
     }
 
     protected final void checkCanStay(@NotNull World world, @NotNull TilePosc tilePos) {
         if (!canStay(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTNT.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTNT.java
index 7ae29c260..0ecdc1f33 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTNT.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTNT.java
@@ -28,8 +28,8 @@ public class BlockLogicTNT extends BlockLogic {
 	}
 
 	@Override
-	public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
-		if (id > 0 && world.hasNeighborSignal(tilePos)) {
+	public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+		if (world.hasNeighborSignal(tilePos)) {
 			ignite(world, tilePos, true);
 		}
 	}
@@ -62,7 +62,7 @@ public class BlockLogicTNT extends BlockLogic {
 			}
 			return;
 		}
-		world.setBlockIdNotify(tilePos, 0);
+		world.setBlockTypeNotify(tilePos, Blocks.AIR);
 		EntityPrimedTNT tnt = new EntityPrimedTNT(world, tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F);
 		world.entityJoinedWorld(tnt);
 		if (sound) world.playSoundAtEntity(null, tnt, "tile.tnt.fuse", 1.0F, 1.0F);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTallGrass.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTallGrass.java
index 0a09cb887..d15c330d3 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTallGrass.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTallGrass.java
@@ -19,16 +19,15 @@ public class BlockLogicTallGrass extends BlockLogicFlower
     }
 
     @Override
-    protected boolean mayPlaceOn(int blockId) {
-    	Block<?> block = Blocks.getBlock(blockId);
-    	if(block != null && block.getLogic() instanceof BlockLogicMoss) {
+    protected boolean mayPlaceOn(final @NotNull Block<?> block) {
+    	if(block.getLogic() instanceof BlockLogicMoss) {
     		return true;
     	}
-    	return super.mayPlaceOn(blockId);
+    	return super.mayPlaceOn(block);
     }
 
     @Override
-    public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity)
+    public @NotNull ItemStack @Nullable [] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity)
     {
         return switch (dropCause) {
             case PICK_BLOCK, SILK_TOUCH -> new ItemStack[]{new ItemStack(this)};
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java
index ad5b45705..57a96ee9c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTorch.java
@@ -149,7 +149,7 @@ public class BlockLogicTorch extends BlockLogic implements ISupportable {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         boolean invalid;
         int side = world.getBlockData(tilePos) & MASK_DIRECTION;
         invalid = switch (side) {
@@ -162,14 +162,14 @@ public class BlockLogicTorch extends BlockLogic implements ISupportable {
         };
         if (invalid) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, side, null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
     private void dropTorchIfCantStay(@NotNull World world, @NotNull TilePosc tilePos) {
         if (!canPlaceAt(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
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 7d35b4547..a6410530c 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
@@ -34,12 +34,12 @@ public class BlockLogicTorchRedstone extends BlockLogicTorch {
         }
         TilePos queryPos = new TilePos();
         if (this.torchActive) {
-            world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), id());
+            world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block);
         }
     }
 
@@ -47,12 +47,12 @@ public class BlockLogicTorchRedstone extends BlockLogicTorch {
     public void onRemoved(@NotNull World world, @NotNull TilePosc tilePos, int data) {
         TilePos queryPos = new TilePos();
         if (this.torchActive) {
-            world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), id());
+            world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block);
         }
     }
 
@@ -89,17 +89,17 @@ public class BlockLogicTorchRedstone extends BlockLogicTorch {
         boolean isPowered = hasNeighborSignal(world, tilePos);
         if (this.torchActive) {
             if (isPowered) {
-                world.setBlockIdDataNotify(tilePos, Blocks.TORCH_REDSTONE_IDLE.id(), world.getBlockData(tilePos));
+                world.setBlockTypeDataNotify(tilePos, Blocks.TORCH_REDSTONE_IDLE, world.getBlockData(tilePos));
             }
         } else if (!isPowered) {
-            world.setBlockIdDataNotify(tilePos, Blocks.TORCH_REDSTONE_ACTIVE.id(), world.getBlockData(tilePos));
+            world.setBlockTypeDataNotify(tilePos, Blocks.TORCH_REDSTONE_ACTIVE, world.getBlockData(tilePos));
         }
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
-        super.onNeighborChanged(world, tilePos, id);
-        world.scheduleBlockUpdate(tilePos, id(), tickDelay());
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        super.onNeighborChanged(world, tilePos, block);
+        world.scheduleBlockUpdate(tilePos, this.block, tickDelay());
     }
 
     @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 651e4d8ba..a78b3754a 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
@@ -131,13 +131,12 @@ public class BlockLogicTrapDoor extends BlockLogic implements IPaintable {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (world.isClientSide) {
             return;
         }
 
-        Block<?> block = Blocks.getBlock(id);
-        if ((this.material != Materials.METAL && this.material != Materials.STEEL && block != null && block.isSignalSource()) || ((this.material == Materials.METAL || this.material == Materials.STEEL) && (block == null || block.isSignalSource()))) {
+        if (this.material != Materials.METAL && this.material != Materials.STEEL && block.isSignalSource() || (this.material == Materials.METAL || this.material == Materials.STEEL) && block.isSignalSource()) {
             int meta = world.getBlockData(tilePos);
             boolean isOpened = isTrapdoorOpen(meta);
             boolean isPowered = world.hasNeighborSignal(tilePos);
@@ -161,7 +160,7 @@ public class BlockLogicTrapDoor extends BlockLogic implements IPaintable {
     @Override
     public boolean isClimbable(@NotNull World world, @NotNull TilePosc tilePos) {
         TilePos queryPos = new TilePos();
-        Block<?> block = world.getBlock(tilePos.down(queryPos));
+        Block<?> block = world.getBlockType(tilePos.down(queryPos));
         int meta = world.getBlockData(tilePos);
         if (isTrapdoorOpen(meta) && (block != null && block.getLogic() instanceof BlockLogicLadder ladder)) {
             Side ladderSide = ladder.getSideFromMeta(world.getBlockData(tilePos.down(queryPos)));
@@ -225,6 +224,6 @@ public class BlockLogicTrapDoor extends BlockLogic implements IPaintable {
     @Override
     public void setColor(World world, @NotNull TilePosc tilePos, DyeColor color) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, Blocks.TRAPDOOR_PLANKS_PAINTED.id(), meta & 0xF | color.blockMeta << 4);
+        world.setBlockTypeDataNotify(tilePos, Blocks.TRAPDOOR_PLANKS_PAINTED, meta & 0xF | color.blockMeta << 4);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoorPainted.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoorPainted.java
index dd15b32ce..2ccb6b7a0 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoorPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrapDoorPainted.java
@@ -46,7 +46,7 @@ public class BlockLogicTrapDoorPainted extends BlockLogicTrapDoor implements IPa
     @Override
     public void removeDye(World world, @NotNull TilePosc tilePos) {
         final int meta = world.getBlockData(tilePos);
-        world.setBlockIdDataNotify(tilePos, Blocks.TRAPDOOR_PLANKS_OAK.id(), meta & 0xF);
+        world.setBlockTypeDataNotify(tilePos, Blocks.TRAPDOOR_PLANKS_OAK, meta & 0xF);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrommel.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrommel.java
index 68c92b2e3..5abc8fb0c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrommel.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicTrommel.java
@@ -69,17 +69,17 @@ public class BlockLogicTrommel extends BlockLogicRotatable
             if(Global.BUILD_CHANNEL.isUnstableBuild()) {
                 throw new RuntimeException(msg);
             }
-            world.setBlockIdNotify(tilepos, 0);
+            world.setBlockTypeNotify(tilepos, Blocks.AIR);
             LOGGER.warn(msg);
             return;
         }
         keepTrommelInventory = true;
         if(lit)
         {
-            world.setBlockIdNotify(tilepos, Blocks.TROMMEL_ACTIVE.id());
+            world.setBlockTypeNotify(tilepos, Blocks.TROMMEL_ACTIVE);
         } else
         {
-            world.setBlockIdNotify(tilepos, Blocks.TROMMEL_IDLE.id());
+            world.setBlockTypeNotify(tilepos, Blocks.TROMMEL_IDLE);
         }
         keepTrommelInventory = false;
         world.setBlockDataNotify(tilepos, data);
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 b6585226a..ea1b89ba6 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
@@ -69,7 +69,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
         ArrayList<TilePos> toUpdate = new ArrayList<>(this.toUpdate);
         this.toUpdate.clear();
         for (TilePos pos : toUpdate) {
-            world.notifyBlocksOfNeighborChange(pos, id());
+            world.notifyBlocksOfNeighborChange(pos, this.block);
         }
     }
 
@@ -114,9 +114,9 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
             }
         }
         if (strength != newStrength) {
-            int blockId = world.getBlockId(curPos);
-            if (blockId == id() || blockId == Blocks.FLUID_LAVA_STILL.id() || blockId == Blocks.FLUID_LAVA_FLOWING.id()) { // Intentionally keeping lava transmutation, do not delete carelessly
-                world.noNeighborUpdate = true;
+            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;
@@ -165,15 +165,15 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
     }
 
     private void checkCornerChangeAt(@NotNull World world, @NotNull TilePosc tilePos) {
-        if (world.getBlockId(tilePos) == id()) {
+        if (world.getBlockType(tilePos) == this.block) {
             TilePos queryPos = new TilePos();
-            world.notifyBlocksOfNeighborChange(tilePos, id());
-            world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), id());
-            world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), id());
+            world.notifyBlocksOfNeighborChange(tilePos, this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.west(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.east(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.north(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.south(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
+            world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
         }
     }
 
@@ -187,8 +187,8 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
 
         //        updatePowerStrength(world, x, y, z);
         world.getWireHandler().onWireAdded(tilePos);
-        world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), id());
-        world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), id());
+        world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
+        world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
         checkCornerChangeAt(world, tilePos.west(queryPos));
         checkCornerChangeAt(world, tilePos.east(queryPos));
         checkCornerChangeAt(world, tilePos.north(queryPos));
@@ -223,10 +223,10 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
         }
 
         TilePos queryPos = new TilePos();
-        world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), id());
-        world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), id());
+        world.notifyBlocksOfNeighborChange(tilePos.up(queryPos), this.block);
+        world.notifyBlocksOfNeighborChange(tilePos.down(queryPos), this.block);
 //        updatePowerStrength(world, x, y, z);
-        world.getWireHandler().onWireRemoved(tilePos, new BlockState(this.id(), world.getBlockData(tilePos)));
+        world.getWireHandler().onWireRemoved(tilePos, new BlockState(this.block, world.getBlockData(tilePos)));
         checkCornerChangeAt(world, tilePos.west(queryPos));
         checkCornerChangeAt(world, tilePos.east(queryPos));
         checkCornerChangeAt(world, tilePos.north(queryPos));
@@ -254,7 +254,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
     }
 
     private int checkTarget(@NotNull World world, @NotNull TilePos tilePos, int sourceStrength) {
-        if (world.getBlockId(tilePos) != id()) {
+        if (world.getBlockType(tilePos) != this.block) {
             return sourceStrength;
         }
 
@@ -263,7 +263,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (world.isClientSide || world.getWireHandler().onWireUpdated(tilePos)) {
             return;
         }
@@ -271,11 +271,11 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
         int strength = world.getBlockData(tilePos);
         if (!canPlaceAt(world, tilePos)) {
             dropWithCause(world, EnumDropCause.WORLD, tilePos, strength, null, null);
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         } else {
             updatePowerStrength(world, tilePos);
         }
-        super.onNeighborChanged(world, tilePos, id);
+        super.onNeighborChanged(world, tilePos, block);
     }
 
     @Override
@@ -396,7 +396,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
 
     public static boolean shouldConnectTo(@NotNull WorldSource source, @NotNull TilePos tilePos, @NotNull Side side) {
         // TODO make connections handled per block rather then by the dust
-        final Block<?> block = source.getBlock(tilePos);
+        final Block<?> block = source.getBlockType(tilePos);
         if (block == null) {
             return false;
         }
@@ -426,8 +426,7 @@ public class BlockLogicWireRedstone extends BlockLogic implements ISupportable {
         if (!(side2 == Side.TOP || side2 == Side.BOTTOM))
             return false; // Maybe some can generate a connection if placed below a block in the future?
 
-        int blockId = worldSource.getBlockId(tilePos);
-        return blockId == Blocks.WIRE_REDSTONE.id();
+        return worldSource.getBlockType(tilePos) == Blocks.WIRE_REDSTONE;
     }
 
     @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 952756601..a3b0048bf 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
@@ -42,763 +42,765 @@ public final class Blocks {
     public static final boolean[] neighborNotifyOnMetadataChangeDisabled = new boolean[blocksList.length];
     public static int highestBlockId = 0;
 
-    public static final Block<?> STONE = register("stone", "minecraft:block/stone", 1, (b) -> new BlockLogicStone(b, Blocks.COBBLE_STONE, Materials.STONE))
+    public static final @NotNull Block<?> AIR = register("air", "minecraft:block/air", 0, (b) -> new BlockLogicAir(b))
+        .withTags(BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
+    public static final @NotNull Block<?> STONE = register("stone", "minecraft:block/stone", 1, (b) -> new BlockLogicStone(b, Blocks.COBBLE_STONE, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BASALT = register("basalt", "minecraft:block/basalt", 2, (b) -> new BlockLogicStone(b, Blocks.COBBLE_BASALT, Materials.BASALT))
+    public static final @NotNull Block<?> BASALT = register("basalt", "minecraft:block/basalt", 2, (b) -> new BlockLogicStone(b, Blocks.COBBLE_BASALT, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> LIMESTONE = register("limestone", "minecraft:block/limestone", 3, (b) -> new BlockLogicStone(b, Blocks.COBBLE_LIMESTONE, Materials.LIMESTONE))
+    public static final @NotNull Block<?> LIMESTONE = register("limestone", "minecraft:block/limestone", 3, (b) -> new BlockLogicStone(b, Blocks.COBBLE_LIMESTONE, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> GRANITE = register("granite", "minecraft:block/granite", 4, (b) -> new BlockLogicStone(b, Blocks.COBBLE_GRANITE, Materials.GRANITE))
+    public static final @NotNull Block<?> GRANITE = register("granite", "minecraft:block/granite", 4, (b) -> new BlockLogicStone(b, Blocks.COBBLE_GRANITE, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> MARBLE = register("marble", "minecraft:block/marble", 5, (b) -> new BlockLogic(b, Materials.MARBLE))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> SLATE = register("slate", "minecraft:block/slate", 6, (b) -> new BlockLogic(b, Materials.SLATE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> PERMAFROST = register("permafrost", "minecraft:block/permafrost", 7, (b) -> new BlockLogicStone(b, Blocks.COBBLE_PERMAFROST, Materials.PERMAFROST))
+    public static final @NotNull Block<?> PERMAFROST = register("permafrost", "minecraft:block/permafrost", 7, (b) -> new BlockLogicStone(b, Blocks.COBBLE_PERMAFROST, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> COBBLE_STONE = register("cobble.stone", "minecraft:block/cobble_stone", 10, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_STONE = register("cobble.stone", "minecraft:block/cobble_stone", 10, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> COBBLE_STONE_MOSSY = register("cobble.stone.mossy", "minecraft:block/cobble_stone_mossy", 11, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_STONE_MOSSY = register("cobble.stone.mossy", "minecraft:block/cobble_stone_mossy", 11, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
-    public static final Block<?> COBBLE_BASALT = register("cobble.basalt", "minecraft:block/cobble_basalt", 12, (b) -> new BlockLogicCobble(b, Materials.BASALT, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_BASALT = register("cobble.basalt", "minecraft:block/cobble_basalt", 12, (b) -> new BlockLogicCobble(b, Materials.BASALT, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> COBBLE_LIMESTONE = register("cobble.limestone", "minecraft:block/cobble_limestone", 13, (b) -> new BlockLogicCobble(b, Materials.LIMESTONE, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_LIMESTONE = register("cobble.limestone", "minecraft:block/cobble_limestone", 13, (b) -> new BlockLogicCobble(b, Materials.LIMESTONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> COBBLE_GRANITE = register("cobble.granite", "minecraft:block/cobble_granite", 14, (b) -> new BlockLogicCobble(b, Materials.GRANITE, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_GRANITE = register("cobble.granite", "minecraft:block/cobble_granite", 14, (b) -> new BlockLogicCobble(b, Materials.GRANITE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> COBBLE_PERMAFROST = register("cobble.permafrost", "minecraft:block/cobble_permafrost", 15, (b) -> new BlockLogicCobble(b, Materials.PERMAFROST, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_PERMAFROST = register("cobble.permafrost", "minecraft:block/cobble_permafrost", 15, (b) -> new BlockLogicCobble(b, Materials.PERMAFROST, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.PERMAFROST).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> COBBLE_BASALT_MOSSY = register("cobble.basalt.mossy", "minecraft:block/cobble_basalt_mossy", 16, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_BASALT_MOSSY = register("cobble.basalt.mossy", "minecraft:block/cobble_basalt_mossy", 16, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
-    public static final Block<?> COBBLE_LIMESTONE_MOSSY = register("cobble.limestone.mossy", "minecraft:block/cobble_limestone_mossy", 17, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_LIMESTONE_MOSSY = register("cobble.limestone.mossy", "minecraft:block/cobble_limestone_mossy", 17, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
-    public static final Block<?> COBBLE_GRANITE_MOSSY = register("cobble.granite.mossy", "minecraft:block/cobble_granite_mossy", 18, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
+    public static final @NotNull Block<?> COBBLE_GRANITE_MOSSY = register("cobble.granite.mossy", "minecraft:block/cobble_granite_mossy", 18, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.GRAVEL))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
 
-    public static final Block<?> PILLAR_MARBLE = register("pillar.marble", "minecraft:block/pillar_marble", 20, (b) -> new BlockLogicAxisAligned(b, Materials.MARBLE))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> CAPSTONE_MARBLE = register("capstone.marble", "minecraft:block/capstone_marble", 21, (b) -> new BlockLogic(b, Materials.MARBLE))
+    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()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> SANDSTONE = register("sandstone", "minecraft:block/sandstone", 30, (b) -> new BlockLogicSandstone(b, Materials.STONE))
+    public static final @NotNull Block<?> SANDSTONE = register("sandstone", "minecraft:block/sandstone", 30, (b) -> new BlockLogicSandstone(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(0.8F).withOverrideColor(MaterialColor.sand)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> STONE_CARVED = register("stone.carved", "minecraft:block/stone_carved", 40, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> STONE_CARVED = register("stone.carved", "minecraft:block/stone_carved", 40, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> GRANITE_CARVED = register("granite.carved", "minecraft:block/granite_carved", 41, (b) -> new BlockLogic(b, Materials.GRANITE))
+    public static final @NotNull Block<?> GRANITE_CARVED = register("granite.carved", "minecraft:block/granite_carved", 41, (b) -> new BlockLogic(b, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> LIMESTONE_CARVED = register("limestone.carved", "minecraft:block/limestone_carved", 42, (b) -> new BlockLogic(b, Materials.LIMESTONE))
+    public static final @NotNull Block<?> LIMESTONE_CARVED = register("limestone.carved", "minecraft:block/limestone_carved", 42, (b) -> new BlockLogic(b, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BASALT_CARVED = register("basalt.carved", "minecraft:block/basalt_carved", 43, (b) -> new BlockLogic(b, Materials.BASALT))
+    public static final @NotNull Block<?> BASALT_CARVED = register("basalt.carved", "minecraft:block/basalt_carved", 43, (b) -> new BlockLogic(b, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> PERMAFROST_CARVED = register("permafrost.carved", "minecraft:block/permafrost_carved", 44, (b) -> new BlockLogic(b, Materials.PERMAFROST))
+    public static final @NotNull Block<?> PERMAFROST_CARVED = register("permafrost.carved", "minecraft:block/permafrost_carved", 44, (b) -> new BlockLogic(b, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(1.0F).withBlastResistance(10F).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> NETHERRACK_CARVED = register("netherrack.carved", "minecraft:block/netherrack_carved", 45, (b) -> new BlockLogic(b, Materials.NETHERRACK))
+    public static final @NotNull Block<?> NETHERRACK_CARVED = register("netherrack.carved", "minecraft:block/netherrack_carved", 45, (b) -> new BlockLogic(b, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F).withBlastResistance(1F).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> PLANKS_OAK = register("planks.oak", "minecraft:block/planks_oak", 50, BlockLogicPlanks::new)
+    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()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicPlanksPainted> PLANKS_OAK_PAINTED = register("planks.oak.painted", "minecraft:block/planks_oak_painted", 51, BlockLogicPlanksPainted::new)
+    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()
         .setBlockItem((b) -> new ItemBlockPainted<>(b, false))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> TORCH_COAL = register("torch.coal", "minecraft:block/torch_coal", 60, BlockLogicTorch::new)
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS);
 //    public static final BlockContainer<?> candleSoulwax;
 
-    public static final Block<? extends BlockLogicLadder> LADDER_OAK = register("ladder.oak", "minecraft:block/ladder_oak", 70, BlockLogicLadder::new)
+    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()
         .setBlockItem(ItemBlockLadder::new)
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<BlockLogicFence> FENCE_PLANKS_OAK = register("fence.planks.oak", "minecraft:block/fence_planks_oak", 80, BlockLogicFence::new)
+    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()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE, BlockTags.CAN_HANG_OFF);
-    public static final Block<BlockLogicFencePainted> FENCE_PLANKS_OAK_PAINTED = register("fence.planks.oak.painted", "minecraft:block/fence_planks_oak_painted", 81, BlockLogicFencePainted::new)
+    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()
         .setBlockItem((b) -> new ItemBlockPainted<>(b, false))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE, BlockTags.CAN_HANG_OFF);
 
-    public static final Block<BlockLogicFenceGate> FENCE_GATE_PLANKS_OAK = register("fencegate.planks.oak", "minecraft:block/fence_gate_planks_oak", 90, BlockLogicFenceGate::new)
+    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()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicFenceGatePainted> FENCE_GATE_PLANKS_OAK_PAINTED = register("fencegate.planks.oak.painted", "minecraft:block/fence_gate_planks_oak_painted", 91, BlockLogicFenceGatePainted::new)
+    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()
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> BOOKSHELF_PLANKS_OAK = register("bookshelf.planks.oak", "minecraft:block/bookshelf_planks_oak", 100, (b) -> new BlockLogicBookshelf(b, Materials.WOOD))
+    public static final @NotNull Block<?> BOOKSHELF_PLANKS_OAK = register("bookshelf.planks.oak", "minecraft:block/bookshelf_planks_oak", 100, (b) -> new BlockLogicBookshelf(b, Materials.WOOD))
         .withSound(BlockSounds.WOOD).withHardness(1.5F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> WOOL = register("wool", "minecraft:block/wool", 110, BlockLogicWool::new)
+    public static final @NotNull Block<?> WOOL = register("wool", "minecraft:block/wool", 110, BlockLogicWool::new)
         .withSound(BlockSounds.CLOTH).withHardness(0.8F).withDisabledNeighborNotifyOnMetadataChange()
         .setBlockItem((b) -> new ItemBlockPainted<>(b, false))
         .withTags(BlockTags.MINEABLE_BY_SHEARS);
-    public static final Block<BlockLogicRope> ROPE = register("rope", "minecraft:block/rope", 111, BlockLogicRope::new)
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS, BlockTags.CAN_HANG_OFF, BlockTags.INSTANT_PICKUP);
 
-    public static final Block<?> BRICK_CLAY = register("brick.clay", "minecraft:block/brick_clay", 120, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BRICK_CLAY = register("brick.clay", "minecraft:block/brick_clay", 120, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3.0F).withBlastResistance(10F).withOverrideColor(MaterialColor.brick)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_STONE_POLISHED = register("brick.stone.polished", "minecraft:block/brick_stone_polished", 121, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BRICK_STONE_POLISHED = register("brick.stone.polished", "minecraft:block/brick_stone_polished", 121, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_STONE_POLISHED_MOSSY = register("brick.stone.polished.mossy", "minecraft:block/brick_stone_polished_mossy", 122, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BRICK_STONE_POLISHED_MOSSY = register("brick.stone.polished.mossy", "minecraft:block/brick_stone_polished_mossy", 122, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(2F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS);
-    public static final Block<?> BRICK_SANDSTONE = register("brick.sandstone", "minecraft:block/brick_sandstone", 123, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BRICK_SANDSTONE = register("brick.sandstone", "minecraft:block/brick_sandstone", 123, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(0.8F).withBlastResistance(10F).withOverrideColor(MaterialColor.sand)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_GOLD = register("brick.gold", "minecraft:block/brick_gold", 124, (b) -> new BlockLogic(b, Materials.METAL))
+    public static final @NotNull Block<?> BRICK_GOLD = register("brick.gold", "minecraft:block/brick_gold", 124, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.gold)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_LAPIS = register("brick.lapis", "minecraft:block/brick_lapis", 125, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BRICK_LAPIS = register("brick.lapis", "minecraft:block/brick_lapis", 125, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.lapis)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_BASALT = register("brick.basalt", "minecraft:block/brick_basalt", 126, (b) -> new BlockLogic(b, Materials.BASALT))
+    public static final @NotNull Block<?> BRICK_BASALT = register("brick.basalt", "minecraft:block/brick_basalt", 126, (b) -> new BlockLogic(b, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_LIMESTONE = register("brick.limestone", "minecraft:block/brick_limestone", 127, (b) -> new BlockLogic(b, Materials.LIMESTONE))
+    public static final @NotNull Block<?> BRICK_LIMESTONE = register("brick.limestone", "minecraft:block/brick_limestone", 127, (b) -> new BlockLogic(b, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_GRANITE = register("brick.granite", "minecraft:block/brick_granite", 128, (b) -> new BlockLogic(b, Materials.GRANITE))
+    public static final @NotNull Block<?> BRICK_GRANITE = register("brick.granite", "minecraft:block/brick_granite", 128, (b) -> new BlockLogic(b, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_MARBLE = register("brick.marble", "minecraft:block/brick_marble", 129, (b) -> new BlockLogic(b, Materials.MARBLE))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_SLATE = register("brick.slate", "minecraft:block/brick_slate", 130, (b) -> new BlockLogic(b, Materials.SLATE))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_STONE = register("brick.stone", "minecraft:block/brick_stone", 131, (b) -> new BlockLogic(b, Materials.STONE))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_PERMAFROST = register("brick.permafrost", "minecraft:block/brick_permafrost", 132, (b) -> new BlockLogic(b, Materials.PERMAFROST))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_IRON = register("brick.iron", "minecraft:block/brick_iron", 133, (b) -> new BlockLogic(b, Materials.METAL))
+    public static final @NotNull Block<?> BRICK_IRON = register("brick.iron", "minecraft:block/brick_iron", 133, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.iron)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BRICK_STEEL = register("brick.steel", "minecraft:block/brick_steel", 134, (b) -> new BlockLogic(b, Materials.STEEL))
+    public static final @NotNull Block<?> BRICK_STEEL = register("brick.steel", "minecraft:block/brick_steel", 134, (b) -> new BlockLogic(b, Materials.STEEL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(2000F).withOverrideColor(MaterialColor.steel)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<BlockLogicSlab> SLAB_PLANKS_OAK = register("slab.planks.oak", "minecraft:block/slab_planks_oak", 140, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlabPaintable(b, Blocks.PLANKS_OAK))
+    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)
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicSlab> SLAB_COBBLE_STONE = register("slab.cobble.stone", "minecraft:block/slab_cobble_stone", 141, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_STONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_SANDSTONE = register("slab.sandstone", "minecraft:block/slab_sandstone", 142, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.SANDSTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final 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))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_STONE_POLISHED = register("slab.stone.carved", "minecraft:block/slab_stone_carved", 144, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.STONE_CARVED))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_MARBLE = register("slab.brick.marble", "minecraft:block/slab_brick_marble", 145, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_MARBLE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_CLAY = register("slab.brick.clay", "minecraft:block/slab_brick_clay", 146, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_CLAY))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_CAPSTONE_MARBLE = register("slab.capstone.marble", "minecraft:block/slab_capstone_marble", 147, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.CAPSTONE_MARBLE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_COBBLE_BASALT = register("slab.cobble.basalt", "minecraft:block/slab_cobble_basalt", 148, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_BASALT))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_COBBLE_LIMESTONE = register("slab.cobble.limestone", "minecraft:block/slab_cobble_limestone", 149, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_LIMESTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_COBBLE_GRANITE = register("slab.cobble.granite", "minecraft:block/slab_cobble_granite", 150, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_GRANITE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_BASALT = register("slab.brick.basalt", "minecraft:block/slab_brick_basalt", 151, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_BASALT))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_LIMESTONE = register("slab.brick.limestone", "minecraft:block/slab_brick_limestone", 152, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_LIMESTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_GRANITE = register("slab.brick.granite", "minecraft:block/slab_brick_granite", 153, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_GRANITE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final 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))
+    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)
         .setBlockItem(ItemBlockSlabPainted::new)
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_SLATE = register("slab.brick.slate", "minecraft:block/slab_brick_slate", 155, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_SLATE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_STONE = register("slab.brick.stone", "minecraft:block/slab_brick_stone", 156, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_STONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_GRANITE_POLISHED = register("slab.granite.carved", "minecraft:block/slab_granite_carved", 157, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.GRANITE_CARVED))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_LIMESTONE_POLISHED = register("slab.limestone.carved", "minecraft:block/slab_limestone_carved", 158, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.LIMESTONE_CARVED))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BASALT_POLISHED = register("slab.basalt.carved", "minecraft:block/slab_basalt_carved", 159, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BASALT_CARVED))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<BlockLogicStairs> STAIRS_PLANKS_OAK = register("stairs.planks.oak", "minecraft:block/stairs_planks_oak", 160, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairsPaintable(b, Blocks.PLANKS_OAK))
+    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)
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicStairs> STAIRS_COBBLE_STONE = register("stairs.cobble.stone", "minecraft:block/stairs_cobble_stone", 161, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_STONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final 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))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_MARBLE = register("stairs.brick.marble", "minecraft:block/stairs_brick_marble", 163, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_MARBLE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_COBBLE_BASALT = register("stairs.cobble.basalt", "minecraft:block/stairs_cobble_basalt", 164, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_BASALT))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_COBBLE_LIMESTONE = register("stairs.cobble.limestone", "minecraft:block/stairs_cobble_limestone", 165, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_LIMESTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_COBBLE_GRANITE = register("stairs.cobble.granite", "minecraft:block/stairs_cobble_granite", 166, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_GRANITE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_BASALT = register("stairs.brick.basalt", "minecraft:block/stairs_brick_basalt", 167, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_BASALT))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_LIMESTONE = register("stairs.brick.limestone", "minecraft:block/stairs_brick_limestone", 168, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_LIMESTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_GRANITE = register("stairs.brick.granite", "minecraft:block/stairs_brick_granite", 169, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_GRANITE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_CLAY = register("stairs.brick.clay", "minecraft:block/stairs_brick_clay", 170, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_CLAY))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final 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))
+    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)
         .setBlockItem(ItemBlockStairsPainted::new)
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_SLATE = register("stairs.brick.slate", "minecraft:block/stairs_brick_slate", 172, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_SLATE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_STONE = register("stairs.brick.stone", "minecraft:block/stairs_brick_stone", 173, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_STONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_SANDSTONE = register("stairs.sandstone", "minecraft:block/stairs_sandstone", 174, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.SANDSTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_SANDSTONE = register("stairs.brick.sandstone", "minecraft:block/stairs_brick_sandstone", 175, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_SANDSTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_COBBLE_PERMAFROST = register("stairs.cobble.permafrost", "minecraft:block/stairs_cobble_permafrost", 176, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_PERMAFROST))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_PERMAFROST = register("stairs.brick.permafrost", "minecraft:block/stairs_brick_permafrost", 177, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_PERMAFROST))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> OBSIDIAN = register("obsidian", "minecraft:block/obsidian", 180, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> OBSIDIAN = register("obsidian", "minecraft:block/obsidian", 180, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(10F).withBlastResistance(2000F).withOverrideColor(MaterialColor.paintedBlack).withImmovableFlagSet()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PISTON_CRUSHING);
 
-    public static final Block<?> GLASS = register("glass", "minecraft:block/glass", 190, (b) -> new BlockLogicGlass(b, Materials.GLASS))
+    public static final @NotNull Block<?> GLASS = register("glass", "minecraft:block/glass", 190, (b) -> new BlockLogicGlass(b, Materials.GLASS))
         .withSound(BlockSounds.GLASS).withHardness(0.3F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.EXTENDS_MOTION_SENSOR_RANGE);
-    public static final Block<?> GLASS_TINTED = register("glass.tinted", "minecraft:block/glass_tinted", 191, BlockLogicGlassTinted::new)
+    public static final @NotNull Block<?> GLASS_TINTED = register("glass.tinted", "minecraft:block/glass_tinted", 191, BlockLogicGlassTinted::new)
         .withSound(BlockSounds.GLASS).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> GLASS_STEEL = register("glass.steel", "minecraft:block/glass_steel", 192, (b) -> new BlockLogicTransparent(b, Materials.GLASS))
+    public static final @NotNull Block<?> GLASS_STEEL = register("glass.steel", "minecraft:block/glass_steel", 192, (b) -> new BlockLogicTransparent(b, Materials.GLASS))
         .withSound(BlockSounds.GLASS).withHardness(0.3F).withBlastResistance(2000F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.EXTENDS_MOTION_SENSOR_RANGE);
 
-    public static final Block<?> GRASS = register("grass", "minecraft:block/grass", 200, (b) -> new BlockLogicGrass(b, Blocks.DIRT))
+    public static final @NotNull Block<?> GRASS = register("grass", "minecraft:block/grass", 200, (b) -> new BlockLogicGrass(b, Blocks.DIRT))
         .withSound(BlockSounds.GRASS).withHardness(0.6F)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE, BlockTags.PASSIVE_MOBS_SPAWN, BlockTags.FIREFLIES_CAN_SPAWN, BlockTags.GROWS_TREES, BlockTags.CAVES_CUT_THROUGH, BlockTags.CAVE_GEN_REPLACES_SURFACE);
-    public static final Block<?> GRASS_RETRO = register("grass.retro", "minecraft:block/grass_retro", 201, (b) -> new BlockLogicGrass(b, Blocks.DIRT))
+    public static final @NotNull Block<?> GRASS_RETRO = register("grass.retro", "minecraft:block/grass_retro", 201, (b) -> new BlockLogicGrass(b, Blocks.DIRT))
         .withSound(BlockSounds.GRASS).withHardness(0.6F)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE, BlockTags.PASSIVE_MOBS_SPAWN, BlockTags.FIREFLIES_CAN_SPAWN, BlockTags.GROWS_TREES, BlockTags.CAVES_CUT_THROUGH, BlockTags.CAVE_GEN_REPLACES_SURFACE);
-    public static final Block<?> GRASS_SCORCHED = register("grass.scorched", "minecraft:block/grass_scorched", 202, (b) -> new BlockLogicGrass(b, Blocks.DIRT_SCORCHED))
+    public static final @NotNull Block<?> GRASS_SCORCHED = register("grass.scorched", "minecraft:block/grass_scorched", 202, (b) -> new BlockLogicGrass(b, Blocks.DIRT_SCORCHED))
         .withSound(BlockSounds.GRASS).withHardness(0.6F).withOverrideColor(MaterialColor.grassScorched)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE, BlockTags.GROWS_TREES, BlockTags.CAVES_CUT_THROUGH, BlockTags.PASSIVE_MOBS_SPAWN, BlockTags.FIREFLIES_CAN_SPAWN, BlockTags.GROWS_CACTI, BlockTags.CAVE_GEN_REPLACES_SURFACE);
 
-    public static final Block<?> PATH_DIRT = register("path.dirt", "minecraft:block/path_dirt", 210, BlockLogicPathDirt::new)
+    public static final @NotNull Block<?> PATH_DIRT = register("path.dirt", "minecraft:block/path_dirt", 210, BlockLogicPathDirt::new)
         .withSound(BlockSounds.GRAVEL).withHardness(0.5F).withLitInteriorSurface(true).withOverrideColor(MaterialColor.grassScorched)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL);
 
-    public static final Block<?> DIRT = register("dirt", "minecraft:block/dirt", 220, (b) -> new BlockLogic(b, Materials.DIRT))
+    public static final @NotNull Block<?> DIRT = register("dirt", "minecraft:block/dirt", 220, (b) -> new BlockLogic(b, Materials.DIRT))
         .withSound(BlockSounds.GRAVEL).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE, BlockTags.GROWS_TREES, BlockTags.CAVES_CUT_THROUGH);
-    public static final Block<?> DIRT_SCORCHED = register("dirt.scorched", "minecraft:block/dirt_scorched", 221, (b) -> new BlockLogic(b, Materials.DIRT))
+    public static final @NotNull Block<?> DIRT_SCORCHED = register("dirt.scorched", "minecraft:block/dirt_scorched", 221, (b) -> new BlockLogic(b, Materials.DIRT))
         .withSound(BlockSounds.GRAVEL).withHardness(0.5F).withOverrideColor(MaterialColor.dirtScorched)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE, BlockTags.GROWS_CACTI, BlockTags.GROWS_TREES, BlockTags.CAVES_CUT_THROUGH);
-    public static final Block<?> DIRT_SCORCHED_RICH = register("dirt.scorched.rich", "minecraft:block/dirt_scorched_rich", 222, (b) -> new BlockLogic(b, Materials.DIRT))
+    public static final @NotNull Block<?> DIRT_SCORCHED_RICH = register("dirt.scorched.rich", "minecraft:block/dirt_scorched_rich", 222, (b) -> new BlockLogic(b, Materials.DIRT))
         .withSound(BlockSounds.GRAVEL).withHardness(0.6F).withOverrideColor(MaterialColor.dirtScorched)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE, BlockTags.GROWS_CACTI, BlockTags.CAVES_CUT_THROUGH);
 
-    public static final Block<?> MUD = register("mud", "minecraft:block/mud", 225, (b) -> new BlockLogicMud(b, Materials.DIRT, false))
+    public static final @NotNull Block<?> MUD = register("mud", "minecraft:block/mud", 225, (b) -> new BlockLogicMud(b, Materials.DIRT, false))
         .withSound(BlockSounds.GRAVEL).withHardness(0.6F).withOverrideColor(MaterialColor.mud)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_CACTI, BlockTags.GROWS_TREES, BlockTags.CAVES_CUT_THROUGH, BlockTags.GROWS_SUGAR_CANE);
-    public static final Block<?> MUD_BAKED = register("mud.baked", "minecraft:block/mud_baked", 226, (b) -> new BlockLogicMud(b, Materials.STEEL, true))
+    public static final @NotNull Block<?> MUD_BAKED = register("mud.baked", "minecraft:block/mud_baked", 226, (b) -> new BlockLogicMud(b, Materials.STEEL, true))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withOverrideColor(MaterialColor.dirt)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_CACTI, BlockTags.GROWS_TREES, BlockTags.CAVES_CUT_THROUGH, BlockTags.GROWS_SUGAR_CANE);
 
-    public static final Block<?> SPONGE_DRY = register("sponge.dry", "minecraft:block/sponge_dry", 230, (b) -> new BlockLogicSponge(b, false))
+    public static final @NotNull Block<?> SPONGE_DRY = register("sponge.dry", "minecraft:block/sponge_dry", 230, (b) -> new BlockLogicSponge(b, false))
         .withSound(BlockSounds.GRASS).withHardness(0.6F).withOverrideColor(MaterialColor.paintedYellow)
         .withTags(BlockTags.MINEABLE_BY_SHEARS);
-    public static final Block<?> SPONGE_WET = register("sponge.wet", "minecraft:block/sponge_wet", 231, (b) -> new BlockLogicSponge(b, true))
+    public static final @NotNull Block<?> SPONGE_WET = register("sponge.wet", "minecraft:block/sponge_wet", 231, (b) -> new BlockLogicSponge(b, true))
         .withSound(BlockSounds.GRASS).withHardness(1.0F).withOverrideColor(MaterialColor.paintedYellow)
         .withTags(BlockTags.MINEABLE_BY_SHEARS);
-    public static final Block<?> PUMICE_DRY = register("pumice.dry", "minecraft:block/pumice_dry", 232, (b) -> new BlockLogicPumice(b, false))
+    public static final @NotNull Block<?> PUMICE_DRY = register("pumice.dry", "minecraft:block/pumice_dry", 232, (b) -> new BlockLogicPumice(b, false))
         .withSound(BlockSounds.STONE).withHardness(0.6F).withOverrideColor(MaterialColor.fire)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> PUMICE_WET = register("pumice.wet", "minecraft:block/pumice_wet", 233, (b) -> new BlockLogicPumice(b, true))
+    public static final @NotNull Block<?> PUMICE_WET = register("pumice.wet", "minecraft:block/pumice_wet", 233, (b) -> new BlockLogicPumice(b, true))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withLightEmission(0.625F).withOverrideColor(MaterialColor.fire)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> MOSS_STONE = register("moss.stone", "minecraft:block/moss_stone", 240, (b) -> new BlockLogicMoss(b, Blocks.STONE))
+    public static final @NotNull Block<?> MOSS_STONE = register("moss.stone", "minecraft:block/moss_stone", 240, (b) -> new BlockLogicMoss(b, Blocks.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
-    public static final Block<?> MOSS_BASALT = register("moss.basalt", "minecraft:block/moss_basalt", 241, (b) -> new BlockLogicMoss(b, Blocks.BASALT))
+    public static final @NotNull Block<?> MOSS_BASALT = register("moss.basalt", "minecraft:block/moss_basalt", 241, (b) -> new BlockLogicMoss(b, Blocks.BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
-    public static final Block<?> MOSS_LIMESTONE = register("moss.limestone", "minecraft:block/moss_limestone", 242, (b) -> new BlockLogicMoss(b, Blocks.LIMESTONE))
+    public static final @NotNull Block<?> MOSS_LIMESTONE = register("moss.limestone", "minecraft:block/moss_limestone", 242, (b) -> new BlockLogicMoss(b, Blocks.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
-    public static final Block<?> MOSS_GRANITE = register("moss.granite", "minecraft:block/moss_granite", 243, (b) -> new BlockLogicMoss(b, Blocks.GRANITE))
+    public static final @NotNull Block<?> MOSS_GRANITE = register("moss.granite", "minecraft:block/moss_granite", 243, (b) -> new BlockLogicMoss(b, Blocks.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.GROWS_SUGAR_CANE);
 
-    public static final Block<?> SAND = register("sand", "minecraft:block/sand", 250, BlockLogicSand::new)
+    public static final @NotNull Block<?> SAND = register("sand", "minecraft:block/sand", 250, BlockLogicSand::new)
         .withSound(BlockSounds.SAND).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.GROWS_SUGAR_CANE, BlockTags.GROWS_CACTI, BlockTags.CAVES_CUT_THROUGH, BlockTags.FIREFLIES_CAN_SPAWN);
-    public static final Block<?> GRAVEL = register("gravel", "minecraft:block/gravel", 251, BlockLogicGravel::new)
+    public static final @NotNull Block<?> GRAVEL = register("gravel", "minecraft:block/gravel", 251, BlockLogicGravel::new)
         .withSound(BlockSounds.GRAVEL).withHardness(0.6F)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL);
-    public static final Block<?> SULFUR = register("sulfur", "minecraft:block/sulfur", 252, (b) -> new BlockLogic(b, Materials.SAND))
+    public static final @NotNull Block<?> SULFUR = register("sulfur", "minecraft:block/sulfur", 252, (b) -> new BlockLogic(b, Materials.SAND))
             .withSound(BlockSounds.SAND).withHardness(0.7F)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL);
 
-    public static final Block<?> BEDROCK = register("bedrock", "minecraft:block/bedrock", 260, (b) -> new BlockLogicBedrock(b, Materials.STONE))
+    public static final @NotNull Block<?> BEDROCK = register("bedrock", "minecraft:block/bedrock", 260, (b) -> new BlockLogicBedrock(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withSetUnbreakable().withBlastResistance(6000000F).withImmovableFlagSet()
         .withTags(BlockTags.PISTON_CRUSHING);
-    public static final Block<?> BONESHALE = register("boneshale", "minecraft:block/boneshale", 261, (b) -> new BlockLogicBoneShale(b, Materials.STONE))
+    public static final @NotNull Block<?> BONESHALE = register("boneshale", "minecraft:block/boneshale", 261, (b) -> new BlockLogicBoneShale(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(16F).withBlastResistance(6000000F).withImmovableFlagSet()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
 
-    public static final 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))
+    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()
         .withTags(BlockTags.IS_WATER, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final 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))
+    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)
         .withTags(BlockTags.IS_WATER, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final 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))
+    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()
         .withTags(BlockTags.IS_LAVA, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final 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))
+    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)
         .withTags(BlockTags.IS_LAVA, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<?> LOG_OAK = register("log.oak", "minecraft:block/log_oak", 280, BlockLogicLog::new)
+    public static final @NotNull Block<?> LOG_OAK = register("log.oak", "minecraft:block/log_oak", 280, BlockLogicLog::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> LOG_PINE = register("log.pine", "minecraft:block/log_pine", 281, BlockLogicLog::new)
+    public static final @NotNull Block<?> LOG_PINE = register("log.pine", "minecraft:block/log_pine", 281, BlockLogicLog::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> LOG_BIRCH = register("log.birch", "minecraft:block/log_birch", 282, BlockLogicLog::new)
+    public static final @NotNull Block<?> LOG_BIRCH = register("log.birch", "minecraft:block/log_birch", 282, BlockLogicLog::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> LOG_CHERRY = register("log.cherry", "minecraft:block/log_cherry", 283, BlockLogicLog::new)
+    public static final @NotNull Block<?> LOG_CHERRY = register("log.cherry", "minecraft:block/log_cherry", 283, BlockLogicLog::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> LOG_EUCALYPTUS = register("log.eucalyptus", "minecraft:block/log_eucalyptus", 284, BlockLogicLog::new)
+    public static final @NotNull Block<?> LOG_EUCALYPTUS = register("log.eucalyptus", "minecraft:block/log_eucalyptus", 284, BlockLogicLog::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> LOG_OAK_MOSSY = register("log.oak.mossy", "minecraft:block/log_oak_mossy", 285, BlockLogicLog::new)
+    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()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE, BlockTags.GROWS_FLOWERS);
-    public static final Block<?> LOG_THORN = register("log.thorn", "minecraft:block/log_thorn", 286, BlockLogicLog::new)
+    public static final @NotNull Block<?> LOG_THORN = register("log.thorn", "minecraft:block/log_thorn", 286, BlockLogicLog::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> LOG_PALM = register("log.palm", "minecraft:block/log_palm", 287, BlockLogicLog::new)
+    public static final @NotNull Block<?> LOG_PALM = register("log.palm", "minecraft:block/log_palm", 287, BlockLogicLog::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> LEAVES_OAK = register("leaves.oak", "minecraft:block/leaves_oak", 290, BlockLogicLeavesOak::new)
+    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()
         .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 Block<?> LEAVES_OAK_RETRO = register("leaves.oak.retro", "minecraft:block/leaves_oak_retro", 291, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_OAK_RETRO))
+    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()
         .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 Block<?> LEAVES_PINE = register("leaves.pine", "minecraft:block/leaves_pine", 292, BlockLogicLeavesPine::new)
+    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)
         .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 Block<?> LEAVES_BIRCH = register("leaves.birch", "minecraft:block/leaves_birch", 293, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_BIRCH))
+    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)
         .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 Block<?> LEAVES_CHERRY = register("leaves.cherry", "minecraft:block/leaves_cherry", 294, BlockLogicLeavesCherry::new)
+    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)
         .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 Block<?> LEAVES_EUCALYPTUS = register("leaves.eucalyptus", "minecraft:block/leaves_eucalyptus", 295, BlockLogicLeavesEucalyptus::new)
+    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()
         .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 Block<?> LEAVES_SHRUB = register("leaves.shrub", "minecraft:block/leaves_shrub", 296, BlockLogicLeavesShrub::new)
+    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()
         .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 Block<?> LEAVES_CHERRY_FLOWERING = register("leaves.cherry.flowering", "minecraft:block/leaves_cherry_flowering", 297, BlockLogicLeavesCherryFlowering::new)
+    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)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
-    public static final Block<?> LEAVES_CACAO = register("leaves.cacao", "minecraft:block/leaves_cacao", 298, BlockLogicLeavesCacao::new)
+    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()
         .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 Block<?> LEAVES_THORN = register("leaves.thorn", "minecraft:block/leaves_thorn", 299, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_THORN))
+    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)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
-    public static final Block<?> LEAVES_PALM = register("leaves.palm", "minecraft:block/leaves_palm", 300, (b) -> new BlockLogicLeavesBase(b, Materials.LEAVES, Blocks.SAPLING_PALM))
+    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)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_SHEARS);
 
-    public static final Block<?> SAPLING_OAK = register("sapling.oak", "minecraft:block/sapling_oak", 310, BlockLogicSaplingOak::new)
+    public static final @NotNull Block<?> SAPLING_OAK = register("sapling.oak", "minecraft:block/sapling_oak", 310, BlockLogicSaplingOak::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_OAK_RETRO = register("sapling.oak.retro", "minecraft:block/sapling_oak_retro", 311, BlockLogicSaplingRetro::new)
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_PINE = register("sapling.pine", "minecraft:block/sapling_pine", 312, BlockLogicSaplingPine::new)
+    public static final @NotNull Block<?> SAPLING_PINE = register("sapling.pine", "minecraft:block/sapling_pine", 312, BlockLogicSaplingPine::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_BIRCH = register("sapling.birch", "minecraft:block/sapling_birch", 313, BlockLogicSaplingBirch::new)
+    public static final @NotNull Block<?> SAPLING_BIRCH = register("sapling.birch", "minecraft:block/sapling_birch", 313, BlockLogicSaplingBirch::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_CHERRY = register("sapling.cherry", "minecraft:block/sapling_cherry", 314, BlockLogicSaplingCherry::new)
+    public static final @NotNull Block<?> SAPLING_CHERRY = register("sapling.cherry", "minecraft:block/sapling_cherry", 314, BlockLogicSaplingCherry::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_EUCALYPTUS = register("sapling.eucalyptus", "minecraft:block/sapling_eucalyptus", 315, BlockLogicSaplingEucalyptus::new)
+    public static final @NotNull Block<?> SAPLING_EUCALYPTUS = register("sapling.eucalyptus", "minecraft:block/sapling_eucalyptus", 315, BlockLogicSaplingEucalyptus::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_SHRUB = register("sapling.shrub", "minecraft:block/sapling_shrub", 316, BlockLogicSaplingShrub::new)
+    public static final @NotNull Block<?> SAPLING_SHRUB = register("sapling.shrub", "minecraft:block/sapling_shrub", 316, BlockLogicSaplingShrub::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_CACAO = register("sapling.cacao", "minecraft:block/sapling_cacao", 317, BlockLogicSaplingCacao::new)
+    public static final @NotNull Block<?> SAPLING_CACAO = register("sapling.cacao", "minecraft:block/sapling_cacao", 317, BlockLogicSaplingCacao::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_THORN = register("sapling.thorn", "minecraft:block/sapling_thorn", 318, BlockLogicSaplingThorn::new)
+    public static final @NotNull Block<?> SAPLING_THORN = register("sapling.thorn", "minecraft:block/sapling_thorn", 318, BlockLogicSaplingThorn::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SAPLING_PALM = register("sapling.palm", "minecraft:block/sapling_palm", 319, BlockLogicSaplingPalm::new)
+    public static final @NotNull Block<?> SAPLING_PALM = register("sapling.palm", "minecraft:block/sapling_palm", 319, BlockLogicSaplingPalm::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR);
 
-    public static final Block<?> TALLGRASS = register("tallgrass", "minecraft:block/tallgrass", 320, b -> new BlockLogicTallGrass(b).setKilledByWeather())
+    public static final @NotNull Block<?> TALLGRASS = register("tallgrass", "minecraft:block/tallgrass", 320, b -> new BlockLogicTallGrass(b).setKilledByWeather())
         .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.SHEEPS_FAVOURITE_BLOCK);
-    public static final Block<?> TALLGRASS_FERN = register("tallgrass.fern", "minecraft:block/tallgrass_fern", 321, b -> new BlockLogicTallGrass(b).setKilledByWeather())
+    public static final @NotNull Block<?> TALLGRASS_FERN = register("tallgrass.fern", "minecraft:block/tallgrass_fern", 321, b -> new BlockLogicTallGrass(b).setKilledByWeather())
         .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.PLANTABLE_IN_JAR, BlockTags.SHEEPS_FAVOURITE_BLOCK);
-    public static final Block<?> DEADBUSH = register("deadbush", "minecraft:block/deadbush", 322, BlockLogicDeadBush::new)
+    public static final @NotNull Block<?> DEADBUSH = register("deadbush", "minecraft:block/deadbush", 322, BlockLogicDeadBush::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.wood)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.PLANTABLE_IN_JAR);
-    public static final Block<?> SPINIFEX = register("spinifex", "minecraft:block/spinifex", 323, BlockLogicSpinifex::new)
+    public static final @NotNull Block<?> SPINIFEX = register("spinifex", "minecraft:block/spinifex", 323, BlockLogicSpinifex::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.SHEARS_DO_SILK_TOUCH);
-    public static final Block<?> ALGAE = register("algae", "minecraft:block/algae", 324, (b) -> new BlockLogicAlgae(b, Materials.PLANT))
+    public static final @NotNull Block<?> ALGAE = register("algae", "minecraft:block/algae", 324, (b) -> new BlockLogicAlgae(b, Materials.PLANT))
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withLitInteriorSurface(true)
         .setBlockItem(ItemBlockAlgae::new)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.SHEARS_DO_SILK_TOUCH);
 
-    public static final Block<BlockLogicFlowerStackable> FLOWER_YELLOW = register("flower.yellow", "minecraft:block/flower_yellow", 330, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
+    public static final @NotNull Block<BlockLogicFlowerStackable> FLOWER_YELLOW = register("flower.yellow", "minecraft:block/flower_yellow", 330, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedYellow)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.SHEEPS_FAVOURITE_BLOCK, BlockTags.SHEARS_DO_SILK_TOUCH);
-    public static final Block<BlockLogicFlowerStackable> FLOWER_RED = register("flower.red", "minecraft:block/flower_red", 331, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
+    public static final @NotNull Block<BlockLogicFlowerStackable> FLOWER_RED = register("flower.red", "minecraft:block/flower_red", 331, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedRed)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.SHEEPS_FAVOURITE_BLOCK, BlockTags.SHEARS_DO_SILK_TOUCH);
-    public static final Block<BlockLogicFlowerStackable> FLOWER_PINK = register("flower.pink", "minecraft:block/flower_pink", 332, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
+    public static final @NotNull Block<BlockLogicFlowerStackable> FLOWER_PINK = register("flower.pink", "minecraft:block/flower_pink", 332, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedPink)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.SHEEPS_FAVOURITE_BLOCK, BlockTags.SHEARS_DO_SILK_TOUCH);
-    public static final Block<BlockLogicFlowerStackable> FLOWER_PURPLE = register("flower.purple", "minecraft:block/flower_purple", 333, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
+    public static final @NotNull Block<BlockLogicFlowerStackable> FLOWER_PURPLE = register("flower.purple", "minecraft:block/flower_purple", 333, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedPurple)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.SHEEPS_FAVOURITE_BLOCK, BlockTags.SHEARS_DO_SILK_TOUCH);
-    public static final Block<BlockLogicFlowerStackable> FLOWER_LIGHT_BLUE = register("flower.lightblue", "minecraft:block/flower_light_blue", 334, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
+    public static final @NotNull Block<BlockLogicFlowerStackable> FLOWER_LIGHT_BLUE = register("flower.lightblue", "minecraft:block/flower_light_blue", 334, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedLightblue)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.SHEEPS_FAVOURITE_BLOCK, BlockTags.SHEARS_DO_SILK_TOUCH);
-    public static final Block<BlockLogicFlowerStackable> FLOWER_ORANGE = register("flower.orange", "minecraft:block/flower_orange", 335, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
+    public static final @NotNull Block<BlockLogicFlowerStackable> FLOWER_ORANGE = register("flower.orange", "minecraft:block/flower_orange", 335, (BlockLogicSupplier<BlockLogicFlowerStackable>)b -> (BlockLogicFlowerStackable) new BlockLogicFlowerStackable(b).setKilledByWeather().setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedOrange)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.SHEEPS_FAVOURITE_BLOCK, BlockTags.SHEARS_DO_SILK_TOUCH);
 
-    public static final Block<?> MUSHROOM_BROWN = register("mushroom.brown", "minecraft:block/mushroom_brown", 340, (b) -> new BlockLogicMushroom(b).setBonemealable())
+    public static final @NotNull Block<?> MUSHROOM_BROWN = register("mushroom.brown", "minecraft:block/mushroom_brown", 340, (b) -> new BlockLogicMushroom(b).setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withLightEmission(0.125F).withOverrideColor(MaterialColor.paintedBrown)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.PIGS_FAVOURITE_BLOCK);
-    public static final Block<?> MUSHROOM_RED = register("mushroom.red", "minecraft:block/mushroom_red", 341, (b) -> new BlockLogicMushroom(b).setBonemealable())
+    public static final @NotNull Block<?> MUSHROOM_RED = register("mushroom.red", "minecraft:block/mushroom_red", 341, (b) -> new BlockLogicMushroom(b).setBonemealable())
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedRed)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLANTABLE_IN_JAR, BlockTags.PIGS_FAVOURITE_BLOCK);
 
-    public static final Block<?> ORE_COAL_STONE = register("ore.coal.stone", "minecraft:block/ore_coal_stone", 350, (b) -> new BlockLogicOreCoal(b, Blocks.STONE, Materials.STONE))
+    public static final @NotNull Block<?> ORE_COAL_STONE = register("ore.coal.stone", "minecraft:block/ore_coal_stone", 350, (b) -> new BlockLogicOreCoal(b, Blocks.STONE, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_COAL_BASALT = register("ore.coal.basalt", "minecraft:block/ore_coal_basalt", 351, (b) -> new BlockLogicOreCoal(b, Blocks.BASALT, Materials.BASALT))
+    public static final @NotNull Block<?> ORE_COAL_BASALT = register("ore.coal.basalt", "minecraft:block/ore_coal_basalt", 351, (b) -> new BlockLogicOreCoal(b, Blocks.BASALT, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_COAL_LIMESTONE = register("ore.coal.limestone", "minecraft:block/ore_coal_limestone", 352, (b) -> new BlockLogicOreCoal(b, Blocks.LIMESTONE, Materials.LIMESTONE))
+    public static final @NotNull Block<?> ORE_COAL_LIMESTONE = register("ore.coal.limestone", "minecraft:block/ore_coal_limestone", 352, (b) -> new BlockLogicOreCoal(b, Blocks.LIMESTONE, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_COAL_GRANITE = register("ore.coal.granite", "minecraft:block/ore_coal_granite", 353, (b) -> new BlockLogicOreCoal(b, Blocks.GRANITE, Materials.GRANITE))
+    public static final @NotNull Block<?> ORE_COAL_GRANITE = register("ore.coal.granite", "minecraft:block/ore_coal_granite", 353, (b) -> new BlockLogicOreCoal(b, Blocks.GRANITE, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_COAL_PERMAFROST = register("ore.coal.permafrost", "minecraft:block/ore_coal_permafrost", 354, (b) -> new BlockLogicOreCoal(b, Blocks.PERMAFROST, Materials.PERMAFROST))
+    public static final @NotNull Block<?> ORE_COAL_PERMAFROST = register("ore.coal.permafrost", "minecraft:block/ore_coal_permafrost", 354, (b) -> new BlockLogicOreCoal(b, Blocks.PERMAFROST, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> ORE_IRON_STONE = register("ore.iron.stone", "minecraft:block/ore_iron_stone", 360, (b) -> new BlockLogicOreIron(b, Blocks.STONE, Materials.STONE))
+    public static final @NotNull Block<?> ORE_IRON_STONE = register("ore.iron.stone", "minecraft:block/ore_iron_stone", 360, (b) -> new BlockLogicOreIron(b, Blocks.STONE, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_IRON_BASALT = register("ore.iron.basalt", "minecraft:block/ore_iron_basalt", 361, (b) -> new BlockLogicOreIron(b, Blocks.BASALT, Materials.BASALT))
+    public static final @NotNull Block<?> ORE_IRON_BASALT = register("ore.iron.basalt", "minecraft:block/ore_iron_basalt", 361, (b) -> new BlockLogicOreIron(b, Blocks.BASALT, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_IRON_LIMESTONE = register("ore.iron.limestone", "minecraft:block/ore_iron_limestone", 362, (b) -> new BlockLogicOreIron(b, Blocks.LIMESTONE, Materials.LIMESTONE))
+    public static final @NotNull Block<?> ORE_IRON_LIMESTONE = register("ore.iron.limestone", "minecraft:block/ore_iron_limestone", 362, (b) -> new BlockLogicOreIron(b, Blocks.LIMESTONE, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_IRON_GRANITE = register("ore.iron.granite", "minecraft:block/ore_iron_granite", 363, (b) -> new BlockLogicOreIron(b, Blocks.GRANITE, Materials.GRANITE))
+    public static final @NotNull Block<?> ORE_IRON_GRANITE = register("ore.iron.granite", "minecraft:block/ore_iron_granite", 363, (b) -> new BlockLogicOreIron(b, Blocks.GRANITE, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_IRON_PERMAFROST = register("ore.iron.permafrost", "minecraft:block/ore_iron_permafrost", 364, (b) -> new BlockLogicOreIron(b, Blocks.PERMAFROST, Materials.PERMAFROST))
+    public static final @NotNull Block<?> ORE_IRON_PERMAFROST = register("ore.iron.permafrost", "minecraft:block/ore_iron_permafrost", 364, (b) -> new BlockLogicOreIron(b, Blocks.PERMAFROST, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> ORE_GOLD_STONE = register("ore.gold.stone", "minecraft:block/ore_gold_stone", 370, (b) -> new BlockLogicOreGold(b, Blocks.STONE, Materials.STONE))
+    public static final @NotNull Block<?> ORE_GOLD_STONE = register("ore.gold.stone", "minecraft:block/ore_gold_stone", 370, (b) -> new BlockLogicOreGold(b, Blocks.STONE, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_GOLD_BASALT = register("ore.gold.basalt", "minecraft:block/ore_gold_basalt", 371, (b) -> new BlockLogicOreGold(b, Blocks.BASALT, Materials.BASALT))
+    public static final @NotNull Block<?> ORE_GOLD_BASALT = register("ore.gold.basalt", "minecraft:block/ore_gold_basalt", 371, (b) -> new BlockLogicOreGold(b, Blocks.BASALT, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_GOLD_LIMESTONE = register("ore.gold.limestone", "minecraft:block/ore_gold_limestone", 372, (b) -> new BlockLogicOreGold(b, Blocks.LIMESTONE, Materials.LIMESTONE))
+    public static final @NotNull Block<?> ORE_GOLD_LIMESTONE = register("ore.gold.limestone", "minecraft:block/ore_gold_limestone", 372, (b) -> new BlockLogicOreGold(b, Blocks.LIMESTONE, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_GOLD_GRANITE = register("ore.gold.granite", "minecraft:block/ore_gold_granite", 373, (b) -> new BlockLogicOreGold(b, Blocks.GRANITE, Materials.GRANITE))
+    public static final @NotNull Block<?> ORE_GOLD_GRANITE = register("ore.gold.granite", "minecraft:block/ore_gold_granite", 373, (b) -> new BlockLogicOreGold(b, Blocks.GRANITE, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_GOLD_PERMAFROST = register("ore.gold.permafrost", "minecraft:block/ore_gold_permafrost",374, (b) -> new BlockLogicOreGold(b, Blocks.PERMAFROST, Materials.PERMAFROST))
+    public static final @NotNull Block<?> ORE_GOLD_PERMAFROST = register("ore.gold.permafrost", "minecraft:block/ore_gold_permafrost",374, (b) -> new BlockLogicOreGold(b, Blocks.PERMAFROST, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> ORE_LAPIS_STONE = register("ore.lapis.stone", "minecraft:block/ore_lapis_stone", 380, (b) -> new BlockLogicOreLapis(b, Blocks.STONE, Materials.STONE))
+    public static final @NotNull Block<?> ORE_LAPIS_STONE = register("ore.lapis.stone", "minecraft:block/ore_lapis_stone", 380, (b) -> new BlockLogicOreLapis(b, Blocks.STONE, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_LAPIS_BASALT = register("ore.lapis.basalt", "minecraft:block/ore_lapis_basalt", 381, (b) -> new BlockLogicOreLapis(b, Blocks.BASALT, Materials.BASALT))
+    public static final @NotNull Block<?> ORE_LAPIS_BASALT = register("ore.lapis.basalt", "minecraft:block/ore_lapis_basalt", 381, (b) -> new BlockLogicOreLapis(b, Blocks.BASALT, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_LAPIS_LIMESTONE = register("ore.lapis.limestone", "minecraft:block/ore_lapis_limestone", 382, (b) -> new BlockLogicOreLapis(b, Blocks.LIMESTONE, Materials.LIMESTONE))
+    public static final @NotNull Block<?> ORE_LAPIS_LIMESTONE = register("ore.lapis.limestone", "minecraft:block/ore_lapis_limestone", 382, (b) -> new BlockLogicOreLapis(b, Blocks.LIMESTONE, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_LAPIS_GRANITE = register("ore.lapis.granite", "minecraft:block/ore_lapis_granite", 383, (b) -> new BlockLogicOreLapis(b, Blocks.GRANITE, Materials.GRANITE))
+    public static final @NotNull Block<?> ORE_LAPIS_GRANITE = register("ore.lapis.granite", "minecraft:block/ore_lapis_granite", 383, (b) -> new BlockLogicOreLapis(b, Blocks.GRANITE, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_LAPIS_PERMAFROST = register("ore.lapis.permafrost", "minecraft:block/ore_lapis_permafrost", 384, (b) -> new BlockLogicOreLapis(b, Blocks.PERMAFROST, Materials.PERMAFROST))
+    public static final @NotNull Block<?> ORE_LAPIS_PERMAFROST = register("ore.lapis.permafrost", "minecraft:block/ore_lapis_permafrost", 384, (b) -> new BlockLogicOreLapis(b, Blocks.PERMAFROST, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> ORE_REDSTONE_STONE = register("ore.redstone.stone", "minecraft:block/ore_redstone_stone", 390,
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_BASALT = register("ore.redstone.basalt", "minecraft:block/ore_redstone_basalt", 391,
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_LIMESTONE = register("ore.redstone.limestone", "minecraft:block/ore_redstone_limestone", 392,
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_GRANITE = register("ore.redstone.granite", "minecraft:block/ore_redstone_granite", 393,
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_PERMAFROST = register("ore.redstone.permafrost", "minecraft:block/ore_redstone_permafrost", 394,
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> ORE_REDSTONE_GLOWING_STONE = register("ore.redstone.glowing.stone", "minecraft:block/ore_redstone_glowing_stone", 400,
+    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).withLightEmission(0.2F).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_STONE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_GLOWING_BASALT = register("ore.redstone.glowing.basalt", "minecraft:block/ore_redstone_glowing_basalt", 401,
+    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).withLightEmission(0.2F).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_BASALT)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_GLOWING_LIMESTONE = register("ore.redstone.glowing.limestone", "minecraft:block/ore_redstone_glowing_limestone", 402,
+    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).withLightEmission(0.2F).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_LIMESTONE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_GLOWING_GRANITE = register("ore.redstone.glowing.granite", "minecraft:block/ore_redstone_glowing_granite", 403,
+    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).withLightEmission(0.2F).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_GRANITE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_REDSTONE_GLOWING_PERMAFROST = register("ore.redstone.glowing.permafrost", "minecraft:block/ore_redstone_glowing_permafrost", 404,
+    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).withLightEmission(0.2F).withHardness(3F).withBlastResistance(5F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> ORE_REDSTONE_PERMAFROST)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> ORE_DIAMOND_STONE = register("ore.diamond.stone", "minecraft:block/ore_diamond_stone", 410, (b) -> new BlockLogicOreDiamond(b, Blocks.STONE, Materials.STONE))
+    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))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_DIAMOND_BASALT = register("ore.diamond.basalt", "minecraft:block/ore_diamond_basalt", 411, (b) -> new BlockLogicOreDiamond(b, Blocks.BASALT, Materials.BASALT))
+    public static final @NotNull Block<?> ORE_DIAMOND_BASALT = register("ore.diamond.basalt", "minecraft:block/ore_diamond_basalt", 411, (b) -> new BlockLogicOreDiamond(b, Blocks.BASALT, Materials.BASALT))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_DIAMOND_LIMESTONE = register("ore.diamond.limestone", "minecraft:block/ore_diamond_limestone", 412, (b) -> new BlockLogicOreDiamond(b, Blocks.LIMESTONE, Materials.LIMESTONE))
+    public static final @NotNull Block<?> ORE_DIAMOND_LIMESTONE = register("ore.diamond.limestone", "minecraft:block/ore_diamond_limestone", 412, (b) -> new BlockLogicOreDiamond(b, Blocks.LIMESTONE, Materials.LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_DIAMOND_GRANITE = register("ore.diamond.granite", "minecraft:block/ore_diamond_granite", 413, (b) -> new BlockLogicOreDiamond(b, Blocks.GRANITE, Materials.GRANITE))
+    public static final @NotNull Block<?> ORE_DIAMOND_GRANITE = register("ore.diamond.granite", "minecraft:block/ore_diamond_granite", 413, (b) -> new BlockLogicOreDiamond(b, Blocks.GRANITE, Materials.GRANITE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ORE_DIAMOND_PERMAFROST = register("ore.diamond.permafrost", "minecraft:block/ore_diamond_permafrost", 414, (b) -> new BlockLogicOreDiamond(b, Blocks.PERMAFROST, Materials.PERMAFROST))
+    public static final @NotNull Block<?> ORE_DIAMOND_PERMAFROST = register("ore.diamond.permafrost", "minecraft:block/ore_diamond_permafrost", 414, (b) -> new BlockLogicOreDiamond(b, Blocks.PERMAFROST, Materials.PERMAFROST))
         .withSound(BlockSounds.PERMAFROST).withHardness(3F).withBlastResistance(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> ORE_NETHERCOAL_NETHERRACK = register("ore.nethercoal.netherrack", "minecraft:block/ore_nethercoal_netherrack", 420, BlockLogicOreNetherCoal::new)
+    public static final @NotNull Block<?> ORE_NETHERCOAL_NETHERRACK = register("ore.nethercoal.netherrack", "minecraft:block/ore_nethercoal_netherrack", 420, BlockLogicOreNetherCoal::new)
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withLightEmission(0.625F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
 
-    public static final Block<?> BLOCK_COAL = register("block.coal", "minecraft:block/block_coal", 430, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BLOCK_COAL = register("block.coal", "minecraft:block/block_coal", 430, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.coal)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_IRON = register("block.iron", "minecraft:block/block_iron", 431, (b) -> new BlockLogic(b, Materials.METAL))
+    public static final @NotNull Block<?> BLOCK_IRON = register("block.iron", "minecraft:block/block_iron", 431, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.iron)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_GOLD = register("block.gold", "minecraft:block/block_gold", 432, (b) -> new BlockLogic(b, Materials.METAL))
+    public static final @NotNull Block<?> BLOCK_GOLD = register("block.gold", "minecraft:block/block_gold", 432, (b) -> new BlockLogic(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.gold)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_LAPIS = register("block.lapis", "minecraft:block/block_lapis", 433, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BLOCK_LAPIS = register("block.lapis", "minecraft:block/block_lapis", 433, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(5F).withOverrideColor(MaterialColor.lapis)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_REDSTONE = register("block.redstone", "minecraft:block/block_redstone", 434, (b) -> new BlockLogicRedstone(b, Materials.STONE))
+    public static final @NotNull Block<?> BLOCK_REDSTONE = register("block.redstone", "minecraft:block/block_redstone", 434, (b) -> new BlockLogicRedstone(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.redstone)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_DIAMOND = register("block.diamond", "minecraft:block/block_diamond", 435, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BLOCK_DIAMOND = register("block.diamond", "minecraft:block/block_diamond", 435, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(5F).withBlastResistance(10F).withOverrideColor(MaterialColor.diamond)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_NETHER_COAL = register("block.nethercoal", "minecraft:block/block_nethercoal", 436, (b) -> new BlockLogic(b, Materials.NETHERRACK))
+    public static final @NotNull Block<?> BLOCK_NETHER_COAL = register("block.nethercoal", "minecraft:block/block_nethercoal", 436, (b) -> new BlockLogic(b, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_STEEL = register("block.steel", "minecraft:block/block_steel", 437, (b) -> new BlockLogic(b, Materials.STEEL))
+    public static final @NotNull Block<?> BLOCK_STEEL = register("block.steel", "minecraft:block/block_steel", 437, (b) -> new BlockLogic(b, Materials.STEEL))
         .withSound(BlockSounds.METAL).withHardness(5F).withBlastResistance(2000F).withOverrideColor(MaterialColor.steel)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_QUARTZ = register("block.quartz", "minecraft:block/block_quartz", 438, (b) -> new BlockLogic(b, Materials.STEEL))
+    public static final @NotNull Block<?> BLOCK_QUARTZ = register("block.quartz", "minecraft:block/block_quartz", 438, (b) -> new BlockLogic(b, Materials.STEEL))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.quartz)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_OLIVINE = register("block.olivine", "minecraft:block/block_olivine", 439, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BLOCK_OLIVINE = register("block.olivine", "minecraft:block/block_olivine", 439, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.olivine)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BLOCK_CHARCOAL = register("block.charcoal", "minecraft:block/block_charcoal", 440, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> BLOCK_CHARCOAL = register("block.charcoal", "minecraft:block/block_charcoal", 440, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withHardness(3F).withBlastResistance(10F).withOverrideColor(MaterialColor.coal)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<BlockLogicWireRedstone> WIRE_REDSTONE = register("wire.redstone", "minecraft:block/wire_redstone", 450, BlockLogicWireRedstone::new)
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
 
-    public static final Block<?> TORCH_REDSTONE_IDLE = register("torch.redstone.idle", "minecraft:block/torch_redstone_idle", 460, (b) -> new BlockLogicTorchRedstone(b, false))
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<?> TORCH_REDSTONE_ACTIVE = register("torch.redstone.active", "minecraft:block/torch_redstone_active", 461, (b) -> new BlockLogicTorchRedstone(b, true))
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PREVENT_MOB_SPAWNS);
 
-    public static final Block<?> BUTTON_STONE = register("button.stone", "minecraft:block/button_stone", 470, BlockLogicButton::new)
+    public static final @NotNull Block<?> BUTTON_STONE = register("button.stone", "minecraft:block/button_stone", 470, BlockLogicButton::new)
         .withSound(BlockSounds.STONE).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<?> BUTTON_PLANKS = register("button.planks", "minecraft:block/button_planks", 471, BlockLogicButtonPlanks::new)
+    public static final @NotNull Block<?> BUTTON_PLANKS = register("button.planks", "minecraft:block/button_planks", 471, BlockLogicButtonPlanks::new)
         .withSound(BlockSounds.WOOD).withHardness(0.5F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<BlockLogicButtonPainted> BUTTON_PLANKS_PAINTED = register("button.planks.painted", "minecraft:block/button_planks_painted", 472, BlockLogicButtonPainted::new)
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
 
-    public static final Block<?> LEVER_COBBLE_STONE = register("lever.cobble.stone", "minecraft:block/lever_cobble_stone", 480, BlockLogicLever::new)
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
 
-    public static final Block<?> PRESSURE_PLATE_STONE = register("pressureplate.stone", "minecraft:block/pressure_plate_stone", 490, (b) -> new BlockLogicPressurePlate<>(b, Mob.class, Materials.STONE))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<?> PRESSURE_PLATE_PLANKS_OAK = register("pressureplate.planks.oak", "minecraft:block/pressure_plate_planks_oak", 491, (b) -> new BlockLogicPressurePlate<>(b, Entity.class, Materials.WOOD))
+    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()
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<?> PRESSURE_PLATE_COBBLE_STONE = register("pressureplate.cobble.stone", "minecraft:block/pressure_plate_cobble_stone", 492, (b) -> new BlockLogicPressurePlate<>(b, Player.class, Materials.STONE))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final 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))
+    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()
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.PREVENT_MOB_SPAWNS);
 
-    public static final Block<BlockLogicMotionSensor> MOTION_SENSOR_IDLE = register("motionsensor.idle", "minecraft:block/motion_sensor_idle", 500, (BlockLogicSupplier<BlockLogicMotionSensor>)(b) -> new BlockLogicMotionSensor(b, false))
+    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(2.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange().withOverrideColor(MaterialColor.stone)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicMotionSensor> MOTION_SENSOR_ACTIVE = register("motionsensor.active", "minecraft:block/motion_sensor_active", 501, (BlockLogicSupplier<BlockLogicMotionSensor>)(b) -> new BlockLogicMotionSensor(b, true))
+    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(2.0F).withBlastResistance(10F).withOverrideColor(MaterialColor.stone).setStatParent(() -> MOTION_SENSOR_IDLE)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<BlockLogicRepeater> REPEATER_IDLE = register("repeater.idle", "minecraft:block/repeater_idle", 510, (BlockLogicSupplier<BlockLogicRepeater>)b -> new BlockLogicRepeater(b, false))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<BlockLogicRepeater> REPEATER_ACTIVE = register("repeater.active", "minecraft:block/repeater_active", 511, (BlockLogicSupplier<BlockLogicRepeater>)b -> new BlockLogicRepeater(b, true))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.PREVENT_MOB_SPAWNS);
 
-    public static final Block<BlockLogicPistonBase> PISTON_BASE = register("piston.base", "minecraft:block/piston_base", 520, (BlockLogicSupplier<BlockLogicPistonBase>)b -> new BlockLogicPistonBase(b, 12))
+    public static final @NotNull Block<BlockLogicPistonBase> PISTON_BASE = register("piston.base", "minecraft:block/piston_base", 520, (BlockLogicSupplier<BlockLogicPistonBase>)b -> new BlockLogicPistonBase(b, 12))
         .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicPistonBase> PISTON_BASE_STICKY = register("piston.base.sticky", "minecraft:block/piston_base_sticky", 521, (BlockLogicSupplier<BlockLogicPistonBase>)b -> new BlockLogicPistonBaseSticky(b, 12))
+    public static final @NotNull Block<BlockLogicPistonBase> PISTON_BASE_STICKY = register("piston.base.sticky", "minecraft:block/piston_base_sticky", 521, (BlockLogicSupplier<BlockLogicPistonBase>)b -> new BlockLogicPistonBaseSticky(b, 12))
         .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicPistonHead> PISTON_HEAD = register("piston.head", "minecraft:block/piston_head", 522, (BlockLogicSupplier<BlockLogicPistonHead>)(b) -> new BlockLogicPistonHead(b, 4/16d, 4/16d))
+    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().withImmovableFlagSet()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicPistonMoving> PISTON_MOVING = register("piston.moving", "minecraft:block/piston_moving", 523, BlockLogicPistonMoving::new)
+    public static final @NotNull Block<BlockLogicPistonMoving> PISTON_MOVING = register("piston.moving", "minecraft:block/piston_moving", 523, BlockLogicPistonMoving::new)
         .withSound(BlockSounds.STONE).withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicPistonBase> PISTON_BASE_STEEL = register("piston.base.steel", "minecraft:block/piston_base_steel", 524, (BlockLogicSupplier<BlockLogicPistonBase>)b -> new BlockLogicPistonBaseSteel(b, 24))
+    public static final @NotNull Block<BlockLogicPistonBase> PISTON_BASE_STEEL = register("piston.base.steel", "minecraft:block/piston_base_steel", 524, (BlockLogicSupplier<BlockLogicPistonBase>)b -> new BlockLogicPistonBaseSteel(b, 24))
         .withSound(BlockSounds.METAL)
         .withHardness(5F)
         .withBlastResistance(2000F)
         .withOverrideColor(MaterialColor.steel).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final 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))
+    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)
@@ -806,501 +808,501 @@ public final class Blocks {
         .withDisabledNeighborNotifyOnMetadataChange().withDisabledStats()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> NOTEBLOCK = register("noteblock", "minecraft:block/noteblock", 530, BlockLogicNote::new)
+    public static final @NotNull Block<?> NOTEBLOCK = register("noteblock", "minecraft:block/noteblock", 530, BlockLogicNote::new)
         .withSound(BlockSounds.WOOD).withHardness(0.8F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<BlockLogicRail> RAIL = register("rail", "minecraft:block/rail", 540, (BlockLogicSupplier<BlockLogicRail>)b -> new BlockLogicRail(b, false))
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<BlockLogicRail> RAIL_POWERED = register("rail.powered", "minecraft:block/rail_powered", 541, (BlockLogicSupplier<BlockLogicRail>)b -> new BlockLogicRail(b, true))
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
-    public static final Block<BlockLogicRail> RAIL_DETECTOR = register("rail.detector", "minecraft:block/rail_detector", 542, (BlockLogicSupplier<BlockLogicRail>)BlockLogicRailDetector::new)
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.PREVENT_MOB_SPAWNS);
 
-    public static final Block<?> SPIKES = register("spikes", "minecraft:block/spikes", 550, (b) -> new BlockLogicSpikes(b, Materials.METAL))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> DISPENSER_COBBLE_STONE = register("dispenser.cobble.stone", "minecraft:block/dispenser_cobble_stone", 560, BlockLogicDispenser::new)
+    public static final @NotNull Block<?> DISPENSER_COBBLE_STONE = register("dispenser.cobble.stone", "minecraft:block/dispenser_cobble_stone", 560, BlockLogicDispenser::new)
         .withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> ACTIVATOR_COBBLE_NETHERRACK = register("activator.cobble.netherrack", "minecraft:block/activator_cobble_netherrack", 561, BlockLogicActivator::new)
+    public static final @NotNull Block<?> ACTIVATOR_COBBLE_NETHERRACK = register("activator.cobble.netherrack", "minecraft:block/activator_cobble_netherrack", 561, BlockLogicActivator::new)
         .withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> TRAPDOOR_PLANKS_OAK = register("trapdoor.planks.oak", "minecraft:block/trapdoor_planks_oak", 570, (b) -> new BlockLogicTrapDoor(b, Materials.WOOD))
+    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()
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> TRAPDOOR_IRON = register("trapdoor.iron", "minecraft:block/trapdoor_iron", 571, (b) -> new BlockLogicTrapDoor(b, Materials.METAL))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> TRAPDOOR_GLASS = register("trapdoor.glass", "minecraft:block/trapdoor_glass", 572, (b) -> new BlockLogicTrapDoor(b, Materials.GLASS))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> TRAPDOOR_PLANKS_PAINTED = register("trapdoor.planks.oak.painted", "minecraft:block/trapdoor_planks_oak_painted", 573, (b) -> new BlockLogicTrapDoorPainted(b, Materials.WOOD))
+    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()
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> TRAPDOOR_STEEL = register("trapdoor.steel", "minecraft:block/trapdoor_steel", 574, (b) -> new BlockLogicTrapDoor(b, Materials.STEEL))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<BlockLogicTNT> TNT = register("tnt", "minecraft:block/tnt", 580, BlockLogicTNT::new)
+    public static final @NotNull Block<BlockLogicTNT> TNT = register("tnt", "minecraft:block/tnt", 580, BlockLogicTNT::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F);
 
-    public static final Block<BlockLogicDoor> DOOR_PLANKS_OAK_BOTTOM = register("door.planks.oak.bottom", "minecraft:block/door_planks_oak_bottom", 590,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicDoor> DOOR_PLANKS_OAK_TOP = register("door.planks.oak.top", "minecraft:block/doors_planks_oak_top", 591,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicDoor> DOOR_IRON_BOTTOM = register("door.iron.bottom", "minecraft:block/door_iron_bottom", 592,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicDoor> DOOR_IRON_TOP = register("door.iron.top", "minecraft:block/door_iron_top", 593,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicDoorPainted> DOOR_PLANKS_PAINTED_BOTTOM = register("door.planks.oak.painted.bottom", "minecraft:block/door_planks_oak_painted_bottom", 594,
+    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)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicDoorPainted> DOOR_PLANKS_PAINTED_TOP = register("door.planks.oak.painted.top", "minecraft:block/door_planks_oak_painted_top", 595,
+    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)
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicDoor> DOOR_GLASS_BOTTOM = register("door.glass.bottom", "minecraft:block/door_glass_bottom", 596,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicDoor> DOOR_GLASS_TOP = register("door.glass.top", "minecraft:block/door_glass_top", 597,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicDoor> DOOR_STEEL_BOTTOM = register("door.steel.bottom", "minecraft:block/door_steel_bottom", 598,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicDoor> DOOR_STEEL_TOP = register("door.steel.top", "minecraft:block/door_steel_top", 599,
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> MESH = register("mesh", "minecraft:block/mesh", 600, BlockLogicMesh::new)
+    public static final @NotNull Block<?> MESH = register("mesh", "minecraft:block/mesh", 600, BlockLogicMesh::new)
         .withSound(BlockSounds.METAL).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CAN_HANG_OFF);
-    public static final Block<?> MESH_GOLD = register("mesh.gold", "minecraft:block/mesh_gold", 601, BlockLogicMeshGold::new)
+    public static final @NotNull Block<?> MESH_GOLD = register("mesh.gold", "minecraft:block/mesh_gold", 601, BlockLogicMeshGold::new)
         .withSound(BlockSounds.METAL).withHardness(1F).withOverrideColor(MaterialColor.gold)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CAN_HANG_OFF);
 
-    public static final Block<BlockLogicBed> BED = register("bed", "minecraft:block/bed", 610, (BlockLogicSupplier<BlockLogicBed>)BlockLogicBed::new)
+    public static final @NotNull Block<BlockLogicBed> BED = register("bed", "minecraft:block/bed", 610, (BlockLogicSupplier<BlockLogicBed>)BlockLogicBed::new)
         .withSound(BlockSounds.WOOD).withHardness(0.2F).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true).setStatParent(() -> Items.BED)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> SEAT = register("seat", "minecraft:block/seat", 611, BlockLogicSeat::new)
+    public static final @NotNull Block<?> SEAT = register("seat", "minecraft:block/seat", 611, BlockLogicSeat::new)
         .withSound(BlockSounds.WOOD).withHardness(0.2F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.SEAT)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> COBWEB = register("cobweb", "minecraft:block/cobweb", 620, (b) -> new BlockLogicCobweb(b, Materials.WEB))
+    public static final @NotNull Block<?> COBWEB = register("cobweb", "minecraft:block/cobweb", 620, (b) -> new BlockLogicCobweb(b, Materials.WEB))
         .withSound(BlockSounds.CLOTH).withLightBlock(1).withHardness(4F)
         .withTags(BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_SHEARS, BlockTags.MINEABLE_BY_SWORD);
 
-    public static final Block<BlockLogicFire> FIRE = register("fire", "minecraft:block/fire", 630, BlockLogicFire::new)
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicBrazier> BRAZIER_INACTIVE = register("brazier.inactive", "minecraft:block/brazier_inactive", 631, (BlockLogicSupplier<BlockLogicBrazier>)b -> new BlockLogicBrazier(b, false))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicBrazier> BRAZIER_ACTIVE = register("brazier.active", "minecraft:block/brazier_active", 632, (BlockLogicSupplier<BlockLogicBrazier>)b -> new BlockLogicBrazier(b, true))
+    public static final @NotNull Block<BlockLogicBrazier> BRAZIER_ACTIVE = register("brazier.active", "minecraft:block/brazier_active", 632, (BlockLogicSupplier<BlockLogicBrazier>)b -> new BlockLogicBrazier(b, true))
         .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 Block<BlockLogicFireCold> FIRE_COLD = register("fire_cold", "minecraft:block/fire_cold", 633, BlockLogicFireCold::new)
+    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()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<?> MOBSPAWNER = register("mobspawner", "minecraft:block/mobspawner", 640, BlockLogicMobSpawner::new)
+    public static final @NotNull Block<?> MOBSPAWNER = register("mobspawner", "minecraft:block/mobspawner", 640, BlockLogicMobSpawner::new)
         .withSound(BlockSounds.METAL).withHardness(5F).withImmovableFlagSet()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> MOBSPAWNER_DEACTIVATED = register("mobspawner.deactivated", "minecraft:block/mobspawner_deactivated", 641, BlockLogicMobSpawnerDeactivated::new)
+    public static final @NotNull Block<?> MOBSPAWNER_DEACTIVATED = register("mobspawner.deactivated", "minecraft:block/mobspawner_deactivated", 641, BlockLogicMobSpawnerDeactivated::new)
         .withSound(BlockSounds.METAL).withHardness(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> WORKBENCH = register("workbench", "minecraft:block/workbench", 650, BlockLogicWorkbench::new)
+    public static final @NotNull Block<?> WORKBENCH = register("workbench", "minecraft:block/workbench", 650, BlockLogicWorkbench::new)
         .withSound(BlockSounds.WOOD).withHardness(2.5F)
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> FURNACE_STONE_IDLE = register("furnace.stone.idle", "minecraft:block/furnace_stone_idle", 660, (b) -> new BlockLogicFurnace(b, false))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> FURNACE_STONE_ACTIVE = register("furnace.stone.active", "minecraft:block/furnace_stone_active", 661, (b) -> new BlockLogicFurnace(b, true))
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> FURNACE_BLAST_IDLE = register("furnace.blast.idle", "minecraft:block/furnace_blast_idle", 662, (b) -> new BlockLogicFurnaceBlast(b, false))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> FURNACE_BLAST_ACTIVE = register("furnace.blast.active", "minecraft:block/furnace_blast_active", 663, (b) -> new BlockLogicFurnaceBlast(b, true))
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> TROMMEL_IDLE = register("trommel.idle", "minecraft:block/trommel_idle", 670, (b) -> new BlockLogicTrommel(b, Materials.STONE, false))
+    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()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> TROMMEL_ACTIVE = register("trommel.active", "minecraft:block/trommel_active", 671, (b) -> new BlockLogicTrommel(b, Materials.STONE, true))
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
     @SuppressWarnings("deprecation")
-    public static final Block<BlockLogicChestLegacy> CHEST_LEGACY = register("chest.legacy", "minecraft:block/chest_legacy", 680, BlockLogicChestLegacy::new)
+    public static final @NotNull Block<BlockLogicChestLegacy> CHEST_LEGACY = register("chest.legacy", "minecraft:block/chest_legacy", 680, BlockLogicChestLegacy::new)
         .withSound(BlockSounds.WOOD).withHardness(2.5f).withBlastResistance(5.0f).setStatParent(() -> Blocks.CHEST_PLANKS_OAK)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
     @SuppressWarnings("deprecation")
-    public static final Block<BlockLogicChestLegacy> CHEST_LEGACY_PAINTED = register("chest.legacy.painted", "minecraft:block/chest_legacy_painted", 681, BlockLogicChestLegacy::new)
+    public static final @NotNull Block<BlockLogicChestLegacy> CHEST_LEGACY_PAINTED = register("chest.legacy.painted", "minecraft:block/chest_legacy_painted", 681, BlockLogicChestLegacy::new)
         .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 Block<BlockLogicChest> CHEST_PLANKS_OAK = register("chest.planks.oak", "minecraft:block/chest_planks_oak", 682, (BlockLogicSupplier<BlockLogicChest>)(b) -> new BlockLogicChest(b, Materials.WOOD))
+    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()
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
-    public static final 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))
+    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()
         .setBlockItem((b) -> new ItemBlockPainted<>(b, true))
         .withTags(BlockTags.FENCES_CONNECT, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> CROPS_WHEAT = register("crops.wheat", "minecraft:block/crops_wheat", 690, BlockLogicCropsWheat::new)
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<?> CROPS_PUMPKIN = register("crops.pumpkin", "minecraft:block/crops_pumpkin", 691, BlockLogicCropsPumpkin::new)
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.OVERRIDE_STEPSOUND);
 
-    public static final Block<?> FARMLAND_DIRT = register("farmland.dirt", "minecraft:block/farmland_dirt", 700, BlockLogicFarmland::new)
+    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()
         .withTags(BlockTags.MINEABLE_BY_SHOVEL);
 
-    public static final 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))
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-    public static final 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))
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> FLAG = register("flag", "minecraft:block/flag", 712, (b) -> new BlockLogicFlag(b, Materials.WOOD))
+    public static final @NotNull Block<?> FLAG = register("flag", "minecraft:block/flag", 712, (b) -> new BlockLogicFlag(b, Materials.WOOD))
         .withSound(BlockSounds.WOOD).withHardness(1.0F).setStatParent(() -> Items.FLAG)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
-    public static final 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))
+    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)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
-    public static final 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))
+    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)
             .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<BlockLogicLayerSnow> LAYER_SNOW = register("layer.snow", "minecraft:block/layer_snow", 720, (BlockLogicSupplier<BlockLogicLayerSnow>)(b) -> new BlockLogicLayerSnow(b, Blocks.BLOCK_SNOW, Materials.TOP_SNOW))
+    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))
         .withSound(BlockSounds.CLOTH).withHardness(0.1F).withLitInteriorSurface(true)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.MINEABLE_BY_SHOVEL, BlockTags.OVERRIDE_STEPSOUND);
-    public static final Block<BlockLogicLayerLeaves> LAYER_LEAVES_OAK = register("layer.leaves.oak", "minecraft:block/layer_leaves_oak", 721, (BlockLogicSupplier<BlockLogicLayerLeaves>)(b) -> new BlockLogicLayerLeaves(b, Blocks.LEAVES_OAK, Materials.LEAVES))
+    public static final @NotNull Block<BlockLogicLayerLeaves> LAYER_LEAVES_OAK = register("layer.leaves.oak", "minecraft:block/layer_leaves_oak", 721, (BlockLogicSupplier<BlockLogicLayerLeaves>)(b) -> new BlockLogicLayerLeaves(b, Blocks.LEAVES_OAK, Materials.LEAVES))
         .withSound(BlockSounds.GRASS).withLitInteriorSurface(true)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.SHEARS_DO_SILK_TOUCH, BlockTags.MINEABLE_BY_SHEARS, BlockTags.MINEABLE_BY_SWORD, BlockTags.MINEABLE_BY_AXE, BlockTags.MINEABLE_BY_HOE);
-    public static final Block<BlockLogicLayerBase> LAYER_SLATE = register("layer.slate", "minecraft:block/layer_slate", 722, (BlockLogicSupplier<BlockLogicLayerBase>)(b) -> new BlockLogicLayerSlate(b, Blocks.SLATE, Materials.SLATE))
+    public static final @NotNull Block<BlockLogicLayerBase> LAYER_SLATE = register("layer.slate", "minecraft:block/layer_slate", 722, (BlockLogicSupplier<BlockLogicLayerBase>)(b) -> new BlockLogicLayerSlate(b, Blocks.SLATE, Materials.SLATE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicLayerAsh> LAYER_ASH = register("layer.ash", "minecraft:block/layer_ash", 723, (BlockLogicSupplier<BlockLogicLayerAsh>)(b) -> new BlockLogicLayerAsh(b, Blocks.BLOCK_ASH, Materials.TOP_ASH))
+    public static final @NotNull Block<BlockLogicLayerAsh> LAYER_ASH = register("layer.ash", "minecraft:block/layer_ash", 723, (BlockLogicSupplier<BlockLogicLayerAsh>)(b) -> new BlockLogicLayerAsh(b, Blocks.BLOCK_ASH, Materials.TOP_ASH))
         .withSound(BlockSounds.CLOTH).withHardness(0.1F).withLitInteriorSurface(true)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.PLACE_OVERWRITES, BlockTags.MINEABLE_BY_SHOVEL, BlockTags.OVERRIDE_STEPSOUND);
 
-    public static final Block<?> ICE = register("ice", "minecraft:block/ice", 730, BlockLogicIce::new)
+    public static final @NotNull Block<?> ICE = register("ice", "minecraft:block/ice", 730, BlockLogicIce::new)
         .withSound(BlockSounds.GLASS).withHardness(0.5F).withLightBlock(3)
         .withTags(BlockTags.SKATEABLE, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> PERMAICE = register("ice.perma", "minecraft:block/permaice", 731, (b) -> new BlockLogicSlippery(b, Materials.ICE))
+    public static final @NotNull Block<?> PERMAICE = register("ice.perma", "minecraft:block/permaice", 731, (b) -> new BlockLogicSlippery(b, Materials.ICE))
         .withSound(BlockSounds.GLASS).withHardness(1.5F).withBlastResistance(10F)
         .withTags(BlockTags.SKATEABLE, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> BLOCK_SNOW = register("block.snow", "minecraft:block/block_snow", 740, BlockLogicSnow::new)
+    public static final @NotNull Block<?> BLOCK_SNOW = register("block.snow", "minecraft:block/block_snow", 740, BlockLogicSnow::new)
         .withSound(BlockSounds.CLOTH).withHardness(0.2F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_SHOVEL, BlockTags.FIREFLIES_CAN_SPAWN);
-    public static final Block<?> BLOCK_ASH = register("block.ash", "minecraft:block/block_ash", 741, BlockLogicAsh::new)
+    public static final @NotNull Block<?> BLOCK_ASH = register("block.ash", "minecraft:block/block_ash", 741, BlockLogicAsh::new)
         .withSound(BlockSounds.CLOTH).withHardness(0.2F)
         .withTags(BlockTags.CAVES_CUT_THROUGH, BlockTags.MINEABLE_BY_SHOVEL);
 
-    public static final Block<?> CACTUS = register("cactus", "minecraft:block/cactus", 750, BlockLogicCactus::new)
+    public static final @NotNull Block<?> CACTUS = register("cactus", "minecraft:block/cactus", 750, BlockLogicCactus::new)
         .withSound(BlockSounds.CLOTH).withHardness(0.4F)
         .withTags(BlockTags.GROWS_CACTI, BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_SHEARS, BlockTags.MINEABLE_BY_HOE);
 
-    public static final Block<?> BLOCK_CLAY = register("block.clay", "minecraft:block/block_clay", 760, BlockLogicClay::new)
+    public static final @NotNull Block<?> BLOCK_CLAY = register("block.clay", "minecraft:block/block_clay", 760, BlockLogicClay::new)
         .withSound(BlockSounds.GRAVEL).withHardness(0.6F)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL);
 
-    public static final Block<?> SUGARCANE = register("sugarcane", "minecraft:block/sugarcane", 770, BlockLogicSugarcane::new)
+    public static final @NotNull Block<?> SUGARCANE = register("sugarcane", "minecraft:block/sugarcane", 770, BlockLogicSugarcane::new)
         .withSound(BlockSounds.GRASS).withHardness(0.0F).withOverrideColor(MaterialColor.paintedLime).setStatParent(() -> Items.SUGARCANE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<?> BLOCK_SUGARCANE = register("block.sugarcane", "minecraft:block/block_sugarcane", 771, (b) -> new BlockLogicAxisAligned(b, Materials.MOSS))
+    public static final @NotNull Block<?> BLOCK_SUGARCANE = register("block.sugarcane", "minecraft:block/block_sugarcane", 771, (b) -> new BlockLogicAxisAligned(b, Materials.MOSS))
         .withSound(BlockSounds.GRASS).withHardness(0.6F).withOverrideColor(MaterialColor.paintedLime)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.FENCES_CONNECT);
-    public static final Block<?> BLOCK_SUGARCANE_BAKED = register("block.sugarcane.baked", "minecraft:block/block_sugarcane_baked", 772, (b) -> new BlockLogicAxisAligned(b, Materials.MOSS))
+    public static final @NotNull Block<?> BLOCK_SUGARCANE_BAKED = register("block.sugarcane.baked", "minecraft:block/block_sugarcane_baked", 772, (b) -> new BlockLogicAxisAligned(b, Materials.MOSS))
         .withSound(BlockSounds.GRASS).withHardness(0.6F).withOverrideColor(MaterialColor.wood)
         .withTags(BlockTags.MINEABLE_BY_AXE, BlockTags.FENCES_CONNECT);
 
-    public static final Block<BlockLogicJukebox> JUKEBOX = register("jukebox", "minecraft:block/jukebox", 780, BlockLogicJukebox::new)
+    public static final @NotNull Block<BlockLogicJukebox> JUKEBOX = register("jukebox", "minecraft:block/jukebox", 780, BlockLogicJukebox::new)
         .withSound(BlockSounds.WOOD).withHardness(2.0F).withBlastResistance(10F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> PUMPKIN = register("pumpkin", "minecraft:block/pumpkin", 790, (b) -> new BlockLogicPumpkin(b, true))
+    public static final @NotNull Block<?> PUMPKIN = register("pumpkin", "minecraft:block/pumpkin", 790, (b) -> new BlockLogicPumpkin(b, true))
         .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> PUMPKIN_CARVED_IDLE = register("pumpkin.carved.idle", "minecraft:block/pumpkin_carved_idle", 791, (b) -> new BlockLogicPumpkin(b, false))
+    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()
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> PUMPKIN_CARVED_ACTIVE = register("pumpkin.carved.active", "minecraft:block/pumpkin_carved_active", 792, (b) -> new BlockLogicPumpkin(b, false))
+    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()
         .withTags(BlockTags.MINEABLE_BY_AXE);
-    public static final Block<?> PUMPKIN_REDSTONE = register("pumpkin.redstone", "minecraft:block/pumpkin_redstone", 793, BlockLogicPumpkinRedstone::new)
+    public static final @NotNull Block<?> PUMPKIN_REDSTONE = register("pumpkin.redstone", "minecraft:block/pumpkin_redstone", 793, BlockLogicPumpkinRedstone::new)
         .withSound(BlockSounds.WOOD).withHardness(1.0F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_AXE);
 
-    public static final Block<?> COBBLE_NETHERRACK = register("cobble.netherrack", "minecraft:block/cobble_netherrack", 800, (b) -> new BlockLogicCobble(b, Materials.NETHERRACK, null))
+    public static final @NotNull Block<?> COBBLE_NETHERRACK = register("cobble.netherrack", "minecraft:block/cobble_netherrack", 800, (b) -> new BlockLogicCobble(b, Materials.NETHERRACK, null))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
-    public static final Block<?> COBBLE_NETHERRACK_IGNEOUS = register("cobble.netherrack.igneous", "minecraft:block/cobble_netherrack_igneous", 801, BlockLogicNetherrackIgneous::new)
+    public static final @NotNull Block<?> COBBLE_NETHERRACK_IGNEOUS = register("cobble.netherrack.igneous", "minecraft:block/cobble_netherrack_igneous", 801, BlockLogicNetherrackIgneous::new)
         .withSound(BlockSounds.STONE).withHardness(1.25F).withBlastResistance(7F).withLightEmission(10)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> COBBLE_NETHERRACK_MOSSY = register("cobble.netherrack.mossy", "minecraft:block/cobble_netherrack_mossy", 802, (b) -> new BlockLogicCobble(b, Materials.NETHERRACK, null))
+    public static final @NotNull Block<?> COBBLE_NETHERRACK_MOSSY = register("cobble.netherrack.mossy", "minecraft:block/cobble_netherrack_mossy", 802, (b) -> new BlockLogicCobble(b, Materials.NETHERRACK, null))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.GROWS_FLOWERS, BlockTags.INFINITE_BURN);
-    public static final Block<?> NETHERRACK = register("netherrack", "minecraft:block/netherrack", 803, (b) -> new BlockLogicStone(b, Blocks.COBBLE_NETHERRACK, Materials.NETHERRACK))
+    public static final @NotNull Block<?> NETHERRACK = register("netherrack", "minecraft:block/netherrack", 803, (b) -> new BlockLogicStone(b, Blocks.COBBLE_NETHERRACK, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.32F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
-    public static final Block<?> BRICK_NETHERRACK = register("brick.netherrack", "minecraft:block/brick_netherrack", 804, (b) -> new BlockLogic(b, Materials.NETHERRACK))
+    public static final @NotNull Block<?> BRICK_NETHERRACK = register("brick.netherrack", "minecraft:block/brick_netherrack", 804, (b) -> new BlockLogic(b, Materials.NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_NETHERRACK_POLISHED = register("slab.netherrack.carved", "minecraft:block/slab_netherrack_carved", 805, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.NETHERRACK_CARVED))
+    public static final @NotNull Block<BlockLogicSlab> SLAB_NETHERRACK_POLISHED = register("slab.netherrack.carved", "minecraft:block/slab_netherrack_carved", 805, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.NETHERRACK_CARVED))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_COBBLE_NETHERRACK = register("slab.cobble.netherrack", "minecraft:block/slab_cobble_netherrack", 806, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_NETHERRACK))
+    public static final @NotNull Block<BlockLogicSlab> SLAB_COBBLE_NETHERRACK = register("slab.cobble.netherrack", "minecraft:block/slab_cobble_netherrack", 806, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.COBBLE_NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_NETHERRACK = register("slab.brick.netherrack", "minecraft:block/slab_brick_netherrack", 807, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_NETHERRACK))
+    public static final @NotNull Block<BlockLogicSlab> SLAB_BRICK_NETHERRACK = register("slab.brick.netherrack", "minecraft:block/slab_brick_netherrack", 807, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_COBBLE_NETHERRACK = register("stairs.cobble.netherrack", "minecraft:block/stairs_cobble_netherrack", 808, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_NETHERRACK))
+    public static final @NotNull Block<BlockLogicStairs> STAIRS_COBBLE_NETHERRACK = register("stairs.cobble.netherrack", "minecraft:block/stairs_cobble_netherrack", 808, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.COBBLE_NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_NETHERRACK = register("stairs.brick.netherrack", "minecraft:block/stairs_brick_netherrack", 809, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_NETHERRACK))
+    public static final @NotNull Block<BlockLogicStairs> STAIRS_BRICK_NETHERRACK = register("stairs.brick.netherrack", "minecraft:block/stairs_brick_netherrack", 809, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_NETHERRACK))
         .withSound(BlockSounds.STONE).withHardness(0.4F).withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> SOULSAND = register("soulsand", "minecraft:block/soulsand", 810, BlockLogicSoulSand::new)
+    public static final @NotNull Block<?> SOULSAND = register("soulsand", "minecraft:block/soulsand", 810, BlockLogicSoulSand::new)
         .withSound(BlockSounds.SAND).withHardness(0.5F).withOverrideColor(MaterialColor.paintedBrown)
         .withTags(BlockTags.MINEABLE_BY_SHOVEL, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN, BlockTags.INFINITE_BURN_COLD);
-    public static final Block<?> SOULSCHIST = register("soulschist", "minecraft:block/soulschist", 811, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.SOULSAND))
+    public static final @NotNull Block<?> SOULSCHIST = register("soulschist", "minecraft:block/soulschist", 811, (b) -> new BlockLogicCobble(b, Materials.STONE, () -> Blocks.SOULSAND))
         .withSound(BlockSounds.STONE).withHardness(2.0F).withBlastResistance(10F).withOverrideColor(MaterialColor.paintedBrown)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NETHER_MOBS_SPAWN);
 
-    public static final Block<?> GLOWSTONE = register("glowstone", "minecraft:block/glowstone", 820, (b) -> new BlockLogicGlowStone(b, Materials.STONE))
+    public static final @NotNull Block<?> GLOWSTONE = register("glowstone", "minecraft:block/glowstone", 820, (b) -> new BlockLogicGlowStone(b, Materials.STONE))
         .withSound(BlockSounds.GLASS).withHardness(0.3F).withLightEmission(1.0F).withOverrideColor(MaterialColor.paintedYellow)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> CRYSTAL = register("crystal", "minecraft:block/crystal", 821, (b) -> new BlockLogicCrystal(b))
+    public static final @NotNull Block<?> CRYSTAL = register("crystal", "minecraft:block/crystal", 821, (b) -> new BlockLogicCrystal(b))
         .withSound(BlockSounds.GLASS).withLightEmission(0.8F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> CRYSTAL_STALK = register("crystal.stalk", "minecraft:block/crystal_stalk", 822, (b) -> new BlockLogicStalk(b))
+    public static final @NotNull Block<?> CRYSTAL_STALK = register("crystal.stalk", "minecraft:block/crystal_stalk", 822, (b) -> new BlockLogicStalk(b))
         .withSound(BlockSounds.GLASS).withDisabledNeighborNotifyOnMetadataChange().withLightEmission(0.8F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> NETHERRACK_CRYSTALLINE = register("netherrack.crystalline", "minecraft:block/netherrack_crystalline", 823, (b) -> new BlockLogic(b, Materials.STONE))
+    public static final @NotNull Block<?> NETHERRACK_CRYSTALLINE = register("netherrack.crystalline", "minecraft:block/netherrack_crystalline", 823, (b) -> new BlockLogic(b, Materials.STONE))
         .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN);
 
-    public static final Block<BlockLogicPortal> PORTAL_NETHER = register("portal.nether", "minecraft:block/portal_nether", 830, (BlockLogicSupplier<BlockLogicPortal>) b -> new BlockLogicPortal(b, Dimension.NETHER, Blocks.OBSIDIAN, Blocks.FIRE))
+    public static final @NotNull Block<BlockLogicPortal> PORTAL_NETHER = register("portal.nether", "minecraft:block/portal_nether", 830, (BlockLogicSupplier<BlockLogicPortal>) b -> new BlockLogicPortal(b, Dimension.NETHER, Blocks.OBSIDIAN, Blocks.FIRE))
         .withSound(BlockSounds.GLASS).withHardness(-1F).withLightEmission(0.75F).withOverrideColor(MaterialColor.paintedPurple).withDisabledStats()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicPortal> PORTAL_DRIFT = register("portal.drift", "minecraft:block/portal_drift", 831, (BlockLogicSupplier<BlockLogicPortal>) b -> new BlockLogicPortal(b, Dimension.DRIFT, Blocks.GLOWSTONE, Blocks.BEDROCK))
+    public static final @NotNull Block<BlockLogicPortal> PORTAL_DRIFT = register("portal.drift", "minecraft:block/portal_drift", 831, (BlockLogicSupplier<BlockLogicPortal>) b -> new BlockLogicPortal(b, Dimension.DRIFT, Blocks.GLOWSTONE, Blocks.BEDROCK))
         .withSound(BlockSounds.GLASS).withHardness(-1F).withLightEmission(0.75f).withOverrideColor(MaterialColor.paintedPurple).withDisabledStats()
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<?> CAKE = register("cake", "minecraft:block/cake", 840, BlockLogicCake::new)
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicEdible> PUMPKIN_PIE = register("pumpkin_pie", "minecraft:block/pumpkin_pie", 841, (BlockLogicSupplier<BlockLogicEdible>)BlockLogicPiePumpkin::new)
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<BlockLogicLamp> LAMP_IDLE = register("lamp.idle", "minecraft:block/lamp_idle", 850, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, false, false))
+    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()
         .setBlockItem(ItemBlockLamp::new)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicLamp> LAMP_ACTIVE = register("lamp.active", "minecraft:block/lamp_active", 851, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, true, false))
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicLamp> LAMP_INVERTED_IDLE = register("lamp.inverted.idle", "minecraft:block/lamp_inverted_idle", 852, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, false, true))
+    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)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicLamp> LAMP_INVERTED_ACTIVE = register("lamp.inverted.active", "minecraft:block/lamp_inverted_active", 853, (BlockLogicSupplier<BlockLogicLamp>)b -> new BlockLogicLamp(b, true, true))
+    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()
         .setBlockItem(ItemBlockLamp::new)
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> STONE_POLISHED = register("stone.polished", "minecraft:block/stone_polished", 860, (b) -> new BlockLogic(b, Materials.STONE))
+    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()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> GRANITE_POLISHED = register("granite.polished", "minecraft:block/granite_polished", 861, (b) -> new BlockLogic(b, Materials.GRANITE))
+    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()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> LIMESTONE_POLISHED = register("limestone.polished", "minecraft:block/limestone_polished", 862, (b) -> new BlockLogic(b, Materials.LIMESTONE))
+    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()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> BASALT_POLISHED = register("basalt.polished", "minecraft:block/basalt_polished", 863, (b) -> new BlockLogic(b, Materials.BASALT))
+    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()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> SLATE_POLISHED = register("slate.polished", "minecraft:block/slate_polished", 864, (b) -> new BlockLogic(b, Materials.SLATE))
+    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()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> PERMAFROST_POLISHED = register("permafrost.polished", "minecraft:block/permafrost_polished", 865, (b) -> new BlockLogic(b, Materials.PERMAFROST))
+    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()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> NETHERRACK_POLISHED = register("netherrack.polished", "minecraft:block/netherrack_polished", 866, (b) -> new BlockLogic(b, Materials.NETHERRACK))
+    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()
             .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<?> LANTERN_FIREFLY_GREEN = register("lantern.firefly.green", "minecraft:block/lantern_firefly_green", 870,
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<?> LANTERN_FIREFLY_BLUE = register("lantern.firefly.blue", "minecraft:block/lantern_firefly_blue", 871,
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<?> LANTERN_FIREFLY_ORANGE = register("lantern.firefly.orange", "minecraft:block/lantern_firefly_orange", 872,
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<?> LANTERN_FIREFLY_RED = register("lantern.firefly.red", "minecraft:block/lantern_firefly_red", 873,
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<?> JAR_GLASS = register("jar.glass", "minecraft:block/jar_glass", 874,
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<?> OVERLAY_PEBBLES = register("overlay.pebbles", "minecraft:block/overlay_pebbles", 880, (b) -> new BlockLogicOverlayPebbles(b, Materials.DECORATION))
+    public static final @NotNull Block<?> OVERLAY_PEBBLES = register("overlay.pebbles", "minecraft:block/overlay_pebbles", 880, (b) -> new BlockLogicOverlayPebbles(b, Materials.DECORATION))
         .withSound(BlockSounds.STONE).withHardness(0.0F).withDisabledNeighborNotifyOnMetadataChange().setStatParent(() -> Items.AMMO_PEBBLE)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.NOT_IN_CREATIVE_MENU, BlockTags.OVERRIDE_FRICTION);
 
-    public static final Block<BlockLogicFenceThin> FENCE_CHAINLINK = register("fence.chainlink", "minecraft:block/fence_chainlink", 890, (BlockLogicSupplier<BlockLogicFenceThin>)b -> new BlockLogicFenceChainlink(b, Materials.METAL))
+    public static final @NotNull Block<BlockLogicFenceThin> FENCE_CHAINLINK = register("fence.chainlink", "minecraft:block/fence_chainlink", 890, (BlockLogicSupplier<BlockLogicFenceThin>)b -> new BlockLogicFenceChainlink(b, Materials.METAL))
         .withSound(BlockSounds.METAL).withHardness(5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
-    public static final Block<BlockLogicFenceThin> FENCE_PAPER_WALL = register("fence.paper_wall", "minecraft:block/fence_paper_wall", 891, (BlockLogicSupplier<BlockLogicFenceThin>)b -> new BlockLogicFenceWallPaper(b, Materials.CLOTH))
+    public static final @NotNull Block<BlockLogicFenceThin> FENCE_PAPER_WALL = register("fence.paper_wall", "minecraft:block/fence_paper_wall", 891, (BlockLogicSupplier<BlockLogicFenceThin>)b -> new BlockLogicFenceWallPaper(b, Materials.CLOTH))
         .withSound(BlockSounds.CLOTH).withHardness(0.5F)
         .withTags(BlockTags.MINEABLE_BY_SHEARS, BlockTags.FENCES_CONNECT, BlockTags.CAN_HANG_OFF, BlockTags.MINEABLE_BY_AXE);
-    public static final Block<BlockLogicFenceThin> FENCE_STEEL = register("fence.steel", "minecraft:block/fence_steel", 892, (BlockLogicSupplier<BlockLogicFenceThin>)b -> new BlockLogicFenceSteel(b, Materials.STEEL))
+    public static final @NotNull Block<BlockLogicFenceThin> FENCE_STEEL = register("fence.steel", "minecraft:block/fence_steel", 892, (BlockLogicSupplier<BlockLogicFenceThin>)b -> new BlockLogicFenceSteel(b, Materials.STEEL))
         .withSound(BlockSounds.METAL).withHardness(8F).withOverrideColor(MaterialColor.steel).withBlastResistance(2000F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.CHAINLINK_FENCES_CONNECT, BlockTags.CAN_HANG_OFF);
 
-    public static final Block<BlockLogicBasket> BASKET = register("basket", "minecraft:block/basket", 900, (BlockLogicSupplier<BlockLogicBasket>)(b) -> new BlockLogicBasket(b, Materials.CLOTH))
+    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()
         .withTags(BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<?> PAPER_WALL = register("paper_wall", "minecraft:block/paper_wall", 910, (b) -> new BlockLogic(b, Materials.CLOTH))
+    public static final @NotNull Block<?> PAPER_WALL = register("paper_wall", "minecraft:block/paper_wall", 910, (b) -> new BlockLogic(b, Materials.CLOTH))
         .withSound(BlockSounds.CLOTH).withHardness(0.7F)
         .withTags(BlockTags.MINEABLE_BY_SHEARS, BlockTags.FENCES_CONNECT, BlockTags.CAN_HANG_OFF, BlockTags.MINEABLE_BY_AXE);
 
-    public static final 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))
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final 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))
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final 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))
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final 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))
+    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)
         .withTags(BlockTags.BROKEN_BY_FLUIDS, BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<BlockLogicSlab> SLAB_BRICK_SANDSTONE = register("slab.brick.sandstone", "minecraft:block/slab_brick_sandstone", 1000, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.BRICK_SANDSTONE))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_COBBLE_PERMAFROST = register("slab.cobble.permafrost", "minecraft:block/slab_cobble_permafrost", 1001, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.COBBLE_PERMAFROST))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_PERMAFROST = register("slab.brick.permafrost", "minecraft:block/slab_brick_permafrost", 1002, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.BRICK_PERMAFROST))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_PERMAFROST_POLISHED = register("slab.permafrost.carved", "minecraft:block/slab_permafrost_carved", 1003, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.PERMAFROST_CARVED))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_IRON = register("slab.brick.iron", "minecraft:block/slab_brick_iron", 1004, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_IRON))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_GOLD = register("slab.brick.gold", "minecraft:block/slab_brick_gold", 1005, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_GOLD))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_STEEL = register("slab.brick.steel", "minecraft:block/slab_brick_steel", 1006, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_STEEL))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicSlab> SLAB_BRICK_LAPIS = register("slab.brick.lapis", "minecraft:block/slab_brick_lapis", 1007, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_LAPIS))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_IRON = register("stairs.brick.iron", "minecraft:block/stairs_brick_iron", 1050, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_IRON))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_GOLD = register("stairs.brick.gold", "minecraft:block/stairs_brick_gold", 1051, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_GOLD))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_STEEL = register("stairs.brick.steel", "minecraft:block/stairs_brick_steel", 1052, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_STEEL))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<BlockLogicStairs> STAIRS_BRICK_LAPIS = register("stairs.brick.lapis", "minecraft:block/stairs_brick_lapis", 1053, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_LAPIS))
+    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)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final 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))
+    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))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_STONE_UPPER = register("statue.stone.upper", "minecraft:block/statue_stone_upper", 1011, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_STONE))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_STONE_UPPER = register("statue.stone.upper", "minecraft:block/statue_stone_upper", 1011, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_STONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_BASALT_LOWER = register("statue.basalt.lower", "minecraft:block/statue_basalt_lower", 1012, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_BASALT))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_BASALT_LOWER = register("statue.basalt.lower", "minecraft:block/statue_basalt_lower", 1012, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_BASALT_UPPER = register("statue.basalt.upper", "minecraft:block/statue_basalt_upper", 1013, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_BASALT))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_BASALT_UPPER = register("statue.basalt.upper", "minecraft:block/statue_basalt_upper", 1013, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_BASALT))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_LIMESTONE_LOWER = register("statue.limestone.lower", "minecraft:block/statue_limestone_lower", 1014, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_LIMESTONE))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_LIMESTONE_LOWER = register("statue.limestone.lower", "minecraft:block/statue_limestone_lower", 1014, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_LIMESTONE_UPPER = register("statue.limestone.upper", "minecraft:block/statue_limestone_upper", 1015, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_LIMESTONE))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_LIMESTONE_UPPER = register("statue.limestone.upper", "minecraft:block/statue_limestone_upper", 1015, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_LIMESTONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_GRANITE_LOWER = register("statue.granite.lower", "minecraft:block/statue_granite_lower", 1016, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_GRANITE))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_GRANITE_LOWER = register("statue.granite.lower", "minecraft:block/statue_granite_lower", 1016, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_GRANITE_UPPER = register("statue.granite.upper", "minecraft:block/statue_granite_upper", 1017, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_GRANITE))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_GRANITE_UPPER = register("statue.granite.upper", "minecraft:block/statue_granite_upper", 1017, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_GRANITE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_MARBLE_LOWER = register("statue.marble.lower", "minecraft:block/statue_marble_lower", 1018, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_MARBLE))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_MARBLE_LOWER = register("statue.marble.lower", "minecraft:block/statue_marble_lower", 1018, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_MARBLE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_MARBLE_UPPER = register("statue.marble.upper", "minecraft:block/statue_marble_upper", 1019, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_MARBLE))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_MARBLE_UPPER = register("statue.marble.upper", "minecraft:block/statue_marble_upper", 1019, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_MARBLE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_PIGMAN_LOWER = register("statue.pigman.lower", "minecraft:block/statue_pigman_lower", 1020, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_PIGMAN))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_PIGMAN_LOWER = register("statue.pigman.lower", "minecraft:block/statue_pigman_lower", 1020, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, true, () -> Items.STATUE_PIGMAN))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
-    public static final Block<BlockLogicStatue> STATUE_PIGMAN_UPPER = register("statue.pigman.upper", "minecraft:block/statue_pigman_upper", 1021, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_PIGMAN))
+    public static final @NotNull Block<BlockLogicStatue> STATUE_PIGMAN_UPPER = register("statue.pigman.upper", "minecraft:block/statue_pigman_upper", 1021, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Materials.STONE, false, () -> Items.STATUE_PIGMAN))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
 
-    public static final Block<BlockLogic> MATCHER = register("matcher", "minecraft:block/matcher", 1040, (b) -> new BlockLogicMatcher(b, false))
+    public static final @NotNull Block<BlockLogic> MATCHER = register("matcher", "minecraft:block/matcher", 1040, (b) -> new BlockLogicMatcher(b, false))
         .withSound(BlockSounds.STONE).withHardness(3.5F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
-    public static final Block<BlockLogic> MATCHER_ACTIVE = register("matcher.active", "minecraft:block/matcher_active", 1041, (b) -> new BlockLogicMatcher(b, true))
+    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(3.5F).withDisabledNeighborNotifyOnMetadataChange()
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU);
 
@@ -1382,8 +1384,7 @@ public final class Blocks {
         }
     }
 
-    @Nullable
-    public static Block<?> getBlock(int id)
+    public static @Nullable Block<?> getBlock(int id)
     {
         if (id < 0 || id >= Blocks.blocksList.length) {
             return null;
diff --git a/game/core/src/main/java/net/minecraft/core/block/FluidLava.java b/game/core/src/main/java/net/minecraft/core/block/FluidLava.java
index 9207fcd0e..f5b700143 100644
--- a/game/core/src/main/java/net/minecraft/core/block/FluidLava.java
+++ b/game/core/src/main/java/net/minecraft/core/block/FluidLava.java
@@ -36,16 +36,16 @@ public class FluidLava
             final int data = world.getBlockData(tilePos) & 0x0F;
             if (data == 0) {
                 if (world.dimension == Dimension.NETHER) {
-                    world.setBlockIdNotify(tilePos, Blocks.COBBLE_NETHERRACK_IGNEOUS.id());
+                    world.setBlockTypeNotify(tilePos, Blocks.COBBLE_NETHERRACK_IGNEOUS);
                 } else {
-                    world.setBlockIdNotify(tilePos, Blocks.OBSIDIAN.id());
+                    world.setBlockTypeNotify(tilePos, Blocks.OBSIDIAN);
                 }
             } else if (data <= 2) {
-                world.setBlockIdNotify(tilePos, Blocks.COBBLE_GRANITE.id());
+                world.setBlockTypeNotify(tilePos, Blocks.COBBLE_GRANITE);
             } else if (data <= 4) {
-                world.setBlockIdNotify(tilePos, Blocks.COBBLE_STONE.id());
+                world.setBlockTypeNotify(tilePos, Blocks.COBBLE_STONE);
             } else {
-                world.setBlockIdNotify(tilePos, Blocks.COBBLE_BASALT.id());
+                world.setBlockTypeNotify(tilePos, Blocks.COBBLE_BASALT);
             }
             BlockLogicFluid.fizz(world, tilePos);
         }
@@ -65,21 +65,23 @@ public class FluidLava
             p.x += rand.nextInt(3) - 1;
             p.y++;
             p.z += rand.nextInt(3) - 1;
-            final int id = world.getBlockId(p);
-            if (id == 0) {
-                if (isFlammable(world, p.west(queryPos)) ||
-                    isFlammable(world, p.east(queryPos)) ||
-                    isFlammable(world, p.north(queryPos)) ||
-                    isFlammable(world, p.south(queryPos)) ||
-                    isFlammable(world, p.down(queryPos)) ||
-                    isFlammable(world, p.up(queryPos))) {
-                    world.setBlockIdNotify(p, Blocks.FIRE.id());
+            if (world.areBlocksLoaded(p, 2)) {
+                final @NotNull Block<?> block = world.getBlockType(p);
+                if (block == Blocks.AIR) {
+                    if (isFlammable(world, p.west(queryPos)) ||
+                        isFlammable(world, p.east(queryPos)) ||
+                        isFlammable(world, p.north(queryPos)) ||
+                        isFlammable(world, p.south(queryPos)) ||
+                        isFlammable(world, p.down(queryPos)) ||
+                        isFlammable(world, p.up(queryPos))) {
+                        world.setBlockTypeNotify(p, Blocks.FIRE);
+                        return;
+                    }
+                    continue;
+                }
+                if (block.getMaterial().blocksMotion()) {
                     return;
                 }
-                continue;
-            }
-            if (Blocks.blocksList[id].getMaterial().blocksMotion()) {
-                return;
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/FluidWater.java b/game/core/src/main/java/net/minecraft/core/block/FluidWater.java
index b54916f82..c82b7cd1b 100644
--- a/game/core/src/main/java/net/minecraft/core/block/FluidWater.java
+++ b/game/core/src/main/java/net/minecraft/core/block/FluidWater.java
@@ -40,7 +40,7 @@ public class FluidWater
         if (encountered == Materials.LAVA) {
             final int data = world.getBlockData(tilePos) & 0x0F;
             if (data == 0) {
-                world.setBlockIdNotify(tilePos, Blocks.COBBLE_LIMESTONE.id());
+                world.setBlockTypeNotify(tilePos, Blocks.COBBLE_LIMESTONE);
                 BlockLogicFluid.fizz(world, tilePos);
             }
         }
@@ -68,10 +68,7 @@ public class FluidWater
 
     @Override
     public void onFlowIntoBlock(final @NotNull BlockLogicFluid logicFluid, final @NotNull World world, final @NotNull TilePos tilePos, final int meta) {
-        final Block<?> b = world.getBlock(tilePos);
-        if (b != null) {
-            b.dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
-        }
+        world.getBlockType(tilePos).dropWithCause(world, EnumDropCause.WORLD, tilePos, world.getBlockData(tilePos), null, null);
     }
 
     @Override
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 3ba382720..b4b797808 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
@@ -138,8 +138,7 @@ public class TileEntityMobSpawner extends TileEntity {
         for (tilePos.x = this.x -r; tilePos.x <= this.x + r; tilePos.x++) {
             for (tilePos.y = this.y -r; tilePos.y <= this.y + r; tilePos.y++) {
                 for (tilePos.z = this.z -r; tilePos.z <= this.z + r; tilePos.z++) {
-                    int id = this.worldObj.getBlockId(tilePos);
-                    if (id == Blocks.MOBSPAWNER.id()) {
+                    if (this.worldObj.getBlockType(tilePos) == Blocks.MOBSPAWNER) {
                         count++;
                     }
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java
index 0e49e289b..88cecea89 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBase.java
@@ -111,7 +111,7 @@ public class BlockLogicPistonBase extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         checkIfExtend(world, tilePos);
     }
 
@@ -204,12 +204,12 @@ public class BlockLogicPistonBase extends BlockLogic {
             if (!moving.isExtending()) {
                 moving.finalTick();
             } else {
-                world.setBlockId(shiftedPos, 0);
+                world.setBlockType(shiftedPos, Blocks.AIR);
             }
         }
-        world.setBlockIdData(tilePos, Blocks.PISTON_MOVING.id(), direction.getId());
-        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(this.block.id(), direction.getId(), null, direction, false, true));
-        world.setBlockIdNotify(shiftedPos, 0);
+        world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, direction.getId());
+        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(this.block, direction.getId(), null, direction, false, true));
+        world.setBlockTypeNotify(shiftedPos, Blocks.AIR);
         world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) tilePos.x() + 0.5D, (double) tilePos.y() + 0.5D, (double) tilePos.z() + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F);
     }
 
@@ -251,9 +251,7 @@ public class BlockLogicPistonBase extends BlockLogic {
         return (data & MASK_POWERED) != 0;
     }
 
-    protected boolean isPushable(int id, @NotNull World world, @NotNull TilePos tilePos, boolean canDestroy) {
-        Block<?> block = Blocks.getBlock(id);
-        if (block == null) return false;
+    protected boolean isPushable(final @NotNull Block<?> block, @NotNull World world, @NotNull TilePos tilePos, boolean canDestroy) {
         int pushReaction = block.getPistonPushReaction(world, tilePos);
         return !block.hasTag(BlockTags.PISTON_CRUSHING) &&
             !block.getImmovable() &&
@@ -280,17 +278,17 @@ public class BlockLogicPistonBase extends BlockLogic {
             if (posO.y < 0 || posO.y >= world.getHeightBlocks()) {
                 return false;
             }
-            int id = world.getBlockId(posO);
-            if (id == 0) {
+            final @NotNull Block<?> block = world.getBlockType(posO);
+            if (block == Blocks.AIR) {
                 break;
             }
-            if (!isPushable(id, world, posO, true)) {
-                if (blocks == 1 && BlockTags.PISTON_CRUSHING.appliesTo(Blocks.getBlock(id)) && tryCrush(world, tilePos, direction)) {
+            if (!isPushable(block, world, posO, true)) {
+                if (blocks == 1 && block.hasTag(BlockTags.PISTON_CRUSHING) && tryCrush(world, tilePos, direction)) {
                     break;
                 }
                 return false;
             }
-            if (Blocks.blocksList[id].getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
+            if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
                 break;
             }
             if (blocks == maxPushedBlocks) {
@@ -306,11 +304,10 @@ public class BlockLogicPistonBase extends BlockLogic {
 
     public boolean tryCrush(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction) {
         TilePos pos2 = tilePos.add(direction, new TilePos());
-        Block<?> block = world.getBlock(pos2);
-        if (block == null) return true;
-        world.playBlockEvent(null, pos2, LevelListener.EVENT_BLOCK_BREAK, world.getBlockId(pos2));
+        Block<?> block = world.getBlockType(pos2);
+        world.playBlockEvent(null, pos2, LevelListener.EVENT_BLOCK_BREAK, world.getBlockType(pos2).id());
         block.dropWithCause(world, EnumDropCause.SILK_TOUCH, pos2, world.getBlockData(pos2), null, null);
-        world.setBlockIdNotify(pos2, 0);
+        world.setBlockTypeNotify(pos2, Blocks.AIR);
         return true;
     }
 
@@ -325,15 +322,15 @@ public class BlockLogicPistonBase extends BlockLogic {
             if (posO.y < 0 || posO.y >= world.getHeightBlocks()) {
                 return false;
             }
-            int blockId = world.getBlockId(posO);
-            if (blockId == 0) {
+            final @NotNull Block<?> block = world.getBlockType(posO);
+            if (block == Blocks.AIR) {
                 break;
             }
-            if (!isPushable(blockId, world, posO, true)) {
+            if (!isPushable(block, world, posO, true)) {
                 return false;
             }
-            if (Blocks.blocksList[blockId].getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
-                Blocks.blocksList[blockId].dropWithCause(world, EnumDropCause.WORLD, posO, world.getBlockData(posO), world.getTileEntity(posO), null);
+            if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
+                block.dropWithCause(world, EnumDropCause.WORLD, posO, world.getBlockData(posO), world.getTileEntity(posO), null);
                 break;
             }
             if (blocks == maxPushedBlocks) {
@@ -347,33 +344,33 @@ public class BlockLogicPistonBase extends BlockLogic {
         TilePos posP = new TilePos(posO);
         while (!posO.equals(tilePos)) {
             posP.set(posO.x - direction.getOffsetX(), posO.y - direction.getOffsetY(), posO.z - direction.getOffsetZ());
-            int pushId = world.getBlockId(posP);
+            @NotNull Block<?> pushBlock = world.getBlockType(posP);
             int pushMeta = world.getBlockData(posP);
             TileEntity pushEntity = world.getTileEntity(posP);
             if (pushEntity instanceof TileEntityMovingPistonBlock && posP.equals(tilePos)) {
                 break;
             }
-            if (pushId == this.block.id() && posP.equals(tilePos)) {
+            if (pushBlock == this.block && posP.equals(tilePos)) {
                 createPistonHeadAt(world, posO, data, direction);
-            } else if (pushId == Blocks.PISTON_MOVING.id()) {
+            } else if (pushBlock == Blocks.PISTON_MOVING) {
                 TileEntity old = world.getTileEntity(posP);
                 if (old instanceof TileEntityMovingPistonBlock moving) {
                     if (!moving.isSourcePiston()) {
-                        pushId = moving.getMovedId();
+                        pushBlock = moving.getMovedBlock();
                         pushMeta = moving.getMovedData();
                         pushEntity = moving.getMovedEntity();
                     }
                 }
                 world.removeTileEntity(posP);
-                world.setBlockIdData(posO, Blocks.PISTON_MOVING.id(), pushMeta);
-                world.replaceTileEntity(posO, BlockLogicPistonMoving.createTileEntity(pushId, pushMeta, pushEntity, direction, true, false));
+                world.setBlockTypeData(posO, Blocks.PISTON_MOVING, pushMeta);
+                world.replaceTileEntity(posO, BlockLogicPistonMoving.createTileEntity(pushBlock, pushMeta, pushEntity, direction, true, false));
             } else {
                 world.removeTileEntity(posP);
-                world.setBlockIdData(posO, Blocks.PISTON_MOVING.id(), pushMeta);
-                world.replaceTileEntity(posO, BlockLogicPistonMoving.createTileEntity(pushId, pushMeta, pushEntity, direction, true, false));
+                world.setBlockTypeData(posO, Blocks.PISTON_MOVING, pushMeta);
+                world.replaceTileEntity(posO, BlockLogicPistonMoving.createTileEntity(pushBlock, pushMeta, pushEntity, direction, true, false));
             }
             if (!posP.equals(tilePos)) {
-                world.setBlockIdDataRaw(posP, 0, 0);
+                world.setBlockTypeRaw(posP, Blocks.AIR);
             }
             posO.set(posP.x, posP.y, posP.z);
         }
@@ -382,8 +379,8 @@ public class BlockLogicPistonBase extends BlockLogic {
     }
 
     public void createPistonHeadAt(@NotNull World world, @NotNull TilePos tilePos, int data, @NotNull Direction direction) {
-        world.setBlockIdData(tilePos, Blocks.PISTON_MOVING.id(), BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_NORMAL, direction.getId()));
-        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD.id(), BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_NORMAL, direction.getId()), null, direction, true, false));
+        world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_NORMAL, direction.getId()));
+        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_NORMAL, direction.getId()), null, direction, true, false));
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSteel.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSteel.java
index a71f8ae16..6a9281cf1 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSteel.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSteel.java
@@ -61,18 +61,18 @@ public class BlockLogicPistonBaseSteel extends BlockLogicPistonBase {
             if (posO.y < 0 || posO.y >= world.getHeightBlocks()) {
                 return false;
             }
-            int id = world.getBlockId(posO);
-            if (id == 0) {
+            final @NotNull Block<?> block = world.getBlockType(posO);
+            if (block == Blocks.AIR) {
                 break;
             }
-            if (!isPushable(id, world, posO, true)) {
-                if (blocks == 1 && BlockTags.PISTON_CRUSHING.appliesTo(Blocks.getBlock(id)) && tryCrush(world, tilePos, direction)) {
+            if (!isPushable(block, world, posO, true)) {
+                if (blocks == 1 && block.hasTag(BlockTags.PISTON_CRUSHING) && tryCrush(world, tilePos, direction)) {
                     didCrush = true;
                     break;
                 }
                 return false;
             }
-            if (Blocks.blocksList[id].getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
+            if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
                 break;
             }
             if (blocks == maxPushedBlocks) {
@@ -85,12 +85,12 @@ public class BlockLogicPistonBaseSteel extends BlockLogicPistonBase {
         }
         if (!didCrush && blocks == 1) { // Block Flinging
             tilePos.add(direction, posO);
-            Block<?> block = world.getBlock(posO);
+            Block<?> block = world.getBlockType(posO);
             if (block == null) return true;
             int blockMeta = world.getBlockData(posO);
             TileEntity tileEntity = world.getTileEntity(posO);
             world.removeTileEntity(posO);
-            world.setBlockIdNotify(posO, 0);
+            world.setBlockTypeNotify(posO, Blocks.AIR);
             if (!world.isClientSide) {
                 EntityFallingBlock entityFallingBlock = new EntityFallingBlock(world, posO.x + 0.5, posO.y + 0.5, posO.z + 0.5, block.id(), blockMeta, tileEntity);
                 entityFallingBlock.hasRemovedBlock = true;
@@ -111,11 +111,10 @@ public class BlockLogicPistonBaseSteel extends BlockLogicPistonBase {
     @Override
     public boolean tryCrush(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Direction direction) {
         TilePos pos2 = tilePos.add(direction, new TilePos());
-        Block<?> block = world.getBlock(pos2);
-        if (block == null) return true;
-        world.playBlockEvent(null, pos2, LevelListener.EVENT_BLOCK_BREAK, world.getBlockId(pos2));
+        Block<?> block = world.getBlockType(pos2);
+        world.playBlockEvent(null, pos2, LevelListener.EVENT_BLOCK_BREAK, world.getBlockType(pos2).id());
         block.dropWithCause(world, EnumDropCause.PISTON_CRUSH, pos2, world.getBlockData(pos2), null, null);
-        world.setBlockIdNotify(pos2, 0);
+        world.setBlockTypeNotify(pos2, Blocks.AIR);
         return true;
     }
 
@@ -132,15 +131,15 @@ public class BlockLogicPistonBaseSteel extends BlockLogicPistonBase {
                 if (posO.y < 0 || posO.y >= world.getHeightBlocks()) {
                     return false;
                 }
-                int blockId = world.getBlockId(posO);
-                if (blockId == 0) {
+                final @NotNull Block<?> block = world.getBlockType(posO);
+                if (block == Blocks.AIR) {
                     break;
                 }
-                if (!isPushable(blockId, world, posO, true)) {
+                if (!isPushable(block, world, posO, true)) {
                     return false;
                 }
-                if (Blocks.blocksList[blockId].getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
-                    Blocks.blocksList[blockId].dropWithCause(world, EnumDropCause.WORLD, posO, world.getBlockData(posO), world.getTileEntity(posO), null);
+                if (block.getPistonPushReaction(world, posO) == Material.PISTON_DESTROY_ON_PUSH) {
+                    block.dropWithCause(world, EnumDropCause.WORLD, posO, world.getBlockData(posO), world.getTileEntity(posO), null);
                     break;
                 }
                 if (blocks == maxPushedBlocks) {
@@ -155,16 +154,16 @@ public class BlockLogicPistonBaseSteel extends BlockLogicPistonBase {
                 TilePos posP = new TilePos(posO);
                 while (!posO.equals(tilePos)) {
                     posP.set(posO.x - direction.getOffsetX(), posO.y - direction.getOffsetY(), posO.z - direction.getOffsetZ());
-                    int pushId = world.getBlockId(posP);
+                    @NotNull Block<?> pushBlock = world.getBlockType(posP);
                     TileEntity pushEntity = world.getTileEntity(posP);
                     if (pushEntity instanceof TileEntityMovingPistonBlock && posP.equals(tilePos)) {
                         break;
                     }
-                    if (pushId == this.block.id() && posP.equals(tilePos)) {
+                    if (pushBlock == this.block && posP.equals(tilePos)) {
                         createPistonHeadAt(world, posO, data, direction);
                     }
                     if (!posP.equals(tilePos))
-                        world.setBlockIdDataRaw(posP, 0, 0);
+                        world.setBlockTypeRaw(posP, Blocks.AIR);
                     posO.x = posP.x;
                     posO.y = posP.y;
                     posO.z = posP.z;
@@ -191,8 +190,8 @@ public class BlockLogicPistonBaseSteel extends BlockLogicPistonBase {
 
     @Override
     public void createPistonHeadAt(@NotNull World world, @NotNull TilePos tilePos, int data, @NotNull Direction direction) {
-        world.setBlockIdData(tilePos, Blocks.PISTON_MOVING.id(), BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STEEL, direction.getId()));
-        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD_STEEL.id(), BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STEEL, direction.getId()), null, direction, true, false));
+        world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STEEL, direction.getId()));
+        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD_STEEL, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STEEL, direction.getId()), null, direction, true, false));
     }
 
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSticky.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSticky.java
index 55368869b..890266124 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSticky.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonBaseSticky.java
@@ -11,6 +11,8 @@ import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Objects;
+
 public class BlockLogicPistonBaseSticky extends BlockLogicPistonBase {
     public BlockLogicPistonBaseSticky(@NotNull Block<?> block, int maxPushedBlocks) {
         super(block, maxPushedBlocks);
@@ -24,51 +26,50 @@ public class BlockLogicPistonBaseSticky extends BlockLogicPistonBase {
             if (!moving.isExtending()) {
                 moving.finalTick();
             } else {
-                world.setBlockId(posDir, 0);
+                world.setBlockType(posDir, Blocks.AIR);
             }
         }
-        world.setBlockIdData(tilePos, Blocks.PISTON_MOVING.id(), direction.getId());
-        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(this.block.id(), direction.getId(), null, direction, false, true));
+        world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, direction.getId());
+        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(this.block, direction.getId(), null, direction, false, true));
         TilePos pos1 = new TilePos(tilePos.x() + direction.getOffsetX() * 2, tilePos.y() + direction.getOffsetY() * 2, tilePos.z() + direction.getOffsetZ() * 2);
-        int retractId = world.getBlockId(pos1);
+        @NotNull Block<?> retractBlock = world.getBlockType(pos1);
         int retactMeta = world.getBlockData(pos1);
         TileEntity retractEntity = world.getTileEntity(pos1);
         boolean pulledMoving = false;
-        if (retractId == Blocks.PISTON_MOVING.id()) {
+        if (retractBlock == Blocks.PISTON_MOVING) {
             if ((world.getTileEntity(pos1) instanceof TileEntityMovingPistonBlock movingPistonBlock)) {
                 if (movingPistonBlock.getDirection() == direction && movingPistonBlock.isExtending()) {
                     movingPistonBlock.finalTick();
-                    retractId = movingPistonBlock.getMovedId();
+                    retractBlock = movingPistonBlock.getMovedBlock();
                     retactMeta = movingPistonBlock.getMovedData();
                     retractEntity = movingPistonBlock.getMovedEntity();
                     pulledMoving = true;
                 }
             }
         }
-        Block<?> retractedBlock = Blocks.getBlock(retractId);
         TilePos pos2 = new TilePos(tilePos);
-        if (!pulledMoving && retractedBlock != null &&
-            isPushable(retractId, world, pos1, false) &&
-            (retractedBlock.getPistonPushReaction(world, pos1) == Material.PISTON_PUSHABLE || (retractedBlock.getLogic() instanceof BlockLogicPistonBase))) {
+        if (!pulledMoving &&
+            isPushable(retractBlock, world, pos1, false) &&
+            (retractBlock.getPistonPushReaction(world, pos1) == Material.PISTON_PUSHABLE || (retractBlock.getLogic() instanceof BlockLogicPistonBase))) {
             if (!(retractEntity instanceof TileEntityMovingPistonBlock)) {
                 world.removeTileEntity(pos1);
             }
-            world.setBlockId(pos1, 0);
+            world.setBlockType(pos1, Blocks.AIR);
             pos2.x += direction.getOffsetX();
             pos2.y += direction.getOffsetY();
             pos2.z += direction.getOffsetZ();
-            world.setBlockIdData(pos2, Blocks.PISTON_MOVING.id(), retactMeta);
-            world.replaceTileEntity(pos2, BlockLogicPistonMoving.createTileEntity(retractId, retactMeta, retractEntity, direction, false, false));
-            world.notifyBlockChange(pos1, 0);
+            world.setBlockTypeData(pos2, Blocks.PISTON_MOVING, retactMeta);
+            world.replaceTileEntity(pos2, BlockLogicPistonMoving.createTileEntity(retractBlock, retactMeta, retractEntity, direction, false, false));
+            world.notifyBlockChange(pos1, Blocks.AIR);
         } else if (!pulledMoving) {
-            world.setBlockIdNotify(posDir, 0);
+            world.setBlockTypeNotify(posDir, Blocks.AIR);
         }
         world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) pos2.x + 0.5D, (double) pos2.y + 0.5D, (double) pos2.z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F);
     }
 
     @Override
     public void createPistonHeadAt(@NotNull World world, @NotNull TilePos tilePos, int data, @NotNull Direction direction) {
-        world.setBlockIdData(tilePos, Blocks.PISTON_MOVING.id(), BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STICKY, direction.getId()));
-        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD.id(), BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STICKY, direction.getId()), null, direction, true, false));
+        world.setBlockTypeData(tilePos, Blocks.PISTON_MOVING, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STICKY, direction.getId()));
+        world.replaceTileEntity(tilePos, BlockLogicPistonMoving.createTileEntity(Blocks.PISTON_HEAD, BlockLogicPistonHead.setPistonType(BlockLogicPistonHead.TYPE_STICKY, direction.getId()), null, direction, true, false));
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java
index e2c470172..a1ee5acc8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonHead.java
@@ -50,12 +50,12 @@ public class BlockLogicPistonHead extends BlockLogic {
         }
         Direction orientation = direction.getOpposite();
         TilePos nextPos = tilePos.add(orientation, new TilePos());
-        Block<?> block = world.getBlock(nextPos);
+        Block<?> block = world.getBlockType(nextPos);
         if (block != null && block.getLogic() instanceof BlockLogicPistonBase) {
             int data2 = world.getBlockData(nextPos);
             if (BlockLogicPistonBase.isPowered(data2)) {
                 block.dropWithCause(world, EnumDropCause.PROPER_TOOL, nextPos, data2, null, null);
-                world.setBlockIdNotify(nextPos, 0);
+                world.setBlockTypeNotify(nextPos, Blocks.AIR);
             }
         }
     }
@@ -131,17 +131,17 @@ public class BlockLogicPistonHead extends BlockLogic {
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         Direction direction = getDirectionFromMeta(world.getBlockData(tilePos));
         if (direction == Direction.NONE) {
             return;
         }
         TilePos posOffset = tilePos.sub(direction, new TilePos());
-        Block<?> block = world.getBlock(posOffset);
-        if (block != null && block.getLogic() instanceof BlockLogicPistonBase) {
-            block.onNeighborChanged(world, posOffset, id);
+        Block<?> offsetBlock = world.getBlockType(posOffset);
+        if (offsetBlock.getLogic() instanceof BlockLogicPistonBase) {
+            offsetBlock.onNeighborChanged(world, posOffset, block);
         } else {
-            world.setBlockIdNotify(tilePos, 0);
+            world.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
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 f71417664..192fc82fd 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
@@ -57,9 +57,11 @@ public class BlockLogicPistonMoving extends BlockLogic {
     @Override
     public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) {
         if (!world.isClientSide && world.getTileEntity(tilePos) == null) {
-            int id = 0;
-            if (world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) id = piston.getMovedId();
-            world.setBlockIdNotify(tilePos, id);
+            @NotNull Block<?> block = Blocks.AIR;
+            if (world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) {
+                block = piston.getMovedBlock();
+            }
+            world.setBlockTypeNotify(tilePos, block);
             return true;
         } else {
             return false;
@@ -77,23 +79,20 @@ public class BlockLogicPistonMoving extends BlockLogic {
             return;
         }
         if (world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) {
-            Block<?> b = Blocks.getBlock(piston.getMovedId());
-            if (b != null) {
-                b.dropWithCause(world, EnumDropCause.WORLD, tilePos, data, null, null);
-            }
+            piston.getMovedBlock().dropWithCause(world, EnumDropCause.WORLD, tilePos, data, null, null);
         }
     }
 
     @Override
-    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, int id) {
+    public void onNeighborChanged(@NotNull World world, @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!world.isClientSide) {
             world.getTileEntity(tilePos); // Im not sure if this actually does anything anymore??
         }
     }
 
-    public static TileEntity createTileEntity(int movedId, int movedData, @Nullable TileEntity movedEntity, @NotNull Direction direction, boolean extending, boolean isSourcePiston) {
+    public static TileEntity createTileEntity(final @NotNull Block<?> movedBlock, int movedData, @Nullable TileEntity movedEntity, @NotNull Direction direction, boolean extending, boolean isSourcePiston) {
         assert !(movedEntity instanceof TileEntityMovingPistonBlock) : "Moving piston entity should not be able to be put into another moving piston!";
-        return new TileEntityMovingPistonBlock(movedId, movedData, movedEntity, direction, extending, isSourcePiston);
+        return new TileEntityMovingPistonBlock(movedBlock, movedData, movedEntity, direction, extending, isSourcePiston);
     }
 
     @Override
@@ -103,7 +102,7 @@ public class BlockLogicPistonMoving extends BlockLogic {
             if (piston.isExtending()) {
                 progress = 1.0F - progress;
             }
-            return getCollisionShapeFromTileEntity(source, tilePos, piston.getMovedId(), progress, piston.getDirection());
+            return getCollisionShapeFromTileEntity(source, tilePos, piston.getMovedBlock(), progress, piston.getDirection());
         }
         return null;
     }
@@ -111,8 +110,8 @@ public class BlockLogicPistonMoving extends BlockLogic {
     @Override
     public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) {
         if (source.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock piston) {
-            Block<?> block = Blocks.blocksList[piston.getMovedId()];
-            if (block == null || block == this.block) {
+            Block<?> block = piston.getMovedBlock();
+            if (block == this.block) {
                 return super.getBoundsFromState(source, tilePos);
             }
             float directionStretch = piston.getProgress(0.0F);
@@ -126,11 +125,8 @@ public class BlockLogicPistonMoving extends BlockLogic {
         return super.getBoundsFromState(source, tilePos);
     }
 
-    public @Nullable AABBdc getCollisionShapeFromTileEntity(@NotNull WorldSource source, @NotNull TilePosc tilePos, int blockID, float directionStretch, @NotNull Direction direction) {
-        if (blockID == 0 || blockID == this.block.id()) {
-            return null;
-        }
-        AABBdc aabb = Blocks.blocksList[blockID].getCollisionAABB(source, tilePos);
+    public @Nullable AABBdc getCollisionShapeFromTileEntity(@NotNull WorldSource source, @NotNull TilePosc tilePos, final @NotNull Block<?> block, float directionStretch, @NotNull Direction direction) {
+        AABBdc aabb = block.getCollisionAABB(source, tilePos);
         if (aabb == null) {
             return null;
         } else {
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java
index b6f04adb0..e1c81ee17 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java
@@ -20,7 +20,7 @@ public class TileEntityMovingPistonBlock extends TileEntity
     public static final int TICKS_TO_EXTEND = 2;
     private static final List<Entity> entityBuffer = new ArrayList<>();
 
-    private int movedId;
+    private @NotNull Block<?> movedBlock;
     private int movedData;
     private @Nullable TileEntity movedEntity;
     private Direction direction;
@@ -34,9 +34,9 @@ public class TileEntityMovingPistonBlock extends TileEntity
     {
     }
 
-    public TileEntityMovingPistonBlock(int movedId, int movedData, @Nullable TileEntity movedEntity, Direction direction, boolean extending, boolean isSourcePiston)
+    public TileEntityMovingPistonBlock(final @NotNull Block<?> movedBlock, int movedData, @Nullable TileEntity movedEntity, Direction direction, boolean extending, boolean isSourcePiston)
     {
-        this.movedId = movedId;
+        this.movedBlock = movedBlock;
         this.movedData = movedData;
         this.movedEntity = movedEntity;
         this.direction = direction;
@@ -45,9 +45,9 @@ public class TileEntityMovingPistonBlock extends TileEntity
         this.progress = this.progressO = 0.0F;
     }
 
-    public int getMovedId()
+    public @NotNull Block<?> getMovedBlock()
     {
-        return this.movedId;
+        return this.movedBlock;
     }
 
 	public int getMovedData()
@@ -123,7 +123,7 @@ public class TileEntityMovingPistonBlock extends TileEntity
         } else {
             stretch = 1.0F - stretch;
         }
-        AABBdc aabb = Blocks.PISTON_MOVING.getLogic().getCollisionShapeFromTileEntity(this.worldObj, new TilePos(this.x, this.y, this.z), this.movedId, stretch, this.direction);
+        AABBdc aabb = Blocks.PISTON_MOVING.getLogic().getCollisionShapeFromTileEntity(this.worldObj, new TilePos(this.x, this.y, this.z), this.movedBlock, stretch, this.direction);
         if (aabb == null) return;
 
         List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(null, aabb);
@@ -145,8 +145,8 @@ public class TileEntityMovingPistonBlock extends TileEntity
         this.progressO = this.progress = 1.0F;
         this.worldObj.removeTileEntity(selfPos);
         invalidate();
-        if(this.worldObj.getBlockId(selfPos) == Blocks.PISTON_MOVING.id()) {
-            this.worldObj.setBlockIdDataRaw(selfPos, this.movedId, this.movedData);
+        if(this.worldObj.getBlockType(selfPos) == Blocks.PISTON_MOVING) {
+            this.worldObj.setBlockTypeDataRaw(selfPos, this.movedBlock, this.movedData);
             if (this.movedEntity != null) {
                 TileEntity oldEnt = this.worldObj.getTileEntity(selfPos);
                 if (oldEnt != null) {
@@ -158,13 +158,13 @@ public class TileEntityMovingPistonBlock extends TileEntity
                 this.movedEntity.z = this.z;
                 this.worldObj.replaceTileEntity(selfPos, this.movedEntity);
             }
-            if (this.movedId != 0) {
-                Block.disableNormalEntityLogic = true;
-                Blocks.blocksList[this.movedId].onPlacedByWorld(this.worldObj, selfPos);
-                Block.disableNormalEntityLogic = false;
-            }
+
+            Block.disableNormalEntityLogic = true;
+            this.movedBlock.onPlacedByWorld(this.worldObj, selfPos);
+            Block.disableNormalEntityLogic = false;
+
             assert this.movedEntity == null || this.worldObj.getTileEntity(selfPos) == this.movedEntity : "Piston failed to actually move entity!";
-            this.worldObj.notifyBlockChange(selfPos, this.movedId);
+            this.worldObj.notifyBlockChange(selfPos, this.movedBlock);
         }
     }
 
@@ -191,7 +191,7 @@ public class TileEntityMovingPistonBlock extends TileEntity
 
     @Override
     public void readAdditionalData(@NotNull CompoundTag compoundTag) {
-        this.movedId = compoundTag.getInteger("blockId");
+        this.movedBlock = Objects.requireNonNullElse(Blocks.getBlock(compoundTag.getInteger("blockId")), Blocks.AIR);
         this.movedData = compoundTag.getInteger("blockData");
         if (compoundTag.containsKey("tileEntity")) {
             CompoundTag entityTag = compoundTag.getCompound("tileEntity");
@@ -205,7 +205,7 @@ public class TileEntityMovingPistonBlock extends TileEntity
     @Override
     public void writeAdditionalData(@NotNull CompoundTag compoundTag)
     {
-        compoundTag.putInt("blockId", this.movedId);
+        compoundTag.putInt("blockId", this.movedBlock.id());
         compoundTag.putInt("blockData", this.movedData);
         if (this.movedEntity != null) {
             CompoundTag entityTag = new CompoundTag();
diff --git a/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java b/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java
index 8527353b8..909a160f3 100644
--- a/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java
+++ b/game/core/src/main/java/net/minecraft/core/block/support/ISupportable.java
@@ -12,7 +12,7 @@ public interface ISupportable {
     @NotNull ISupport getSupportConstraint(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side);
 
     default boolean isSupported(final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Side side) {
-        final @Nullable Block<?> supportingBlock = world.getBlock(tilePos.add(side.getDirection(), new TilePos()));
+        final @Nullable Block<?> supportingBlock = world.getBlockType(tilePos.add(side.getDirection(), new TilePos()));
         if (supportingBlock == null) {
             return false;
         }
diff --git a/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java b/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java
index e2fdc58fb..a85af8cec 100644
--- a/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java
+++ b/game/core/src/main/java/net/minecraft/core/current/util/BlockState.java
@@ -8,29 +8,16 @@ 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;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public class BlockState {
 
-	public static final BlockState AIR = new BlockState(null, 0) {
-		public int getBlockId() { return 0; }
-		public boolean is(Block<?> block) { return false; }
-		public BlockState set(int metadata) { return this; }
-		public boolean isAir() { return true; }
-		public boolean isConductor() { return false; }
-		public boolean isSignalSource() { return false; }
-		public boolean hasSignal(World world, TilePos pos, Direction dir) { return false; }
-		public boolean hasDirectSignal(World world, TilePos pos, Direction dir) { return false; }
-		public boolean canSurvive(World world, TilePos pos) { return true; }
-		public void dropItems(World world, TilePos pos) { }
-		public void neighborChanged(World world, TilePos pos, Block<?> fromBlock) { }
-	};
-
-	private final Block<?> block;
-	private final int metadata;
+	public static final @NotNull BlockState AIR = new BlockState(Blocks.AIR, 0);
 
-	public BlockState(int blockId, int metadata) {
-		this(Blocks.getBlock(blockId), metadata);
-	}
+	private final @NotNull Block<?> block;
+	private final int metadata;
 
 	public BlockState(Block<?> block, int metadata) {
 		this.block = block;
@@ -38,24 +25,19 @@ public class BlockState {
 	}
 
 	@Override
-	public boolean equals(Object obj) {
-		if (obj instanceof BlockState) {
-			BlockState state = (BlockState)obj;
-			return state.block == block && state.metadata == metadata;
+	public boolean equals(final @Nullable Object obj) {
+		if (obj instanceof final @NotNull BlockState state) {
+			return state.block == this.block && state.metadata == this.metadata;
 		}
 
 		return false;
 	}
 
-	public int getBlockId() {
-		return block.id();
-	}
-
-	public Block<?> getBlock() {
+	public @NotNull Block<?> getBlockType() {
 		return block;
 	}
 
-	public boolean is(Block<?> block) {
+	public boolean is(@NotNull Block<?> block) {
 		return this.block == block;
 	}
 
@@ -79,29 +61,29 @@ public class BlockState {
 		return block.isSignalSource();
 	}
 
-	public boolean hasSignal(World world, TilePos pos, Direction dir) {
-		return block.getSignal(world, pos.x, pos.y, pos.z, dir.getSide());
+	public boolean hasSignal(World world, TilePosc pos, Direction dir) {
+		return block.isEmittingSignal(world, pos, dir.getSide());
 	}
 
-	public boolean hasDirectSignal(World world, TilePos pos, Direction dir) {
-		return block.getDirectSignal(world, pos.x, pos.y, pos.z, dir.getSide());
+	public boolean hasDirectSignal(World world, TilePosc pos, Direction dir) {
+		return block.isEmittingDirectSignal(world, pos, dir.getSide());
 	}
 
-	public boolean canSurvive(World world, TilePos pos) {
-		Block<?> block = world.getBlock(pos.x, pos.y, pos.z);
+	public boolean canSurvive(World world, TilePosc pos) {
+		Block<?> block = world.getBlockType(pos);
 		if (block == Blocks.WIRE_REDSTONE) {
             return Blocks.WIRE_REDSTONE.getLogic().isSupported(world, pos, Side.BOTTOM);
 		} else {
-			Block<?> underBlock = world.getBlock(pos.x, pos.y - 1, pos.z);
-			return (block == null || block.getMaterial().isReplaceable()) && underBlock != null && underBlock.isCubeShaped();
+			Block<?> underBlock = world.getBlockType(pos.down(new TilePos()));
+			return block.getMaterial().isReplaceable() && underBlock.isCubeShaped();
 		}
 	}
 
 	public void dropItems(World world, TilePos pos) {
-		block.dropBlockWithCause(world, EnumDropCause.WORLD, pos.x, pos.y, pos.z, 0, null, null);
+		block.dropWithCause(world, EnumDropCause.WORLD, pos, 0, null, null);
 	}
 
 	public void neighborChanged(World world, TilePos pos, Block<?> neighborBlock) {
-		block.onNeighborBlockChange(world, pos.x, pos.y, pos.z, neighborBlock.id());
+		block.onNeighborChanged(world, pos, neighborBlock);
 	}
 }
diff --git a/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java b/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java
index 578ce8242..ccc694224 100644
--- a/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java
+++ b/game/core/src/main/java/net/minecraft/core/current/wire/WireHandler.java
@@ -995,7 +995,7 @@ public class WireHandler {
                 WireNode neighborWire = node.neighborWire;
 
                 if (neighborWire != null) {
-                    updateBlock(node, neighborWire.state.getBlock());
+                    updateBlock(node, neighborWire.state.getBlockType());
                 }
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/current/wire/WireNode.java b/game/core/src/main/java/net/minecraft/core/current/wire/WireNode.java
index cca46b4a4..b949ee832 100644
--- a/game/core/src/main/java/net/minecraft/core/current/wire/WireNode.java
+++ b/game/core/src/main/java/net/minecraft/core/current/wire/WireNode.java
@@ -114,7 +114,7 @@ class WireNode extends Node {
 
         if (this.shouldBreak) {
             this.state.dropItems(this.world, this.pos);
-            this.world.setBlockId(this.pos, 0);
+            this.world.setBlockType(this.pos, Blocks.AIR);
 
             return true;
         }
diff --git a/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java b/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java
index 722ce72e7..ade1e452a 100644
--- a/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java
+++ b/game/core/src/main/java/net/minecraft/core/current/wire/WorldHelper.java
@@ -1,5 +1,7 @@
 package net.minecraft.core.current.wire;
 
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.Blocks;
 import net.minecraft.core.current.util.BlockState;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
@@ -15,13 +17,13 @@ class WorldHelper {
             return BlockState.AIR;
         }
 
-        int blockId = world.getBlockId(pos);
+        final @NotNull Block<?> block = world.getBlockType(pos);
 
-        if (blockId == 0) {
+        if (block == Blocks.AIR) {
             return BlockState.AIR;
         }
 
-        return new BlockState(blockId, world.getBlockData(pos));
+        return new BlockState(block, world.getBlockData(pos));
     }
 
     /**
@@ -35,10 +37,10 @@ class WorldHelper {
             return false;
         }
 
-        int blockId = state.getBlockId();
-        int prevBlockId = world.getBlockId(pos);
+        @NotNull Block<?> block = state.getBlockType();
+        @NotNull Block<?> prevBlock = world.getBlockType(pos);
 
-        if (blockId != prevBlockId) {
+        if (block != prevBlock) {
             return false;
         }
 
@@ -52,7 +54,7 @@ class WorldHelper {
         world.setBlockData(pos, metadata);
 
         // notify clients of the BlockState change
-        world.notifyBlockChange(pos, blockId);
+        world.notifyBlockChange(pos, block);
         // mark the chunk for saving
         world.markBlockDirty(pos);
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/Entity.java b/game/core/src/main/java/net/minecraft/core/entity/Entity.java
index 058afc505..27f6908a4 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/Entity.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/Entity.java
@@ -736,7 +736,7 @@ public abstract class Entity
     public boolean isUnderLiquid(@NotNull Material material) {
         double headY = this.y + (double) getHeadHeight();
         TilePos tilePos = new TilePos(this.x, headY, this.z);
-        Block<?> block = this.world.getBlock(tilePos);
+        Block<?> block = this.world.getBlockType(tilePos);
         if (block != null && block.getMaterial() == material) {
             float f = BlockLogicFluid.getHeight(this.world.getBlockData(tilePos)) - 0.2F;
             float f1 = (float) (tilePos.y + 1) - f;
diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java b/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java
index 5024b055a..583a3aa94 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/EntityFallingBlock.java
@@ -202,7 +202,7 @@ public class EntityFallingBlock extends Entity
 
         final int skylight;
         final int blocklight;
-        if (this.world.getBlockLitInteriorSurface(blockPos) || this.world.getBlock(blockPos) == this.carriedBlock.block()) {
+        if (this.world.getBlockLitInteriorSurface(blockPos) || this.world.getBlockType(blockPos) == this.carriedBlock.block()) {
             TilePos queryPos = new TilePos();
 
             int bU = this.world.getSavedLightValue(LightLayer.Block, blockPos.up(queryPos));
diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityFishingBobber.java b/game/core/src/main/java/net/minecraft/core/entity/EntityFishingBobber.java
index 59eef94b5..dbc9e63d0 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/EntityFishingBobber.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/EntityFishingBobber.java
@@ -186,7 +186,7 @@ public class EntityFishingBobber extends Entity {
             }
         }
         if (isInGround() && this.tilePos != null) {
-            if (this.world.getBlockId(this.tilePos) == Blocks.ROPE.id()) {
+            if (this.world.getBlockType(this.tilePos) == Blocks.ROPE) {
                 this.x = this.tilePos.x + 0.5D;
                 this.y = this.tilePos.y + 0.5D;
                 this.z = this.tilePos.z + 0.5D;
@@ -208,7 +208,7 @@ public class EntityFishingBobber extends Entity {
         nextPos = new Vector3d(this.x + this.xd, this.y + this.yd, this.z + this.zd);
         if (clip != null) {
             nextPos = clip.location;
-            if (clip instanceof HitResult.Tile hitTile && this.world.getBlockId(hitTile.tilePos) == Blocks.ROPE.id()) {
+            if (clip instanceof HitResult.Tile hitTile && this.world.getBlockType(hitTile.tilePos) == Blocks.ROPE) {
                 setInGround(true);
                 this.tilePos = new TilePos(hitTile.tilePos);
             }
@@ -286,7 +286,7 @@ public class EntityFishingBobber extends Entity {
                     rainRate = 200;
                 }
 
-                if (this.world.getBlockId(tileAbove) == Blocks.ALGAE.id()) {
+                if (this.world.getBlockType(tileAbove) == Blocks.ALGAE) {
                     algaeRate = 100;
                 }
                 catchRate = (catchRate - rainRate) - algaeRate;
diff --git a/game/core/src/main/java/net/minecraft/core/entity/Mob.java b/game/core/src/main/java/net/minecraft/core/entity/Mob.java
index 56f029b0d..68e76d4b4 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/Mob.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/Mob.java
@@ -23,6 +23,7 @@ import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.pos.TilePos;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.joml.Vector3d;
@@ -1071,6 +1072,7 @@ public abstract class Mob extends Entity {
         if (Blocks.hasTag(this.world.getBlockId(blockX, blockY, blockZ), BlockTags.PREVENT_MOB_SPAWNS)) {
             return false;
         }
+        if (!this.world.areBlocksLoaded(new TilePos(this.bb.minX - 1, this.bb.minY - 1, this.bb.minZ - 1), new TilePos(this.bb.maxX + 1, this.bb.maxY + 1, this.bb.maxZ + 1))) return false;
         return this.world.checkIfAABBIsClear(this.bb) && this.world.getCubes(this, this.bb).isEmpty() && !this.world.getIsAnyLiquid(this.bb);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/MobPathfinder.java b/game/core/src/main/java/net/minecraft/core/entity/MobPathfinder.java
index f7e47a5ca..12037448a 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/MobPathfinder.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/MobPathfinder.java
@@ -5,6 +5,7 @@ import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.pathfinder.Path;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.joml.Vector3dc;
@@ -146,7 +147,7 @@ public abstract class MobPathfinder extends Mob {
             int x1 = MathHelper.floor((this.x + (double) this.random.nextInt(13)) - 6D);
             int y1 = MathHelper.floor((this.y + (double) this.random.nextInt(7)) - 3D);
             int z1 = MathHelper.floor((this.z + (double) this.random.nextInt(13)) - 6D);
-            float currentPathWeight = getBlockPathWeight(x1, y1, z1);
+            float currentPathWeight = getBlockPathWeight(new TilePos(x1, y1, z1));
             if (currentPathWeight > bestPathWeight) {
                 bestPathWeight = currentPathWeight;
                 if (tilePos != null) {
@@ -168,7 +169,7 @@ public abstract class MobPathfinder extends Mob {
     protected void attackBlockedEntity(@NotNull Entity entity, float f) {
     }
 
-    protected float getBlockPathWeight(int x, int y, int z) {
+    protected float getBlockPathWeight(@NotNull TilePosc blockPos) {
         return 0.0F;
     }
 
@@ -178,10 +179,7 @@ public abstract class MobPathfinder extends Mob {
 
     @Override
     public boolean canSpawnHere() {
-        int x = MathHelper.floor(this.x);
-        int y = MathHelper.floor(this.bb.minY);
-        int z = MathHelper.floor(this.z);
-        return super.canSpawnHere() && getBlockPathWeight(x, y, z) >= 0.0F;
+        return super.canSpawnHere() && getBlockPathWeight(new TilePos(this)) >= 0.0F;
     }
 
     public boolean hasPath() {
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobAnimal.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobAnimal.java
index 189ea6dde..94fdaef6e 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobAnimal.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobAnimal.java
@@ -8,6 +8,8 @@ import net.minecraft.core.util.helper.MathHelper;
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.world.World;
 import net.minecraft.core.block.Blocks;
+import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.season.Seasons;
 import org.jetbrains.annotations.NotNull;
 
@@ -61,14 +63,14 @@ public abstract class MobAnimal extends MobPathfinder
     }
 
     @Override
-	protected float getBlockPathWeight(int x, int y, int z)
-    {
-        if(world.getBlockId(x, y - 1, z) == Blocks.GRASS.id())
+	protected float getBlockPathWeight(@NotNull TilePosc blockPos) {
+        if (!world.isBlockLoaded(blockPos)) return 0;
+        if(world.getBlockType(blockPos.down(new TilePos())) == Blocks.GRASS)
         {
             return 10F;
         } else
         {
-            return world.getLightBrightness(x, y, z) - 0.5F;
+            return world.getLightBrightness(blockPos) - 0.5F;
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java
index 58dd6c077..47b147bf1 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java
@@ -184,7 +184,7 @@ public class MobGhast extends MobFlying
         AABBd aabb = new AABBd(this.bb);
         for (int i = 1; (double) i < d3; i++) {
             aabb.translate(d4, d5, d6);
-            if (!this.world.getCubes(this, aabb).isEmpty()) {
+            if (!this.world.areBlocksLoaded(aabb) || !this.world.getCubes(this, aabb).isEmpty()) {
                 return false;
             }
         }
@@ -233,7 +233,7 @@ public class MobGhast extends MobFlying
         return
             this.world.getDifficulty().canHostileMobsSpawn() &&
                 this.random.nextInt(20) == 0 &&
-                BlockTags.NETHER_MOBS_SPAWN.appliesTo(this.world.getBlock(new TilePos(this.x, this.y - this.heightOffset - 1, this.z))) &&
+                BlockTags.NETHER_MOBS_SPAWN.appliesTo(this.world.getBlockType(new TilePos(this.x, this.y - this.heightOffset - 1, this.z))) &&
                 super.canSpawnHere();
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGiant.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGiant.java
index badeaf224..69a8bfe46 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGiant.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGiant.java
@@ -1,7 +1,8 @@
 package net.minecraft.core.entity.monster;
 
-import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
 
 public class MobGiant extends MobZombie
 {
@@ -21,8 +22,8 @@ public class MobGiant extends MobZombie
         return super.getMaxHealth() * 10;
     }
     @Override
-	protected float getBlockPathWeight(final int x, final int y, final int z)
-    {
-        return this.world.getLightBrightness(x, y, z) - 0.5F;
+	protected float getBlockPathWeight(@NotNull TilePosc blockPos) {
+        if (!this.world.isBlockLoaded(blockPos)) return 0;
+        return this.world.getLightBrightness(blockPos) - 0.5F;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobMonster.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobMonster.java
index 36c2398a5..4b5c6377f 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobMonster.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobMonster.java
@@ -8,6 +8,7 @@ import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.world.World;
 import net.minecraft.core.util.helper.DamageType;
 import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.season.Seasons;
 import org.jetbrains.annotations.NotNull;
 import org.joml.Vector3d;
@@ -109,8 +110,9 @@ public abstract class MobMonster extends MobPathfinder
     }
 
     @Override
-    protected float getBlockPathWeight(int x, int y, int z) {
-        return 0.5F - this.world.getLightBrightness(x, y, z);
+    protected float getBlockPathWeight(@NotNull TilePosc blockPos) {
+        if (!this.world.isBlockLoaded(blockPos)) return 0;
+        return 0.5F - this.world.getLightBrightness(blockPos);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java
index e860ff6f2..297204471 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombiePig.java
@@ -73,10 +73,11 @@ public class MobZombiePig extends MobZombie {
     public boolean canSpawnHere() {
         TilePos tilePos = new TilePos(this);
         if (!this.world.isAirBlock(tilePos)) return false;
-        Block<?> below = this.world.getBlock(tilePos.down(new TilePos()));
+        Block<?> below = this.world.getBlockType(tilePos.down(new TilePos()));
         if (!BlockTags.NETHER_MOBS_SPAWN.appliesTo(below)) return false;
         int blockLight = this.world.getSavedLightValue(LightLayer.Block, tilePos);
         if (blockLight > 7) return false;
+        if (!this.world.areBlocksLoaded(new TilePos(this.bb.minX - 1, this.bb.minY - 1, this.bb.minZ - 1), new TilePos(this.bb.maxX + 1, this.bb.maxY + 1, this.bb.maxZ + 1))) return false;
         return this.world.getDifficulty().canHostileMobsSpawn() && this.world.checkIfAABBIsClear(this.bb) && this.world.getCubes(this, this.bb).isEmpty() && !this.world.getIsAnyLiquid(this.bb);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
index f161b7d88..3971b38eb 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
@@ -82,11 +82,11 @@ public abstract class Player
     public static final int DATA_SELECTED_ART = 17;
     public static final int DATA_HELD_ARROW = 18;
     public static final TextFormatting deathMsgColor = TextFormatting.RED;
-    public ContainerInventory inventory;
+    public final @NotNull ContainerInventory inventory;
     public final @Nullable ItemStack @NotNull [] oldArmorInventory = new ItemStack[4]; // Last tick's armor inventory, used for playing equip sounds at the right time.
-    public MenuAbstract inventorySlots;
-    public MenuAbstract craftingInventory;
-    public Gamemode gamemode = Gamemodes.SURVIVAL;
+    public @NotNull MenuAbstract inventoryMenu;
+    public @NotNull MenuAbstract containerMenu;
+    public @NotNull Gamemode gamemode = Gamemodes.SURVIVAL;
     //    public byte userType;
     public int score;
     public List<String> messageHistory = new ArrayList<>();
@@ -141,14 +141,15 @@ public abstract class Player
         this.timeUntilPortal = 20;
         this.inPortal = false;
         this.bobberEntity = null;
-        this.inventorySlots = new MenuInventory(this.inventory);
-        this.craftingInventory = this.inventorySlots;
+        this.inventoryMenu = new MenuInventory(this.inventory);
+        this.containerMenu = this.inventoryMenu;
         TilePos spawnPoint = world.getSpawnPoint();
         moveTo((double) spawnPoint.x + 0.5D, spawnPoint.y + 1, (double) spawnPoint.z + 0.5D, 0.0F, 0.0F);
 //        rotOffs = 180F;
         this.fireImmuneTicks = 20;
         setTextureIdentifier("minecraft", "char");
         this.noAI = false;
+        this.yRot = 180.0f;
     }
 
     @Override
@@ -311,9 +312,9 @@ public abstract class Player
             this.heldObject.heldTick(this.world, this);
         }
 
-        if (!this.world.isClientSide && this.craftingInventory != null && !this.craftingInventory.stillValid(this)) {
+        if (!this.world.isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) {
             closeScreen();
-            this.craftingInventory = this.inventorySlots;
+            this.containerMenu = this.inventoryMenu;
         }
         addStat(StatList.minutesPlayedStat, 1);
         if (this.vehicle == null) {
@@ -327,7 +328,7 @@ public abstract class Player
     }
 
     protected void closeScreen() {
-        this.craftingInventory = this.inventorySlots;
+        this.containerMenu = this.inventoryMenu;
     }
 
     @Override
@@ -476,7 +477,7 @@ public abstract class Player
         }
 
         if (!this.world.getGameRuleValue(GameRules.KEEP_INVENTORY)) {
-            this.craftingInventory.onCraftGuiClosed(this);
+            this.containerMenu.onCraftGuiClosed(this);
             this.inventory.dropAllItems();
         }
         if (this.heldObject != null) { // TODO consider whether making the held object kept with keep inventory is a good idea
@@ -1087,9 +1088,9 @@ public abstract class Player
     @Override
     public void remove() {
         super.remove();
-        this.inventorySlots.onCraftGuiClosed(this);
-        if (this.craftingInventory != null) {
-            this.craftingInventory.onCraftGuiClosed(this);
+        this.inventoryMenu.onCraftGuiClosed(this);
+        if (this.containerMenu != null) {
+            this.containerMenu.onCraftGuiClosed(this);
         }
     }
 
@@ -1193,7 +1194,7 @@ public abstract class Player
         setupScale();
         TilePos bedPos = this.bedTilePos;
         Block<?> b;
-        if (bedPos != null && (b = this.world.getBlock(bedPos)) != null && b.getLogic() instanceof BlockLogicBed) {
+        if (bedPos != null && (b = this.world.getBlockType(bedPos)) != null && b.getLogic() instanceof BlockLogicBed) {
             BlockLogicBed.setBedOccupied(this.world, bedPos, false);
             TilePos emptyPos = BlockLogicBed.getNearestEmptyTilePos(this.world, bedPos, 0);
             if (emptyPos == null) {
@@ -1224,7 +1225,7 @@ public abstract class Player
         chunkProvider.prepareChunk(coords.x + 3 >> 4, coords.z - 3 >> 4);
         chunkProvider.prepareChunk(coords.x - 3 >> 4, coords.z + 3 >> 4);
         chunkProvider.prepareChunk(coords.x + 3 >> 4, coords.z + 3 >> 4);
-        if (Block.hasLogicClass(world.getBlock(coords), BlockLogicBed.class)) {
+        if (Block.hasLogicClass(world.getBlockType(coords), BlockLogicBed.class)) {
             return BlockLogicBed.getNearestEmptyTilePos(world, coords, 0);
         } else {
             return null;
@@ -1432,10 +1433,10 @@ public abstract class Player
         this.gamemode = gamemode;
 
         MenuInventory newContainer = gamemode.getInventoryMenu(this.inventory);
-        if (this.craftingInventory == this.inventorySlots) {
-            this.craftingInventory = newContainer;
+        if (this.containerMenu == this.inventoryMenu) {
+            this.containerMenu = newContainer;
         }
-        this.inventorySlots = newContainer;
+        this.inventoryMenu = newContainer;
         if (!gamemode.hasPlayerFlight()) {
             this.noPhysics = false;
         }
diff --git a/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileArrow.java b/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileArrow.java
index 01138b4ce..7d732e303 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileArrow.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/projectile/ProjectileArrow.java
@@ -108,7 +108,7 @@ public class ProjectileArrow extends Projectile {
             this.xRotO = this.xRot = (float) ((Math.atan2(this.yd, f) * 180D) / Math.PI);
         }
         if (this.tilePos != null) {
-            Block<?> block = this.world.getBlock(this.tilePos);
+            Block<?> block = this.world.getBlockType(this.tilePos);
             if (block != null) {
                 AABBdc aabb = block.getCollisionAABB(this.world, this.tilePos);
                 if (aabb != null && aabb.containsPoint(new Vector3d(this.x, this.y, this.z))) {
@@ -117,7 +117,7 @@ public class ProjectileArrow extends Projectile {
             }
         }
         if (isGrounded() && this.tilePos != null) {
-            Block<?> b = this.world.getBlock(this.tilePos);
+            Block<?> b = this.world.getBlockType(this.tilePos);
             int meta = this.world.getBlockData(this.tilePos);
             if (b != this.inTile || meta != this.inData) {
                 setGrounded(false);
@@ -171,7 +171,7 @@ public class ProjectileArrow extends Projectile {
             }
         } else if (hitResult instanceof HitResult.Tile hitTile) {
             this.tilePos = new TilePos(hitTile.tilePos);
-            this.inTile = this.world.getBlock(hitTile.tilePos);
+            this.inTile = this.world.getBlockType(hitTile.tilePos);
             this.inData = this.world.getBlockData(hitTile.tilePos);
             this.xd = (float) (hitResult.location.x() - this.x);
             this.yd = (float) (hitResult.location.y() - this.y);
diff --git a/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityMinecart.java b/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityMinecart.java
index 2fb52e496..1f6db4191 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityMinecart.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityMinecart.java
@@ -346,7 +346,7 @@ public class EntityMinecart extends Entity implements Container {
         final double maxSpeed = 0.4D;
         boolean didFurnacePush = false;
         final double d5 = 0.0078125D;
-        Block<?> block = this.world.getBlock(tilePos);
+        Block<?> block = this.world.getBlockType(tilePos);
         if (block != null && block.getLogic() instanceof BlockLogicRail rail) {
             Vector3dc vec3d = getPos(this.x, this.y, this.z);
             this.y = blockY;
diff --git a/game/core/src/main/java/net/minecraft/core/item/Item.java b/game/core/src/main/java/net/minecraft/core/item/Item.java
index 13bc34eff..5434bbcdd 100644
--- a/game/core/src/main/java/net/minecraft/core/item/Item.java
+++ b/game/core/src/main/java/net/minecraft/core/item/Item.java
@@ -27,12 +27,7 @@ import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
+import java.util.*;
 import java.util.function.Supplier;
 
 @SuppressWarnings("unchecked")
@@ -266,18 +261,16 @@ public class Item implements ITaggable<Item>, IItemConvertible {
     /**
      * Called before a block is destroyed with this item. If the return value is false, the block won't be destroyed
      */
-    public boolean beforeBlockDestroyed(final @NotNull ItemStack selfStack, final @NotNull World world, final @NotNull Player player, final @NotNull Block<?> block, final @NotNull TilePos blockPos, final @NotNull Side side) {
+    public boolean beforeBlockDestroyed(final @NotNull ItemStack selfStack, final @NotNull World world, final @NotNull Player player, final @NotNull Block<?> block, final @NotNull TilePosc blockPos, final @NotNull Side side) {
         return true;
     }
 
     @Deprecated
     public final boolean onBlockDestroyed(final @NotNull World world, final @NotNull ItemStack selfStack, final int removedBlockId, final int x, final int y, final int z, final @NotNull Side side, final @NotNull Mob mob) {
-        Block<?> b = Blocks.getBlock(removedBlockId);
-        assert b != null;
-        return onBlockDestroyed(selfStack, world, mob, b, new TilePos(x, y, z), side);
+        return onBlockDestroyed(selfStack, world, mob, Objects.requireNonNull(Blocks.getBlock(removedBlockId)), new TilePos(x, y, z), side);
     }
 
-    public boolean onBlockDestroyed(final @NotNull ItemStack selfStack, final @NotNull World world, final @NotNull Mob mob, final @NotNull Block<?> removedBlock, final @NotNull TilePos blockPos, final @NotNull Side side) {
+    public boolean onBlockDestroyed(final @NotNull ItemStack selfStack, final @NotNull World world, final @NotNull Mob mob, final @NotNull Block<?> removedBlock, final @NotNull TilePosc blockPos, final @NotNull Side side) {
         return false;
     }
 
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 4cf988695..9c4a28593 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
@@ -28,8 +28,8 @@ 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.setBlockIdDataNotify(pos, Blocks.BED.id(), dir.getHorizontalIndex());
-                world.setBlockIdDataNotify(pos2, Blocks.BED.id(), dir.getHorizontalIndex() | 0b1000);
+                world.setBlockTypeDataNotify(pos, Blocks.BED, dir.getHorizontalIndex());
+                world.setBlockTypeDataNotify(pos2, Blocks.BED, dir.getHorizontalIndex() | 0b1000);
                 return true;
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java b/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java
index 05c89c8c3..95329ef10 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemBoat.java
@@ -30,7 +30,7 @@ public class ItemBoat extends Item {
         if (rayCast instanceof HitResult.Tile hitTile) {
             TilePos pos = new TilePos(hitTile.tilePos);
             if (!world.isClientSide) {
-                if (world.getBlockId(pos) == Blocks.LAYER_SNOW.id()) {
+                if (world.getBlockType(pos) == Blocks.LAYER_SNOW) {
                     pos.y--;
                 }
                 EntityBoat boat = new EntityBoat(world, pos.x + 0.5F, pos.y + 1.0F, pos.z + 0.5F);
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 459d54675..0d632252a 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
@@ -46,7 +46,7 @@ public class ItemBucket extends Item {
             return selfStack;
         }
 
-        Block<?> block = world.getBlock(rayCastPos);
+        Block<?> block = world.getBlockType(rayCastPos);
         if (block != null && !block.hasTag(BlockTags.PLACE_OVERWRITES) && !block.hasTag(BlockTags.BROKEN_BY_FLUIDS)) {
             Side side = hitTile.side;
             rayCastPos.x += side.getOffsetX();
@@ -63,11 +63,8 @@ public class ItemBucket extends Item {
                 world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, rayCastPos.x + 0.5F, rayCastPos.y + 0.5F, rayCastPos.z + 0.5F, "liquid.splash", 0.5f, 1.0f);
             }
             player.swingItem();
-            Block<?> block1 = world.getBlock(rayCastPos);
-            if (block1 != null) {
-                block1.dropWithCause(world, EnumDropCause.WORLD, rayCastPos, world.getBlockData(rayCastPos), null, null);
-            }
-            world.setBlockIdDataNotify(rayCastPos, this.blockToPlace.id(), 0);
+            world.getBlockType(rayCastPos).dropWithCause(world, EnumDropCause.WORLD, rayCastPos, world.getBlockData(rayCastPos), null, null);
+            world.setBlockTypeNotify(rayCastPos, this.blockToPlace);
             if (player.getGamemode().hasBlockConsumption()) {
                 return new ItemStack(Items.BUCKET);
             }
@@ -83,9 +80,9 @@ public class ItemBucket extends Item {
             return;
         }
         TilePos posAhead = blockPos.add(direction, new TilePos());
-        Block<?> b = world.getBlock(posAhead);
-        if (b == null || BlockTags.PLACE_OVERWRITES.appliesTo(b) || BlockTags.BROKEN_BY_FLUIDS.appliesTo(b)) {
-            world.setBlockIdNotify(posAhead, this.blockToPlace.id());
+        Block<?> b = world.getBlockType(posAhead);
+        if (b.hasTag(BlockTags.PLACE_OVERWRITES) || b.hasTag(BlockTags.BROKEN_BY_FLUIDS)) {
+            world.setBlockTypeNotify(posAhead, this.blockToPlace);
             selfStack.itemID = Items.BUCKET.id;
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemBucketEmpty.java b/game/core/src/main/java/net/minecraft/core/item/ItemBucketEmpty.java
index 1904e2510..a13f2fa63 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemBucketEmpty.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemBucketEmpty.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.item;
 
+import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.block.material.Materials;
 import net.minecraft.core.entity.animal.MobCow;
@@ -37,12 +38,12 @@ public class ItemBucketEmpty extends Item {
                 return selfStack;
             } else if (world.getBlockMaterial(hitTile.tilePos) == Materials.WATER && world.getBlockData(hitTile.tilePos) == 0) {
                 if (useBucket(player, new ItemStack(Items.BUCKET_WATER))) {
-                    world.setBlockIdNotify(hitTile.tilePos, 0);
+                    world.setBlockTypeNotify(hitTile.tilePos, Blocks.AIR);
                     player.swingItem();
                 }
             } else if (world.getBlockMaterial(hitTile.tilePos) == Materials.LAVA && world.getBlockData(hitTile.tilePos) == 0) {
                 if (useBucket(player, new ItemStack(Items.BUCKET_LAVA))) {
-                    world.setBlockIdNotify(hitTile.tilePos, 0);
+                    world.setBlockTypeNotify(hitTile.tilePos, Blocks.AIR);
                     player.swingItem();
                 }
             }
@@ -58,11 +59,11 @@ public class ItemBucketEmpty extends Item {
 
         TilePos shiftedPos = blockPos.add(direction, new TilePos());
         if (world.getBlockMaterial(shiftedPos) == Materials.WATER && world.getBlockData(shiftedPos) == 0) {
-            world.setBlockIdNotify(shiftedPos, 0);
+            world.setBlockTypeNotify(shiftedPos, Blocks.AIR);
             selfStack.itemID = Items.BUCKET_WATER.id;
             return;
         } else if (world.getBlockMaterial(shiftedPos) == Materials.LAVA && world.getBlockData(shiftedPos) == 0) {
-            world.setBlockIdNotify(shiftedPos, 0);
+            world.setBlockTypeNotify(shiftedPos, Blocks.AIR);
             selfStack.itemID = Items.BUCKET_LAVA.id;
             return;
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemDiscMusic.java b/game/core/src/main/java/net/minecraft/core/item/ItemDiscMusic.java
index 40deff422..baa816515 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemDiscMusic.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemDiscMusic.java
@@ -28,7 +28,7 @@ public class ItemDiscMusic extends Item {
 
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        if (world.getBlockId(blockPos) == Blocks.JUKEBOX.id() && world.getBlockData(blockPos) == 0) {
+        if (world.getBlockType(blockPos) == Blocks.JUKEBOX && world.getBlockData(blockPos) == 0) {
             if (!world.isClientSide) {
                 Blocks.JUKEBOX.getLogic().playRecord(world, new TilePos(blockPos), this.id);
                 world.playBlockEvent(null, blockPos, LevelListener.EVENT_JUKEBOX_TOGGLE, this.id);
@@ -42,8 +42,7 @@ public class ItemDiscMusic extends Item {
     @Override
     public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) {
         TilePos pos = blockPos.add(direction, new TilePos());
-        int b = world.getBlockId(pos);
-        if (b == Blocks.JUKEBOX.id() && world.getBlockData(pos) == 0) {
+        if (world.getBlockType(pos) == Blocks.JUKEBOX && world.getBlockData(pos) == 0) {
             Blocks.JUKEBOX.getLogic().playRecord(world, new TilePos(pos), this.id);
             world.playBlockEvent(null, pos, LevelListener.EVENT_JUKEBOX_TOGGLE, this.id);
             selfStack.consumeItem(null);
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 5f273a557..aa381176a 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
@@ -41,8 +41,8 @@ public class ItemDoor extends Item {
 
         int isSolidBlockLeft = (isSupported(world, blockPos, leftDir, false) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), leftDir, false) ? 1 : 0);
         int isSolidBlockRight = (isSupported(world, blockPos, leftDir.getOpposite(), true) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), leftDir.getOpposite(), true) ? 1 : 0);
-        boolean isDoorLeft = world.getBlockId(blockPos.add(leftDir, new TilePos())) == this.doorBlockBottom.id() || world.getBlockId(blockPos.add(leftDir, new TilePos()).up(new TilePos())) == this.doorBlockTop.id();
-        boolean isDoorRight = world.getBlockId(blockPos.sub(leftDir, new TilePos())) == this.doorBlockBottom.id() || world.getBlockId(blockPos.sub(leftDir, new TilePos()).up(new TilePos())) == this.doorBlockTop.id();
+        boolean isDoorLeft = world.getBlockType(blockPos.add(leftDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.add(leftDir, new TilePos()).up(new TilePos())) == this.doorBlockTop;
+        boolean isDoorRight = world.getBlockType(blockPos.sub(leftDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.sub(leftDir, new TilePos()).up(new TilePos())) == this.doorBlockTop;
         boolean isMirrored = false;
 
         if (isDoorLeft && !isDoorRight) {
@@ -66,11 +66,11 @@ public class ItemDoor extends Item {
         }
 
         world.noNeighborUpdate = true;
-        world.setBlockIdDataNotify(blockPos, this.doorBlockBottom.id(), meta);
-        world.setBlockIdDataNotify(blockPos.up(new TilePos()), this.doorBlockTop.id(), meta);
+        world.setBlockTypeDataNotify(blockPos, this.doorBlockBottom, meta);
+        world.setBlockTypeDataNotify(blockPos.up(new TilePos()), this.doorBlockTop, meta);
         world.noNeighborUpdate = false;
-        world.notifyBlocksOfNeighborChange(blockPos, this.doorBlockBottom.id());
-        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.doorBlockTop.id());
+        world.notifyBlocksOfNeighborChange(blockPos, this.doorBlockBottom);
+        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.doorBlockTop);
         world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.doorBlockBottom, EnumBlockSoundEffectType.PLACE);
         this.doorBlockBottom.onPlacedByMob(world, blockPos, side, player, xHit, yHit);
         this.doorBlockTop.onPlacedByMob(world, blockPos.up(new TilePos()), side, player, xHit, yHit);
@@ -95,8 +95,8 @@ public class ItemDoor extends Item {
 
         int isSolidBlockLeft = (isSupported(world, blockPos, lefDir, false) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), lefDir, false) ? 1 : 0);
         int isSolidBlockRight = (isSupported(world, blockPos, lefDir.getOpposite(), true) ? 1 : 0) + (isSupported(world, blockPos.up(new TilePos()), lefDir.getOpposite(), true) ? 1 : 0);
-        boolean isDoorLeft = world.getBlockId(blockPos.add(lefDir, new TilePos())) == this.doorBlockBottom.id() || world.getBlockId(blockPos.add(lefDir, new TilePos()).up(new TilePos())) == this.doorBlockTop.id();
-        boolean isDoorRight = world.getBlockId(blockPos.sub(lefDir, new TilePos())) == this.doorBlockBottom.id() || world.getBlockId(blockPos.sub(lefDir, new TilePos()).up(new TilePos())) == this.doorBlockTop.id();
+        boolean isDoorLeft = world.getBlockType(blockPos.add(lefDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.add(lefDir, new TilePos()).up(new TilePos())) == this.doorBlockTop;
+        boolean isDoorRight = world.getBlockType(blockPos.sub(lefDir, new TilePos())) == this.doorBlockBottom || world.getBlockType(blockPos.sub(lefDir, new TilePos()).up(new TilePos())) == this.doorBlockTop;
         boolean isMirrored = false;
 
         if (isDoorLeft && !isDoorRight) {
@@ -119,11 +119,11 @@ public class ItemDoor extends Item {
         }
 
         world.noNeighborUpdate = true;
-        world.setBlockIdDataNotify(blockPos, this.doorBlockBottom.id(), meta);
-        world.setBlockIdDataNotify(blockPos.up(new TilePos()), this.doorBlockTop.id(), meta);
+        world.setBlockTypeDataNotify(blockPos, this.doorBlockBottom, meta);
+        world.setBlockTypeDataNotify(blockPos.up(new TilePos()), this.doorBlockTop, meta);
         world.noNeighborUpdate = false;
-        world.notifyBlocksOfNeighborChange(blockPos, this.doorBlockBottom.id());
-        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.doorBlockTop.id());
+        world.notifyBlocksOfNeighborChange(blockPos, this.doorBlockBottom);
+        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.doorBlockTop);
         world.playBlockSoundEffect(null, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.doorBlockBottom, EnumBlockSoundEffectType.PLACE);
         this.doorBlockBottom.onPlacedOnSide(world, blockPos, direction.getSide(), 0.5, 0.5);
         this.doorBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.getSide(), 0.5, 0.5);
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemDye.java b/game/core/src/main/java/net/minecraft/core/item/ItemDye.java
index 7d8e7d181..e8844b635 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemDye.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemDye.java
@@ -40,7 +40,7 @@ public class ItemDye extends Item {
 
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xPlaced, double yPlaced) {
-        Block<?> block = world.getBlock(blockPos);
+        Block<?> block = world.getBlockType(blockPos);
         if (Block.hasLogicClass(block, BlockLogicSign.class) && world.getTileEntity(blockPos) instanceof TileEntitySign sign) {
             if ((DyeColor.WHITE.itemMeta - selfStack.getMetadata()) != sign.getColor().id) {
                 sign.setColor(TextFormatting.get(DyeColor.WHITE.itemMeta - selfStack.getMetadata()));
@@ -61,12 +61,12 @@ public class ItemDye extends Item {
             }
             if (block == Blocks.DIRT) {
                 if (!world.isClientSide) {
-                    if (Blocks.lightBlock[world.getBlockId(blockPos.up(queryPos))] <= 2) {
-                        int grass = Blocks.GRASS.id();
+                    if (world.getBlockType(blockPos.up(queryPos)).lightBlock() <= 2) {
+                        @NotNull Block<?> grass = Blocks.GRASS;
                         if (world.dimensionData.getWorldType() == WorldTypes.OVERWORLD_RETRO) {
-                            grass = Blocks.GRASS_RETRO.id();
+                            grass = Blocks.GRASS_RETRO;
                         }
-                        world.setBlockIdNotify(blockPos, grass);
+                        world.setBlockTypeNotify(blockPos, grass);
                         if (player == null || player.getGamemode().hasBlockConsumption()) {
                             selfStack.stackSize--;
                         }
@@ -76,9 +76,9 @@ public class ItemDye extends Item {
             }
             if (block == Blocks.DIRT_SCORCHED) {
                 if (!world.isClientSide) {
-                    if (Blocks.lightBlock[world.getBlockId(blockPos.up(queryPos))] <= 2) {
-                        int grass = Blocks.GRASS_SCORCHED.id();
-                        world.setBlockIdNotify(blockPos, grass);
+                    if (world.getBlockType(blockPos.up(queryPos)).lightBlock() <= 2) {
+                        @NotNull Block<?> grass = Blocks.GRASS_SCORCHED;
+                        world.setBlockTypeNotify(blockPos, grass);
                         if (player == null || player.getGamemode().hasBlockConsumption()) {
                             selfStack.stackSize--;
                         }
@@ -100,37 +100,36 @@ public class ItemDye extends Item {
                             p.x += itemRand.nextInt(3) - 1;
                             p.y += ((itemRand.nextInt(3) - 1) * itemRand.nextInt(3)) / 2;
                             p.z += itemRand.nextInt(3) - 1;
-                            int id1 = world.getBlockId(p.down(queryPos));
-                            if (Blocks.blocksList[id1] == null || !Blocks.blocksList[id1].hasTag(BlockTags.GROWS_FLOWERS)) {
+                            if (!world.getBlockType(p.down(queryPos)).hasTag(BlockTags.GROWS_FLOWERS)) {
                                 continue label0;
                             }
                         }
 
-                        if (world.getBlockId(p) != 0) {
+                        if (world.getBlockType(p) != Blocks.AIR) {
                             continue;
                         }
                         if (itemRand.nextInt(10) != 0) {
-                            if (world.getBlockId(p.down(queryPos)) == Blocks.DIRT_SCORCHED.id() ||
-                                world.getBlockId(p.down(queryPos)) == Blocks.DIRT_SCORCHED_RICH.id())
-                                world.setBlockIdNotify(p, Blocks.SPINIFEX.id());
+                            if (world.getBlockType(p.down(queryPos)) == Blocks.DIRT_SCORCHED ||
+                                world.getBlockType(p.down(queryPos)) == Blocks.DIRT_SCORCHED_RICH)
+                                world.setBlockTypeNotify(p, Blocks.SPINIFEX);
                             else
-                                world.setBlockIdNotify(p, Blocks.TALLGRASS.id());
+                                world.setBlockTypeNotify(p, Blocks.TALLGRASS);
                             continue;
                         }
                         int r = itemRand.nextInt(12);
                         Biome biome = world.getBlockBiome(p);
                         if (r < 1) {
-                            world.setBlockIdNotify(p, Blocks.FLOWER_YELLOW.id());
+                            world.setBlockTypeNotify(p, Blocks.FLOWER_YELLOW);
                         } else if (r < 2) {
-                            world.setBlockIdNotify(p, Blocks.FLOWER_RED.id());
+                            world.setBlockTypeNotify(p, Blocks.FLOWER_RED);
                         } else if (r < 4 && (biome == Biomes.OVERWORLD_BIRCH_FOREST || biome == Biomes.OVERWORLD_SEASONAL_FOREST)) {
-                            world.setBlockIdNotify(p, Blocks.FLOWER_PINK.id());
+                            world.setBlockTypeNotify(p, Blocks.FLOWER_PINK);
                         } else if (r < 6 && (biome == Biomes.OVERWORLD_MEADOW || biome == Biomes.OVERWORLD_BOREAL_FOREST || biome == Biomes.OVERWORLD_SHRUBLAND)) {
-                            world.setBlockIdNotify(p, Blocks.FLOWER_PURPLE.id());
+                            world.setBlockTypeNotify(p, Blocks.FLOWER_PURPLE);
                         } else if (r < 8 && (biome == Biomes.OVERWORLD_FOREST || biome == Biomes.OVERWORLD_SWAMPLAND || biome == Biomes.OVERWORLD_RAINFOREST || biome == Biomes.OVERWORLD_GRASSLANDS || biome == Biomes.OVERWORLD_CAATINGA)) {
-                            world.setBlockIdNotify(p, Blocks.FLOWER_LIGHT_BLUE.id());
+                            world.setBlockTypeNotify(p, Blocks.FLOWER_LIGHT_BLUE);
                         } else if (r < 10 && (biome == Biomes.OVERWORLD_PLAINS || biome == Biomes.OVERWORLD_GRASSLANDS || biome == Biomes.OVERWORLD_OUTBACK || biome == Biomes.OVERWORLD_OUTBACK_GRASSY)) {
-                            world.setBlockIdNotify(p, Blocks.FLOWER_ORANGE.id());
+                            world.setBlockTypeNotify(p, Blocks.FLOWER_ORANGE);
                         }
                     }
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java b/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java
index 528e97afb..20777f0b1 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemFireStriker.java
@@ -31,7 +31,7 @@ public class ItemFireStriker extends Item {
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
         blockPos = blockPos.add(side.getDirection(), new TilePos());
         if (world.isAirBlock(blockPos)) {
-            if (world.setBlockIdNotify(blockPos, Blocks.FIRE.id())) {
+            if (world.setBlockTypeNotify(blockPos, Blocks.FIRE)) {
                 world.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, (double) blockPos.x() + 0.5D, (double) blockPos.y() + 0.5D, (double) blockPos.z() + 0.5D, "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F);
                 selfStack.damageItem(1, player);
                 return true;
@@ -46,15 +46,15 @@ public class ItemFireStriker extends Item {
         if (!onUseOnBlock(selfStack, world, null, blockPos, direction.getSide(), 0.5, 0.5)) {
             blockPos = blockPos.add(direction, new TilePos());
             TilePos queryPos = new TilePos();
-            Block<?> b = world.getBlock(blockPos);
+            Block<?> b = world.getBlockType(blockPos);
             if (Block.getLogicClass(b) instanceof BlockLogicBrazier brazier && brazier.isBurning()) {
-                if (Block.hasLogicClass(world.getBlock(blockPos.east(queryPos)), BlockLogicFluid.class) ||
-                    Block.hasLogicClass(world.getBlock(blockPos.west(queryPos)), BlockLogicFluid.class) ||
-                    Block.hasLogicClass(world.getBlock(blockPos.south(queryPos)), BlockLogicFluid.class) ||
-                    Block.hasLogicClass(world.getBlock(blockPos.north(queryPos)), BlockLogicFluid.class)) {
+                if (Block.hasLogicClass(world.getBlockType(blockPos.east(queryPos)), BlockLogicFluid.class) ||
+                    Block.hasLogicClass(world.getBlockType(blockPos.west(queryPos)), BlockLogicFluid.class) ||
+                    Block.hasLogicClass(world.getBlockType(blockPos.south(queryPos)), BlockLogicFluid.class) ||
+                    Block.hasLogicClass(world.getBlockType(blockPos.north(queryPos)), BlockLogicFluid.class)) {
                     return;
                 }
-                world.setBlockIdDataNotify(blockPos, Blocks.BRAZIER_ACTIVE.id(), 0);
+                world.setBlockTypeNotify(blockPos, Blocks.BRAZIER_ACTIVE);
                 selfStack.damageItem(1, null);
                 world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (double) blockPos.x() + 0.5D, (double) blockPos.y() + 0.5D, (double) blockPos.z() + 0.5D, "fire.ignite", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
             } else if (Block.getLogicClass(b) instanceof BlockLogicTNT tnt) {
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java b/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java
index 1289b5f73..fb4726bc3 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemFlag.java
@@ -33,7 +33,7 @@ public class ItemFlag extends Item {
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
         // copy flag data to empty flag
-        if (world.getBlockId(blockPos) == Blocks.FLAG.id() && player != null && !player.isSneaking()) {
+        if (world.getBlockType(blockPos) == Blocks.FLAG && player != null && !player.isSneaking()) {
             if (world.getTileEntity(blockPos) instanceof TileEntityFlag flag) {
                 CompoundTag flagData = selfStack.getData().getCompoundOrDefault("FlagData", new CompoundTag());
                 if (hasFlagBeenDrawnOn(selfStack) && doesFlagContainDyes(selfStack)) {
@@ -67,7 +67,7 @@ public class ItemFlag extends Item {
         }
 
         world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.FLAG, EnumBlockSoundEffectType.PLACE);
-        world.setBlockIdDataNotify(blockPos, Blocks.FLAG.id(), 0);
+        world.setBlockTypeNotify(blockPos, Blocks.FLAG);
 
         selfStack.consumeItem(player);
         if (world.getTileEntity(blockPos) instanceof TileEntityFlag flag) {
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemMap.java b/game/core/src/main/java/net/minecraft/core/item/ItemMap.java
index 1b00dd329..11b149740 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemMap.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemMap.java
@@ -126,7 +126,7 @@ public class ItemMap extends Item implements IComplexItem
 
 	@Override
 	public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-		if (world.getBlockId(blockPos) == Blocks.FLAG.id()) {
+		if (world.getBlockType(blockPos) == Blocks.FLAG) {
 			if (hasInitialized(selfStack)) {
 				for (byte scale = 0; scale <= ItemMapSavedData.MAX_SCALE; scale++) {
 					ItemMapSavedData mapData = getOrCreateSavedData((short) selfStack.getMetadata(), scale, world);
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java b/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java
index 971180231..ffa78f320 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemMinecart.java
@@ -27,7 +27,7 @@ public class ItemMinecart extends Item {
 
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        Block<?> block = world.getBlock(blockPos);
+        Block<?> block = world.getBlockType(blockPos);
         if (!Block.hasLogicClass(block, BlockLogicRail.class)) { return false; }
 
         if(!world.isClientSide) {
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java b/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java
index 881ceeb67..8b969fc60 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemPaintBrush.java
@@ -38,8 +38,7 @@ public class ItemPaintBrush extends Item {
 
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        final int id = world.getBlockId(blockPos);
-        final Block<?> block = Blocks.getBlock(id);
+        final Block<?> block = world.getBlockType(blockPos);
 
         if (Block.hasLogicClass(block, BlockLogicSign.class) && world.getTileEntity(blockPos) instanceof TileEntitySign sign && (player != null && player.isSneaking())) {
             final DyeColor color = getColor(selfStack);
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java b/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java
index e66293138..89bb4b95e 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemPebble.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.item;
 
+import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.block.tag.BlockTags;
@@ -38,10 +39,10 @@ public class ItemPebble extends Item implements IDispensable {
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
         if (player == null) return false;
-        int id = world.getBlockId(blockPos);
+        @NotNull Block<?> block = world.getBlockType(blockPos);
         int meta = world.getBlockData(blockPos);
-        if (id != Blocks.OVERLAY_PEBBLES.id() && Blocks.blocksList[id] != null && Blocks.blocksList[id].hasTag(BlockTags.PLACE_OVERWRITES)) {
-            id = 0;
+        if (block != Blocks.OVERLAY_PEBBLES && block.hasTag(BlockTags.PLACE_OVERWRITES)) {
+            block = Blocks.AIR;
             meta = 0;
         }
         if (selfStack.stackSize <= 0) {
@@ -52,31 +53,29 @@ public class ItemPebble extends Item implements IDispensable {
         }
 
         // Check if we're placing "inside" a layer
-        if (id == Blocks.OVERLAY_PEBBLES.id() && side == Side.TOP) {
+        if (block == Blocks.OVERLAY_PEBBLES && side == Side.TOP) {
             final int newMeta = meta + 1;
             if (!world.canPlaceOnSurfaceOfBlock(blockPos.down(new TilePos()))) {
                 return false;
             }
 
             if (newMeta < 3) {
-                world.setBlockIdDataNotify(blockPos, Blocks.OVERLAY_PEBBLES.id(), newMeta);
+                world.setBlockTypeDataNotify(blockPos, Blocks.OVERLAY_PEBBLES, newMeta);
                 world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.OVERLAY_PEBBLES, EnumBlockSoundEffectType.PLACE);
                 selfStack.consumeItem(player);
                 return true;
             }
-
-
         }
 
         // Offset position
-        if (id != 0) {
+        if (block != Blocks.AIR) {
             blockPos = blockPos.add(side.getDirection(), new TilePos());
-            id = world.getBlockId(blockPos);
+            block = world.getBlockType(blockPos);
             meta = world.getBlockData(blockPos);
         }
 
         // Check if the block we're placing into is a layer
-        if (id == Blocks.OVERLAY_PEBBLES.id()) {
+        if (block == Blocks.OVERLAY_PEBBLES) {
             final int newMeta = meta + 1;
 
             final AABBdc bbBox = new AABBd(blockPos.x(), blockPos.y(), blockPos.z(), blockPos.x() + 1f, blockPos.y() + (2 * (newMeta + 1)) / 16.0f, blockPos.z() + 1f);
@@ -85,7 +84,7 @@ public class ItemPebble extends Item implements IDispensable {
             }
 
             if (newMeta < 3) {
-                world.setBlockIdDataNotify(blockPos, Blocks.OVERLAY_PEBBLES.id(), newMeta);
+                world.setBlockTypeDataNotify(blockPos, Blocks.OVERLAY_PEBBLES, newMeta);
                 world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.OVERLAY_PEBBLES, EnumBlockSoundEffectType.PLACE);
                 selfStack.consumeItem(player);
                 return true;
@@ -95,7 +94,7 @@ public class ItemPebble extends Item implements IDispensable {
 
         // Regular placement, as all else fails
         if (world.canBlockIdBePlacedAt(Blocks.OVERLAY_PEBBLES.id(), blockPos, false, side) && world.canPlaceOnSurfaceOfBlock(blockPos.down(new TilePos()))) {
-            if (world.setBlockIdDataNotify(blockPos, Blocks.OVERLAY_PEBBLES.id(), 0)) {
+            if (world.setBlockTypeNotify(blockPos, Blocks.OVERLAY_PEBBLES)) {
                 Blocks.OVERLAY_PEBBLES.onPlacedByMob(world, blockPos, side, player, xHit, yHit);
                 world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.OVERLAY_PEBBLES, EnumBlockSoundEffectType.PLACE);
                 selfStack.consumeItem(player);
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java
index 212e44032..bc5ba2bdb 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemPlaceable.java
@@ -38,7 +38,7 @@ public class ItemPlaceable extends Item {
             return false;
         }
         if (world.canBlockIdBePlacedAt(this.blockToPlace.id(), blockPos, false, side) && selfStack.consumeItem(player)) {
-            if (world.setBlockIdNotify(blockPos, this.blockToPlace.id())) {
+            if (world.setBlockTypeNotify(blockPos, this.blockToPlace)) {
                 if (player == null) {
                     this.blockToPlace.onPlacedOnSide(world, blockPos, side, xHit, yHit);
                 } else {
@@ -60,7 +60,7 @@ public class ItemPlaceable extends Item {
     @Override
     public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) {
         blockPos = blockPos.add(direction, new TilePos());
-        Block<?> b = world.getBlock(blockPos);
+        Block<?> b = world.getBlockType(blockPos);
         if (b == null || BlockTags.PLACE_OVERWRITES.appliesTo(b)) {
             onUseOnBlock(selfStack, world, null, blockPos, direction.getSide(), 0.5, 0.5);
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemRope.java b/game/core/src/main/java/net/minecraft/core/item/ItemRope.java
index 083e383ca..bed21556f 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemRope.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemRope.java
@@ -23,7 +23,7 @@ public class ItemRope extends ItemPlaceable {
         }
         TilePos bp = new TilePos(blockPos);
         boolean placeOnSide = true;
-        if (world.getBlock(bp) == this.blockToPlace && player != null && !player.isSneaking()) {
+        if (world.getBlockType(bp) == this.blockToPlace && player != null && !player.isSneaking()) {
             placeOnSide = false;
             TilePos tempPos = new TilePos(bp);
             int _y = bp.y;
@@ -32,7 +32,7 @@ public class ItemRope extends ItemPlaceable {
                 if (world.canBlockIdBePlacedAt(this.blockToPlace.id(), tempPos.set(bp.x, _y, bp.z), false, side)) {
                     bp.y = _y;
                     break;
-                } else if (world.getBlock(tempPos.sub(bp.x, _y, bp.z, new TilePos())) != this.blockToPlace) {
+                } else if (world.getBlockType(tempPos.sub(bp.x, _y, bp.z, new TilePos())) != this.blockToPlace) {
                     if (side == Side.TOP) {
                         break;
                     }
@@ -48,7 +48,7 @@ public class ItemRope extends ItemPlaceable {
             return false;
         }
         if (world.canBlockIdBePlacedAt(this.blockToPlace.id(), bp, false, side) && selfStack.consumeItem(player)) {
-            if (world.setBlockIdDataNotify(bp, this.blockToPlace.id(), placeOnSide ? BlockLogicRope.MASK_ROPE_CONNECT : 0)) {
+            if (world.setBlockTypeDataNotify(bp, this.blockToPlace, placeOnSide ? BlockLogicRope.MASK_ROPE_CONNECT : 0)) {
                 if (player == null) {
                     this.blockToPlace.onPlacedOnSide(world, bp, side, xHit, yHit);
                 } else {
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java b/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java
index a9018839a..37e8518f8 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemSeeds.java
@@ -31,8 +31,8 @@ public class ItemSeeds extends Item {
         if (!world.canPlaceInsideBlock(blockPos)) {
             blockPos = blockPos.add(side.getDirection(), new TilePos());
         }
-        if (world.getBlockId(blockPos.down(new TilePos())) == Blocks.FARMLAND_DIRT.id() && world.canPlaceInsideBlock(blockPos)) {
-            if (world.setBlockIdNotify(blockPos, this.cropsBlock.id())) {
+        if (world.getBlockType(blockPos.down(new TilePos())) == Blocks.FARMLAND_DIRT && world.canPlaceInsideBlock(blockPos)) {
+            if (world.setBlockTypeNotify(blockPos, this.cropsBlock)) {
                 world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.cropsBlock, EnumBlockSoundEffectType.PLACE);
                 selfStack.consumeItem(player);
                 return true;
@@ -44,7 +44,7 @@ public class ItemSeeds extends Item {
     @Override
     public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) {
         blockPos = blockPos.add(direction, new TilePos());
-        Block<?> b = world.getBlock(blockPos);
+        Block<?> b = world.getBlockType(blockPos);
         boolean isFarmland = Block.hasLogicClass(b, BlockLogicFarmland.class);
         if (b == null || isFarmland || BlockTags.PLACE_OVERWRITES.appliesTo(b)) {
             onUseOnBlock(selfStack, world, null, blockPos.add(0, isFarmland ? 1 : 0, 0, new TilePos()), direction.getSide(), 0.5, 0.5);
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSign.java b/game/core/src/main/java/net/minecraft/core/item/ItemSign.java
index 4ccbb112d..36a62aa52 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemSign.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemSign.java
@@ -35,10 +35,10 @@ public class ItemSign extends Item {
 
         if (side == Side.TOP) {
             world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.SIGN_POST_PLANKS_OAK, EnumBlockSoundEffectType.PLACE);
-            world.setBlockIdDataNotify(blockPos, Blocks.SIGN_POST_PLANKS_OAK.id(), MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf);
+            world.setBlockTypeDataNotify(blockPos, Blocks.SIGN_POST_PLANKS_OAK, MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf);
         } else {
             world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.SIGN_WALL_PLANKS_OAK, EnumBlockSoundEffectType.PLACE);
-            world.setBlockIdDataNotify(blockPos, Blocks.SIGN_WALL_PLANKS_OAK.id(), side.getId());
+            world.setBlockTypeDataNotify(blockPos, Blocks.SIGN_WALL_PLANKS_OAK, side.getId());
         }
         selfStack.consumeItem(player);
         if (world.getTileEntity(blockPos) instanceof TileEntitySign sign) {
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java b/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java
index 8b5907dd1..a431013e7 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemSignPainted.java
@@ -35,10 +35,10 @@ public class ItemSignPainted extends ItemSign {
         if (side == Side.TOP) {
             int direction = MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf;
             world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.SIGN_POST_PLANKS_OAK_PAINTED, EnumBlockSoundEffectType.PLACE);
-            world.setBlockIdDataNotify(blockPos, Blocks.SIGN_POST_PLANKS_OAK_PAINTED.id(), Blocks.SIGN_POST_PLANKS_OAK_PAINTED.getLogic().toMetadata(DyeColor.colorFromItemMeta(selfStack.getMetadata())) | direction);
+            world.setBlockTypeDataNotify(blockPos, Blocks.SIGN_POST_PLANKS_OAK_PAINTED, Blocks.SIGN_POST_PLANKS_OAK_PAINTED.getLogic().toMetadata(DyeColor.colorFromItemMeta(selfStack.getMetadata())) | direction);
         } else {
             world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.SIGN_WALL_PLANKS_OAK_PAINTED, EnumBlockSoundEffectType.PLACE);
-            world.setBlockIdDataNotify(blockPos, Blocks.SIGN_WALL_PLANKS_OAK_PAINTED.id(), Blocks.SIGN_POST_PLANKS_OAK_PAINTED.getLogic().toMetadata(DyeColor.colorFromItemMeta(selfStack.getMetadata())) | side.getId());
+            world.setBlockTypeDataNotify(blockPos, Blocks.SIGN_WALL_PLANKS_OAK_PAINTED, Blocks.SIGN_POST_PLANKS_OAK_PAINTED.getLogic().toMetadata(DyeColor.colorFromItemMeta(selfStack.getMetadata())) | side.getId());
         }
         selfStack.consumeItem(player);
         if (world.getTileEntity(blockPos) instanceof TileEntitySign sign) {
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 3f421b05d..94adda0c5 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
@@ -13,6 +13,7 @@ import net.minecraft.core.player.inventory.container.Container;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.save.conversion.ChunkConverter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -119,9 +120,10 @@ public final class ItemStack {
 
     @Deprecated
     public boolean useItem(@NotNull Player player, @NotNull World world, int blockX, int blockY, int blockZ, @NotNull Side side, double xHit, double yHit) {
-        return useItemOnBlock(player, world, new TilePos(blockX, blockY, blockZ), side, xHit, yHit);
+        return this.useItemOnBlock(player, world, new TilePos(blockX, blockY, blockZ), side, xHit, yHit);
     }
-    public boolean useItemOnBlock(@NotNull Player player, @NotNull World world, @NotNull TilePos blockPos, @NotNull Side side, double xHit, double yHit) {
+
+    public boolean useItemOnBlock(@NotNull Player player, @NotNull World world, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
         if(getItem().onUseOnBlock(this, world, player, blockPos, side, xHit, yHit)) {
             player.addStat(getItem().getStat(StatList.STAT_USED), 1);
             return true;
@@ -135,7 +137,7 @@ public final class ItemStack {
 
     @Deprecated
     public @Nullable ItemStack useItemRightClick(@NotNull World world, @NotNull Player entityplayer) {
-        return getItem().onUseItem(this, world, entityplayer);
+        return this.useItem(world, entityplayer);
     }
 
     public @Nullable ItemStack useItem(@NotNull World world, @NotNull Player player) {
@@ -287,23 +289,19 @@ public final class ItemStack {
 
     @Deprecated
     public boolean beforeDestroyBlock(@NotNull World world, int id, int x, int y, int z, @NotNull Side side, @NotNull Player player) {
-    	return getItem().beforeDestroyBlock(world, this, id, x, y, z, side, player);
+    	return this.beforeBlockDestroyed(world, player, Objects.requireNonNull(Blocks.getBlock(id)), new TilePos(x, y, z), side);
     }
 
-    public boolean beforeBlockDestroyed(@NotNull World world, @NotNull Player player, @NotNull Block<?> block, @NotNull TilePos blockPos, @NotNull Side side) {
+    public boolean beforeBlockDestroyed(final @NotNull World world, final @NotNull Player player, final @NotNull Block<?> block, final @NotNull TilePosc blockPos, final @NotNull Side side) {
         return getItem().beforeBlockDestroyed(this, world, player, block, blockPos, side);
     }
 
     @Deprecated
     public void onDestroyBlock(@NotNull World world, int id, int x, int y, int z, @NotNull Side side, @NotNull Player entityplayer) {
-        boolean flag = getItem().onBlockDestroyed(world, this, id, x, y, z, side, entityplayer);
-        if(flag)
-        {
-            entityplayer.addStat(getItem().getStat(StatList.STAT_USED), 1);
-        }
+        this.onBlockDestroyed(world, entityplayer, Objects.requireNonNull(Blocks.getBlock(id)), new TilePos(x, y, z), side);
     }
 
-    public void onBlockDestroyed(final @NotNull World world, final @NotNull Player player, final @NotNull Block<?> removedBlock, final @NotNull TilePos blockPos, final @NotNull Side side) {
+    public void onBlockDestroyed(final @NotNull World world, final @NotNull Player player, final @NotNull Block<?> removedBlock, final @NotNull TilePosc blockPos, final @NotNull Side side) {
         if (getItem().onBlockDestroyed(this, world, player, removedBlock, blockPos, side)) {
             player.addStat(getItem().getStat(StatList.STAT_USED), 1);
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java b/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java
index 4e60566c0..accb5a936 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java
@@ -36,11 +36,11 @@ public class ItemStatue extends Item {
         }
 
         world.noNeighborUpdate = true;
-        world.setBlockIdDataNotify(blockPos, this.statueBlockBottom.id(), MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf);
-        world.setBlockIdDataNotify(blockPos.up(new TilePos()), this.statueBlockTop.id(), MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf);
+        world.setBlockTypeDataNotify(blockPos, this.statueBlockBottom, MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf);
+        world.setBlockTypeDataNotify(blockPos.up(new TilePos()), this.statueBlockTop, MathHelper.floor((double) (((player.yRot + 180F) * 16F) / 360F) + 0.5D) & 0xf);
         world.noNeighborUpdate = false;
-        world.notifyBlocksOfNeighborChange(blockPos, this.statueBlockBottom.id());
-        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.statueBlockTop.id());
+        world.notifyBlocksOfNeighborChange(blockPos, this.statueBlockBottom);
+        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.statueBlockTop);
         world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.statueBlockBottom, EnumBlockSoundEffectType.PLACE);
         this.statueBlockBottom.onPlacedByMob(world, blockPos, side, player, xHit, yHit);
         this.statueBlockTop.onPlacedByMob(world, blockPos.up(new TilePos()), side, player, xHit, yHit);
@@ -58,11 +58,11 @@ public class ItemStatue extends Item {
         }
 
         world.noNeighborUpdate = true;
-        world.setBlockIdNotify(blockPos, this.statueBlockBottom.id());
-        world.setBlockIdNotify(blockPos.up(new TilePos()), this.statueBlockTop.id());
+        world.setBlockTypeNotify(blockPos, this.statueBlockBottom);
+        world.setBlockTypeNotify(blockPos.up(new TilePos()), this.statueBlockTop);
         world.noNeighborUpdate = false;
-        world.notifyBlocksOfNeighborChange(blockPos, this.statueBlockBottom.id());
-        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.statueBlockTop.id());
+        world.notifyBlocksOfNeighborChange(blockPos, this.statueBlockBottom);
+        world.notifyBlocksOfNeighborChange(blockPos.up(new TilePos()), this.statueBlockTop);
         world.playBlockSoundEffect(null, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.statueBlockBottom, EnumBlockSoundEffectType.PLACE);
         this.statueBlockBottom.onPlacedOnSide(world, blockPos, direction.getSide(), 0.5, 0.5);
         this.statueBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.getSide(), 0.5, 0.5);
diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java
index 3f7f54fa6..18351c234 100644
--- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java
+++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlock.java
@@ -45,7 +45,7 @@ public class ItemBlock<T extends BlockLogic> extends Item {
         }
         if (world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side) && selfStack.consumeItem(player)) {
             int meta = getPlacedData(selfStack, world, player, blockPos, side, xHit, yHit);
-            if (world.setBlockIdDataNotify(blockPos, this.block.id(), meta)) {
+            if (world.setBlockTypeDataNotify(blockPos, this.block, meta)) {
                 if (player == null) {
                     this.block.onPlacedOnSide(world, blockPos, side, xHit, yHit);
                 } else {
@@ -69,7 +69,7 @@ public class ItemBlock<T extends BlockLogic> extends Item {
     @Override
     public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) {
         blockPos = blockPos.add(direction, new TilePos());
-        Block<?> b = world.getBlock(blockPos);
+        Block<?> b = world.getBlockType(blockPos);
         if (b == null || BlockTags.PLACE_OVERWRITES.appliesTo(b)) {
             onUseOnBlock(selfStack, world, null, blockPos, direction.getSide(), 0.5, 0.5);
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java
index 4fc96cded..8694aaf19 100644
--- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java
+++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockAlgae.java
@@ -41,16 +41,16 @@ public class ItemBlockAlgae<T extends BlockLogic> extends ItemBlock<T> {
         }
         if (rayCast instanceof HitResult.Tile hitTile) {
             TilePos blockPos = new TilePos(hitTile.tilePos);
-            if (world.getBlockId(blockPos) == Blocks.FLUID_WATER_STILL.id()) {
+            if (world.getBlockType(blockPos) == Blocks.FLUID_WATER_STILL) {
                 blockPos.y++;
             } else {
                 return selfStack;
             }
 
-            if (world.getBlockId(blockPos) != 0) {
+            if (world.getBlockType(blockPos) != Blocks.AIR) {
                 return selfStack;
             }
-            if (selfStack.consumeItem(player) && world.setBlockIdDataNotify(blockPos, this.block.id(), 0)) {
+            if (selfStack.consumeItem(player) && world.setBlockTypeNotify(blockPos, this.block)) {
                 this.block.onPlacedByMob(world, blockPos, Side.NONE, player, 0.5, 0.5);
                 world.playBlockSoundEffect(player, blockPos.x + 0.5F, blockPos.y + 0.5F, blockPos.z + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
                 player.swingItem();
@@ -63,10 +63,10 @@ public class ItemBlockAlgae<T extends BlockLogic> extends ItemBlock<T> {
     public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) {
         blockPos = blockPos.add(direction, new TilePos());
         TilePos up = blockPos.up(new TilePos());
-        Block<?> b = world.getBlock(blockPos);
-        Block<?> bAbove = world.getBlock(up);
+        Block<?> b = world.getBlockType(blockPos);
+        Block<?> bAbove = world.getBlockType(up);
         if (b == Blocks.FLUID_WATER_STILL && (bAbove == null || bAbove.hasTag(BlockTags.PLACE_OVERWRITES))) {
-            world.setBlockIdNotify(up, this.block.id());
+            world.setBlockTypeNotify(up, this.block);
             this.block.onPlacedOnSide(world, up, Side.NONE, 0.5, 0.5);
         }
     }
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 a93cc2f38..99ea24a7b 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
@@ -21,13 +21,13 @@ public class ItemBlockLadder<T extends BlockLogicLadder> extends ItemBlock<T> {
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
         TilePos bp = new TilePos(blockPos);
-        Block<?> clickedBlock = world.getBlock(bp);
+        Block<?> clickedBlock = world.getBlockType(bp);
 
         BlockLogicLadder ladder = this.block.getLogic();
 
         if (clickedBlock == this.block && player != null && !player.isSneaking()) {
             Side clickedLadderSide = ladder.getSideFromMeta(world.getBlockData(bp));
-            while (world.getBlock(bp) == this.block && ladder.getSideFromMeta(world.getBlockData(bp)) == clickedLadderSide)
+            while (world.getBlockType(bp) == this.block && ladder.getSideFromMeta(world.getBlockData(bp)) == clickedLadderSide)
                 bp.y--;
             int meta = ladder.getMetaForSide(clickedLadderSide);
             if (ladder.canExistAt(world, new TilePos(bp), meta)) {
@@ -55,15 +55,15 @@ public class ItemBlockLadder<T extends BlockLogicLadder> extends ItemBlock<T> {
     }
 
 
-    public boolean placeBlock(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TilePos blockPos, int meta, @Nullable Player player, @NotNull Side side, double xHit, double yHit) {
-        if (world.canPlaceInsideBlock(blockPos) && world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side) && selfStack.consumeItem(player)) {
-            if (world.setBlockIdDataNotify(blockPos, this.block.id(), meta)) {
+    public boolean placeBlock(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TilePos tilePos, int meta, @Nullable Player player, @NotNull Side side, double xHit, double yHit) {
+        if (world.canPlaceInsideBlock(tilePos) && world.canBlockIdBePlacedAt(this.block.id(), tilePos, false, side) && selfStack.consumeItem(player)) {
+            if (world.setBlockTypeDataNotify(tilePos, this.block, meta)) {
                 if (player == null) {
-                    this.block.onPlacedOnSide(world, blockPos, side, xHit, yHit);
+                    this.block.onPlacedOnSide(world, tilePos, side, xHit, yHit);
                 } else {
-                    this.block.onPlacedByMob(world, blockPos, side, player, xHit, yHit);
+                    this.block.onPlacedByMob(world, tilePos, side, player, xHit, yHit);
                 }
-                world.playBlockSoundEffect(player, blockPos.x + 0.5f, blockPos.y + 0.5f, blockPos.z + 0.5f, this.block, EnumBlockSoundEffectType.PLACE);
+                world.playBlockSoundEffect(player, tilePos.x + 0.5f, tilePos.y + 0.5f, tilePos.z + 0.5f, this.block, EnumBlockSoundEffectType.PLACE);
                 return true;
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java
index 1f4d42ba5..b5c06c363 100644
--- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java
+++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayer.java
@@ -22,14 +22,14 @@ public class ItemBlockLayer<T extends BlockLogicLayerBase> extends ItemBlock<T>
     }
 
     @Override
-    public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        Block<?> targetBlock = world.getBlock(blockPos);
-        int meta = world.getBlockData(blockPos);
+    public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
+        Block<?> targetBlock = world.getBlockType(tilePos);
+        int meta = world.getBlockData(tilePos);
         if (targetBlock != this.block && targetBlock != null && targetBlock.hasTag(BlockTags.PLACE_OVERWRITES)) {
             targetBlock = null;
             meta = 0;
         }
-        if (selfStack.stackSize <= 0 || blockPos.y() == world.getHeightBlocks() - 1 && this.block.getMaterial().isSolid()) {
+        if (selfStack.stackSize <= 0 || tilePos.y() == world.getHeightBlocks() - 1 && this.block.getMaterial().isSolid()) {
             return false;
         }
 
@@ -38,21 +38,21 @@ public class ItemBlockLayer<T extends BlockLogicLayerBase> extends ItemBlock<T>
             final BlockLogicLayerBase blockLayer = this.block.getLogic();
             final int newMeta = meta + 1;
 
-            final AABBdc bbBox = new AABBd(blockPos.x(), blockPos.y(), blockPos.z(), blockPos.x() + 1f, blockPos.y() + (2 * (newMeta + 1)) / 16.0f, blockPos.z() + 1f);
+            final AABBdc bbBox = new AABBd(tilePos.x(), tilePos.y(), tilePos.z(), tilePos.x() + 1f, tilePos.y() + (2 * (newMeta + 1)) / 16.0f, tilePos.z() + 1f);
             if (!world.checkIfAABBIsClear(bbBox)) {
                 return false;
             }
 
             if (newMeta < 7) {
-                world.setBlockIdDataNotify(blockPos, this.block.id(), newMeta);
+                world.setBlockTypeDataNotify(tilePos, this.block, newMeta);
             } else {
                 if (blockLayer.fullBlock != null) {
-                    world.setBlockIdDataNotify(blockPos, blockLayer.fullBlock.id(), 0);
+                    world.setBlockTypeNotify(tilePos, blockLayer.fullBlock);
                 } else {
-                    world.setBlockIdDataNotify(blockPos.up(new TilePos()), this.block.id(), 0);
+                    world.setBlockTypeNotify(tilePos.up(new TilePos()), this.block);
                 }
             }
-            world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
+            world.playBlockSoundEffect(player, tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
             selfStack.consumeItem(player);
             return true;
 
@@ -60,9 +60,9 @@ public class ItemBlockLayer<T extends BlockLogicLayerBase> extends ItemBlock<T>
 
         // Offset position
         if (targetBlock != null) {
-            blockPos = blockPos.add(side.getDirection(), new TilePos());
-            targetBlock = world.getBlock(blockPos);
-            meta = world.getBlockData(blockPos);
+            tilePos = tilePos.add(side.getDirection(), new TilePos());
+            targetBlock = world.getBlockType(tilePos);
+            meta = world.getBlockData(tilePos);
         }
 
         // Check if the block we're placing into is a layer
@@ -70,35 +70,35 @@ public class ItemBlockLayer<T extends BlockLogicLayerBase> extends ItemBlock<T>
             final BlockLogicLayerBase blockLayer = this.block.getLogic();
             final int newMeta = meta + 1;
 
-            final AABBdc bbBox = new AABBd(blockPos.x(), blockPos.y(), blockPos.z(), blockPos.x() + 1f, blockPos.y() + (2 * (newMeta + 1)) / 16.0f, blockPos.z() + 1f);
+            final AABBdc bbBox = new AABBd(tilePos.x(), tilePos.y(), tilePos.z(), tilePos.x() + 1f, tilePos.y() + (2 * (newMeta + 1)) / 16.0f, tilePos.z() + 1f);
             if (!world.checkIfAABBIsClear(bbBox)) {
                 return false;
             }
 
             if (newMeta < 7) {
-                world.setBlockIdDataNotify(blockPos, this.block.id(), newMeta);
+                world.setBlockTypeDataNotify(tilePos, this.block, newMeta);
             } else {
                 if (blockLayer.fullBlock != null) {
-                    world.setBlockIdDataNotify(blockPos, blockLayer.fullBlock.id(), 0);
+                    world.setBlockTypeNotify(tilePos, blockLayer.fullBlock);
                 } else {
-                    world.setBlockIdDataNotify(blockPos.up(new TilePos()), this.block.id(), 0);
+                    world.setBlockTypeNotify(tilePos.up(new TilePos()), this.block);
                 }
             }
-            world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
+            world.playBlockSoundEffect(player, tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
             selfStack.consumeItem(player);
             return true;
         }
 
         // Regular placement, as all else fails
-        if (world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side)) {
-            int placeMeta = getPlacedData(selfStack, world, player, blockPos, side, xHit, yHit);
-            if (world.setBlockIdDataNotify(blockPos, this.block.id(), placeMeta)) {
+        if (world.canBlockIdBePlacedAt(this.block.id(), tilePos, false, side)) {
+            int placeMeta = getPlacedData(selfStack, world, player, tilePos, side, xHit, yHit);
+            if (world.setBlockTypeDataNotify(tilePos, this.block, placeMeta)) {
                 if (player == null) {
-                    this.block.onPlacedOnSide(world, blockPos, side, xHit, yHit);
+                    this.block.onPlacedOnSide(world, tilePos, side, xHit, yHit);
                 } else {
-                    this.block.onPlacedByMob(world, blockPos, Side.NONE, player, xHit, yHit);
+                    this.block.onPlacedByMob(world, tilePos, Side.NONE, player, xHit, yHit);
                 }
-                world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
+                world.playBlockSoundEffect(player, tilePos.x() + 0.5F, tilePos.y() + 0.5F, tilePos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
                 selfStack.consumeItem(player);
                 return true;
             }
diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java
index 6398d1648..7761fa869 100644
--- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java
+++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockLayerLeaves.java
@@ -24,7 +24,7 @@ public class ItemBlockLayerLeaves<T extends BlockLogicLayerLeaves> extends ItemB
 
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        Block<?> targetBlock = world.getBlock(blockPos);
+        Block<?> targetBlock = world.getBlockType(blockPos);
         int meta = world.getBlockData(blockPos);
         if (targetBlock != this.block && targetBlock != null && targetBlock.hasTag(BlockTags.PLACE_OVERWRITES)) {
             targetBlock = null;
@@ -45,12 +45,12 @@ public class ItemBlockLayerLeaves<T extends BlockLogicLayerLeaves> extends ItemB
             }
 
             if ((newMeta & 0b00001111) < 7) {
-                world.setBlockIdDataNotify(blockPos, this.block.id(), BlockLogicLayerLeaves.setPermanent(newMeta, true));
+                world.setBlockTypeDataNotify(blockPos, this.block, BlockLogicLayerLeaves.setPermanent(newMeta, true));
             } else {
                 if (blockLayer.fullBlock != null) {
-                    world.setBlockIdDataNotify(blockPos, blockLayer.fullBlock.id(), BlockLogicLeavesBase.setPermanent(0, true));
+                    world.setBlockTypeDataNotify(blockPos, blockLayer.fullBlock, BlockLogicLeavesBase.setPermanent(0, true));
                 } else {
-                    world.setBlockIdDataNotify(blockPos.up(new TilePos()), this.block.id(), BlockLogicLayerLeaves.setPermanent(0, true));
+                    world.setBlockTypeDataNotify(blockPos.up(new TilePos()), this.block, BlockLogicLayerLeaves.setPermanent(0, true));
                 }
             }
             world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
@@ -61,7 +61,7 @@ public class ItemBlockLayerLeaves<T extends BlockLogicLayerLeaves> extends ItemB
         // Offset position
         if (targetBlock != null) {
             blockPos = blockPos.add(side.getDirection(), new TilePos());
-            targetBlock = world.getBlock(blockPos);
+            targetBlock = world.getBlockType(blockPos);
             meta = world.getBlockData(blockPos);
         }
 
@@ -76,12 +76,12 @@ public class ItemBlockLayerLeaves<T extends BlockLogicLayerLeaves> extends ItemB
             }
 
             if ((newMeta & 0b00001111) < 7) {
-                world.setBlockIdDataNotify(blockPos, this.block.id(), BlockLogicLayerLeaves.setPermanent(newMeta, true));
+                world.setBlockTypeDataNotify(blockPos, this.block, BlockLogicLayerLeaves.setPermanent(newMeta, true));
             } else {
                 if (blockLayer.fullBlock != null) {
-                    world.setBlockIdDataNotify(blockPos, blockLayer.fullBlock.id(), BlockLogicLeavesBase.setPermanent(0, true));
+                    world.setBlockTypeDataNotify(blockPos, blockLayer.fullBlock, BlockLogicLeavesBase.setPermanent(0, true));
                 } else {
-                    world.setBlockIdDataNotify(blockPos.up(new TilePos()), this.block.id(), BlockLogicLayerLeaves.setPermanent(0, true));
+                    world.setBlockTypeDataNotify(blockPos.up(new TilePos()), this.block, BlockLogicLayerLeaves.setPermanent(0, true));
                 }
             }
             world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
@@ -92,7 +92,7 @@ public class ItemBlockLayerLeaves<T extends BlockLogicLayerLeaves> extends ItemB
         // Regular placement, as all else fails
         if (world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side)) {
             int placeMeta = getPlacedData(selfStack, world, player, blockPos, side, xHit, yHit);
-            if (world.setBlockIdDataNotify(blockPos, this.block.id(), placeMeta)) {
+            if (world.setBlockTypeDataNotify(blockPos, this.block, placeMeta)) {
                 if (player == null) {
                     this.block.onPlacedOnSide(world, blockPos, side, xHit, yHit);
                 } else {
diff --git a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java
index 31bce15cd..009657755 100644
--- a/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java
+++ b/game/core/src/main/java/net/minecraft/core/item/block/ItemBlockSlab.java
@@ -23,11 +23,11 @@ public class ItemBlockSlab<T extends BlockLogic> extends ItemBlock<T> {
 
     @Override
     public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        int id = world.getBlockId(blockPos);
+        @NotNull Block<?> block = world.getBlockType(blockPos);
         int meta = world.getBlockData(blockPos) & 0b11;
         int otherMeta = world.getBlockData(blockPos) & ~0b11;
-        if (Blocks.blocksList[world.getBlockId(blockPos)] != null && Blocks.blocksList[world.getBlockId(blockPos)].hasTag(BlockTags.PLACE_OVERWRITES)) {
-            id = 0;
+        if (world.getBlockType(blockPos).hasTag(BlockTags.PLACE_OVERWRITES)) {
+            block = Blocks.AIR;
             meta = 0;
         }
         if (selfStack.stackSize <= 0 || blockPos.y() == world.getHeightBlocks() - 1 && this.block.getMaterial().isSolid()) {
@@ -35,7 +35,7 @@ public class ItemBlockSlab<T extends BlockLogic> extends ItemBlock<T> {
         }
 
         // Check if we're placing "inside" a slab
-        if (id == this.block.id() && otherMeta == selfStack.getMetadata() && (side == Side.TOP || side == Side.BOTTOM)) {
+        if (block == this.block && otherMeta == selfStack.getMetadata() && (side == Side.TOP || side == Side.BOTTOM)) {
             if ((side == Side.TOP && meta == 0) || (side == Side.BOTTOM && meta == 2)) {
                 AABBdc bbBox = new AABBd(blockPos.x(), blockPos.y(), blockPos.z(), blockPos.x() + 1f, blockPos.y() + 1f, blockPos.z() + 1f);
                 if (!world.checkIfAABBIsClear(bbBox)) {
@@ -50,15 +50,15 @@ public class ItemBlockSlab<T extends BlockLogic> extends ItemBlock<T> {
         }
 
         // Offset position
-        if (id != 0) {
+        if (block != Blocks.AIR) {
             blockPos = blockPos.add(side.getDirection(), new TilePos());
-            id = world.getBlockId(blockPos);
+            block = world.getBlockType(blockPos);
             meta = world.getBlockData(blockPos) & 0b11;
             otherMeta = world.getBlockData(blockPos) & ~0b11;
         }
 
         // Check if the block we're placing into is a slab
-        if (id == this.block.id() && otherMeta == selfStack.getMetadata()) {
+        if (block == this.block && otherMeta == selfStack.getMetadata()) {
             if ((yHit > 0.5f && meta == 0) || (yHit <= 0.5f && meta == 2) || (side == Side.BOTTOM && meta == 0) || (side == Side.TOP && meta == 2)) {
                 AABBdc bbBox = new AABBd(blockPos.x(), blockPos.y(), blockPos.z(), blockPos.x() + 1f, blockPos.y() + 1f, blockPos.z() + 1f);
                 if (!world.checkIfAABBIsClear(bbBox)) {
@@ -75,7 +75,7 @@ public class ItemBlockSlab<T extends BlockLogic> extends ItemBlock<T> {
         // Regular placement, as all else fails
         if (world.canBlockIdBePlacedAt(this.block.id(), blockPos, false, side)) {
             int placeMeta = getPlacedData(selfStack, world, player, blockPos, side, xHit, yHit);
-            if (world.setBlockIdDataNotify(blockPos, this.block.id(), placeMeta)) {
+            if (world.setBlockTypeDataNotify(blockPos, this.block, placeMeta)) {
                 if (player == null) {
                     this.block.onPlacedOnSide(world, blockPos, side, xHit, yHit);
                 } else {
diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemTool.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemTool.java
index f6e0810b9..b2fac0e0c 100644
--- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemTool.java
+++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemTool.java
@@ -10,7 +10,7 @@ import net.minecraft.core.item.material.ToolMaterial;
 import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 
 public class ItemTool extends Item {
@@ -45,7 +45,7 @@ public class ItemTool extends Item {
 	}
 
 	@Override
-	public boolean onBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Mob mob, @NotNull Block<?> removedBlock, @NotNull TilePos blockPos, @NotNull Side side) {
+	public boolean onBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Mob mob, @NotNull Block<?> removedBlock, @NotNull TilePosc blockPos, @NotNull Side side) {
         if (removedBlock.getHardness() > 0.0f || isSilkTouch()) {
             selfStack.damageItem(1, mob);
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolAxe.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolAxe.java
index 759592bab..5b9f4d115 100644
--- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolAxe.java
+++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolAxe.java
@@ -2,7 +2,6 @@ package net.minecraft.core.item.tool;
 
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicLog;
-import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.data.gamerule.GameRules;
 import net.minecraft.core.data.gamerule.TreecapitatorHelper;
@@ -12,7 +11,7 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.material.ToolMaterial;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 
 public class ItemToolAxe extends ItemTool {
@@ -27,11 +26,11 @@ public class ItemToolAxe extends ItemTool {
     }
 
     @Override
-    public boolean beforeBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Player player, @NotNull Block<?> block, @NotNull TilePos blockPos, @NotNull Side side) {
+    public boolean beforeBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Player player, @NotNull Block<?> block, @NotNull TilePosc blockPos, @NotNull Side side) {
         if(!world.isClientSide && world.getGameRuleValue(GameRules.TREECAPITATOR) && !player.isSneaking()) {
-            int id = world.getBlockId(blockPos);
-            if(Block.hasLogicClass(Blocks.getBlock(id), BlockLogicLog.class)) {
-                return !new TreecapitatorHelper(world, blockPos.x, blockPos.y, blockPos.z, player).chopTree();
+            final @NotNull Block<?> blockType = world.getBlockType(blockPos);
+            if(Block.hasLogicClass(blockType, BlockLogicLog.class)) {
+                return !new TreecapitatorHelper(world, blockPos.x(), blockPos.y(), blockPos.z(), player).chopTree();
             }
         }
         return true;
diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java
index e6d2444eb..7034c6fa5 100644
--- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java
+++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolHoe.java
@@ -43,23 +43,23 @@ public class ItemToolHoe extends ItemTool {
     }
 
     public boolean till(@NotNull ItemStack selfStack, @Nullable Player player, @NotNull World world, @NotNull TilePosc blockPos, @NotNull Side side) {
-        int id = world.getBlockId(blockPos);
-        int idAbove = world.getBlockId(blockPos.up(new TilePos()));
-        if (side != Side.BOTTOM && idAbove == 0 && (id == Blocks.GRASS.id() || id == Blocks.DIRT.id() || id == Blocks.PATH_DIRT.id() || id == Blocks.GRASS_RETRO.id() || id == Blocks.MUD.id())) {
+        final @NotNull Block<?> block = world.getBlockType(blockPos);
+        final @NotNull Block<?> blockAbove = world.getBlockType(blockPos.up(new TilePos()));
+        if (side != Side.BOTTOM && blockAbove == Blocks.AIR && (block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.PATH_DIRT || block == Blocks.GRASS_RETRO || block == Blocks.MUD)) {
             int meta = 0;
-            if (id == Blocks.MUD.id()) {
+            if (block == Blocks.MUD) {
                 meta = 1;
             }
             world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.DIRT, EnumBlockSoundEffectType.MINE);
             if (!world.isClientSide) {
-                if (id == Blocks.GRASS.id() || id == Blocks.GRASS_RETRO.id() || id == Blocks.GRASS_SCORCHED.id()) {
+                if (block == Blocks.GRASS || block == Blocks.GRASS_RETRO || block == Blocks.GRASS_SCORCHED) {
                     if (world.rand.nextInt(5) == 0) {
                         world.dropItem(blockPos.up(new TilePos()), new ItemStack(Items.SEEDS_WHEAT));
                     }
                 }
             }
             if (!world.isClientSide) {
-                world.setBlockIdDataNotify(blockPos, Blocks.FARMLAND_DIRT.id(), meta);
+                world.setBlockTypeDataNotify(blockPos, Blocks.FARMLAND_DIRT, meta);
                 selfStack.damageItem(1, player);
             }
             return true;
@@ -68,7 +68,7 @@ public class ItemToolHoe extends ItemTool {
     }
 
     @Override
-    public boolean onBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Mob mob, @NotNull Block<?> removedBlock, @NotNull TilePos blockPos, @NotNull Side side) {
+    public boolean onBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Mob mob, @NotNull Block<?> removedBlock, @NotNull TilePosc blockPos, @NotNull Side side) {
         if (!world.isClientSide) {
             if (removedBlock == Blocks.TALLGRASS || removedBlock == Blocks.TALLGRASS_FERN) {
                 if (this.material.isSilkTouch()) {
diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java
index 584313013..895b76bff 100644
--- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java
+++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolShovel.java
@@ -40,12 +40,12 @@ public class ItemToolShovel extends ItemTool {
     }
 
     public boolean shovelBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player entityplayer, @NotNull TilePosc blockPos, @NotNull Side side) {
-        int blockId = world.getBlockId(blockPos);
-        int blockAbove = world.getBlockId(blockPos.up(new TilePos()));
-        if (side != Side.BOTTOM && blockAbove == 0 && (blockId == Blocks.GRASS.id() || blockId == Blocks.DIRT.id() || blockId == Blocks.GRASS_RETRO.id() || blockId == Blocks.FARMLAND_DIRT.id())) {
-            world.playBlockSoundEffect(entityplayer, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.blocksList[blockId], EnumBlockSoundEffectType.PLACE);
+        final @NotNull Block<?> block = world.getBlockType(blockPos);
+        final @NotNull Block<?> blockAbove = world.getBlockType(blockPos.up(new TilePos()));
+        if (side != Side.BOTTOM && blockAbove == Blocks.AIR && (block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.GRASS_RETRO || block == Blocks.FARMLAND_DIRT)) {
+            world.playBlockSoundEffect(entityplayer, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, block, EnumBlockSoundEffectType.PLACE);
             if (!world.isClientSide) {
-                world.setBlockIdNotify(blockPos, Blocks.PATH_DIRT.id());
+                world.setBlockTypeNotify(blockPos, Blocks.PATH_DIRT);
                 selfStack.damageItem(1, entityplayer);
             }
             return true;
diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java
index b4c75d12c..3d99468b8 100644
--- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java
+++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolSword.java
@@ -43,7 +43,7 @@ public class ItemToolSword extends Item
     }
 
     @Override
-    public boolean onBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Mob mob, @NotNull Block<?> removedBlock, @NotNull TilePos blockPos, @NotNull Side side) {
+    public boolean onBlockDestroyed(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Mob mob, @NotNull Block<?> removedBlock, @NotNull TilePosc blockPos, @NotNull Side side) {
         if (removedBlock.getHardness() > 0.0f || isSilkTouch()) {
             selfStack.damageItem(2, mob);
         }
@@ -53,9 +53,9 @@ public class ItemToolSword extends Item
     @Override
     public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) {
         blockPos = blockPos.add(direction, new TilePos());
-        Block<?> b = world.getBlock(blockPos);
+        Block<?> b = world.getBlockType(blockPos);
         if (b == Blocks.PUMPKIN) {
-            world.setBlockIdData(blockPos, Blocks.PUMPKIN_CARVED_IDLE.id(), direction.getOpposite().getId());
+            world.setBlockTypeData(blockPos, Blocks.PUMPKIN_CARVED_IDLE, direction.getOpposite().getId());
             selfStack.damageItem(1, null);
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java b/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java
index 308637c87..016ec2376 100644
--- a/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java
+++ b/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java
@@ -10,15 +10,15 @@ public abstract class PacketHandler {
 
     public abstract boolean isServerHandler();
 
-    public void handleBlockRegionUpdate(@NotNull PacketBlockRegionUpdate packetBlockRegionUpdate) {
-    }
-
     public void handleInvalidPacket(@NotNull Packet packet) {
     }
 
     public void handleErrorMessage(String message, Object[] objects) {
     }
 
+    public void handleBlockRegionUpdate(@NotNull PacketBlockRegionUpdate packetBlockRegionUpdate) {
+    }
+
     public void handleDisconnect(@NotNull PacketDisconnect packetDisconnect) {
         handleInvalidPacket(packetDisconnect);
     }
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java
index f13abb824..21c0c9a58 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketUseOrPlaceItemStack.java
@@ -7,6 +7,7 @@ import java.io.IOException;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.net.handler.PacketHandler;
 import net.minecraft.core.util.helper.Direction;
+import org.jetbrains.annotations.Nullable;
 
 public class PacketUseOrPlaceItemStack extends Packet
 {
@@ -60,7 +61,7 @@ public class PacketUseOrPlaceItemStack extends Packet
     {
     }
 
-    public PacketUseOrPlaceItemStack(int x, int y, int z, Direction direction, ItemStack itemstack, double xPlaced, double yPlaced, byte type)
+    public PacketUseOrPlaceItemStack(int x, int y, int z, Direction direction, @Nullable ItemStack itemstack, double xPlaced, double yPlaced, byte type)
     {
         xPosition = x;
         yPosition = y;
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerInventory.java b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerInventory.java
index a4c6ddfc1..ba98d5c82 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerInventory.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerInventory.java
@@ -85,26 +85,28 @@ public class ContainerInventory
         }
     }
 
-    public int setCurrentItem(final @NotNull ItemStack stack) {
+    public int setCurrentItem(final @Nullable ItemStack stack) {
         if (this.currentSlotLocked()) {
             return this.currentSlot;
         }
 
-        if (stack.itemID < Blocks.blocksList.length) {
-            if (Objects.requireNonNull(Blocks.blocksList[stack.itemID]).hasTag(BlockTags.NOT_IN_CREATIVE_MENU)) {
-                return this.currentSlot;
-            }
-        } else {
-            if (Objects.requireNonNull(Item.itemsList[stack.itemID]).hasTag(ItemTags.NOT_IN_CREATIVE_MENU)) {
-                return this.currentSlot;
+        if (stack != null) {
+            if (stack.itemID < Blocks.blocksList.length) {
+                if (Objects.requireNonNull(Blocks.blocksList[stack.itemID]).hasTag(BlockTags.NOT_IN_CREATIVE_MENU)) {
+                    return this.currentSlot;
+                }
+            } else {
+                if (Objects.requireNonNull(Item.itemsList[stack.itemID]).hasTag(ItemTags.NOT_IN_CREATIVE_MENU)) {
+                    return this.currentSlot;
+                }
             }
-        }
 
-        for (int i = this.hotbarOffset; i < this.hotbarOffset + HOTBAR_SIZE; i++) {
-            final @Nullable ItemStack hotbarStack = this.mainInventory[i];
-            if (hotbarStack != null && hotbarStack.itemID == stack.itemID) {
-                this.currentSlot = i;
-                return this.currentSlot;
+            for (int i = this.hotbarOffset; i < this.hotbarOffset + HOTBAR_SIZE; i++) {
+                final @Nullable ItemStack hotbarStack = this.mainInventory[i];
+                if (hotbarStack != null && hotbarStack.itemID == stack.itemID) {
+                    this.currentSlot = i;
+                    return this.currentSlot;
+                }
             }
         }
 
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
index 001586e41..041b7f075 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
@@ -126,7 +126,7 @@ public abstract class MenuAbstract
 	 * The returned ItemStack is used to check if the client has the same items as the server.
 	 * If they are different, the server sends the inventory again.
 	 */
-	public ItemStack clicked(InventoryAction action, int[] args, Player player) {
+	public @Nullable ItemStack clicked(final @NotNull InventoryAction action, final int @Nullable [] args, final @NotNull Player player) {
 		if(action.requireCreative()) {
 			if(player.getGamemode().hasBlockConsumption()) {
                 LOGGER.warn("Player {} used a creative inventory action but is not in creative mode!", player.username);
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java
index ebfbbca85..4495cfc63 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java
@@ -72,7 +72,7 @@ public class MenuActivator extends MenuAbstract {
 	}
 
 	@Override
-	public ItemStack clicked(InventoryAction action, int[] args, Player player) {
+	public ItemStack clicked(@NotNull InventoryAction action, int @NotNull [] args, @NotNull Player player) {
 		if (action == InventoryAction.LOCK) {
 			activator.lockSlot(args[0], !activator.locked(args[0]));
 			return null;
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java
index 6547d228e..dc27d2b6b 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java
@@ -75,7 +75,7 @@ public class MenuCrafting extends MenuAbstract {
 
     @Override
     public boolean stillValid(@NotNull Player player) {
-        if (this.world.getBlockId(this.tilePos) != Blocks.WORKBENCH.id()) {
+        if (this.world.getBlockType(this.tilePos) != Blocks.WORKBENCH) {
             return false;
         }
         return player.distanceToSqr((double) this.tilePos.x + 0.5D, (double) this.tilePos.y + 0.5D, (double) this.tilePos.z + 0.5D) <= 64D;
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java
index 46295eaee..51d6a512b 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java
@@ -17,7 +17,7 @@ public class MenuGuidebook extends MenuAbstract
 	}
 
 	@Override
-	public ItemStack clicked(InventoryAction action, int[] args, Player player) {
+	public ItemStack clicked(@NotNull InventoryAction action, int @NotNull [] args, @NotNull Player player) {
 		return null;
 	}
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/BlocksContainer.java b/game/core/src/main/java/net/minecraft/core/world/BlocksContainer.java
index 03670e0ce..ce265fc71 100644
--- a/game/core/src/main/java/net/minecraft/core/world/BlocksContainer.java
+++ b/game/core/src/main/java/net/minecraft/core/world/BlocksContainer.java
@@ -4,7 +4,6 @@ import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.material.Material;
-import net.minecraft.core.block.material.Materials;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.world.biome.Biome;
@@ -17,6 +16,7 @@ import org.jetbrains.annotations.Nullable;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 
 public class BlocksContainer implements MutableWorldSource {
     public final @NotNull World world;
@@ -38,8 +38,8 @@ public class BlocksContainer implements MutableWorldSource {
     }
 
     @Override
-    public boolean setBlockId(final @NotNull TilePosc tilePos, final int id) {
-        this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(id, 0, null));
+    public boolean setBlockType(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(block, 0, null));
         return true;
     }
 
@@ -47,7 +47,7 @@ public class BlocksContainer implements MutableWorldSource {
     public void setBlock(final int x, final int y, final int z, final int id, final int data, final @Nullable TileEntity tileEntity) {
         final @NotNull TilePos tilePos = new TilePos(x, y, z);
 
-        this.setBlockIdData(tilePos, id, data);
+        this.setBlockTypeData(tilePos, Objects.requireNonNull(Blocks.getBlock(id)), data);
         if (tileEntity != null) {
             this.setTileEntity(tilePos, tileEntity);
         }
@@ -59,15 +59,15 @@ public class BlocksContainer implements MutableWorldSource {
         if (entry != null) {
             entry.data = data;
         } else {
-            this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(this.world.getBlockId(tilePos), data, this.world.getTileEntity(tilePos)));
+            this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(this.world.getBlockType(tilePos), data, this.world.getTileEntity(tilePos)));
         }
 
         return true;
     }
 
     @Override
-    public boolean setBlockIdData(final @NotNull TilePosc tilePos, final int id, final int data) {
-        this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(id, data, null));
+    public boolean setBlockTypeData(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final int data) {
+        this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(block, data, null));
         return true;
     }
 
@@ -82,7 +82,7 @@ public class BlocksContainer implements MutableWorldSource {
         if (entry != null) {
             entry.tileEntity = tileEntity;
         } else {
-            this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(this.world.getBlockId(tilePos), this.world.getBlockData(tilePos), tileEntity));
+            this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(this.world.getBlockType(tilePos), this.world.getBlockData(tilePos), tileEntity));
         }
     }
 
@@ -92,7 +92,7 @@ public class BlocksContainer implements MutableWorldSource {
         if (entry != null) {
             entry.tileEntity = null;
         } else {
-            this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(this.world.getBlockId(tilePos), this.world.getBlockData(tilePos), null));
+            this.blockEntryMap.put(new TilePos(tilePos), new BlockEntry(this.world.getBlockType(tilePos), this.world.getBlockData(tilePos), null));
         }
     }
 
@@ -114,18 +114,13 @@ public class BlocksContainer implements MutableWorldSource {
     }
 
     @Override
-    public int getBlockId(final @NotNull TilePosc tilePos) {
+    public @NotNull Block<?> getBlockType(final @NotNull TilePosc tilePos) {
         final @Nullable BlockEntry entry = this.getEntry(tilePos);
         if (entry != null) {
-            return entry.id;
+            return entry.block;
         }
 
-        return 0;
-    }
-
-    @Override
-    public @Nullable Block<?> getBlock(final @NotNull TilePosc tilePos) {
-        return Blocks.getBlock(this.getBlockId(tilePos));
+        return Blocks.AIR;
     }
 
     @Override
@@ -178,24 +173,19 @@ public class BlocksContainer implements MutableWorldSource {
 
     @Override
     public @NotNull Material getBlockMaterial(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        if (block == null) {
-            return Materials.AIR;
-        } else {
-            return block.getMaterial();
-        }
+        final @NotNull Block<?> block = Objects.requireNonNull(this.getBlockType(tilePos));
+        return block.getMaterial();
     }
 
     @Override
     public boolean isBlockOpaqueCube(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        return block != null && block.isSolidRender();
+        return this.getBlockType(tilePos).isSolidRender();
     }
 
     @Override
     public boolean isBlockNormalCube(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        return block != null && block.getMaterial().isSolidBlocking() && block.renderAsNormalBlockOnCondition(this, tilePos);
+        final @Nullable Block<?> block = this.getBlockType(tilePos);
+        return block.getMaterial().isSolidBlocking() && block.renderAsNormalBlockOnCondition(this, tilePos);
     }
 
     @Override
@@ -234,12 +224,12 @@ public class BlocksContainer implements MutableWorldSource {
     }
 
     public static class BlockEntry {
-        public int id;
+        public @NotNull Block<?> block;
         public int data;
         public @Nullable TileEntity tileEntity;
 
-        public BlockEntry(final int id, final int data, final @Nullable TileEntity tileEntity) {
-            this.id = id;
+        public BlockEntry(final @NotNull Block<?> block, final int data, final @Nullable TileEntity tileEntity) {
+            this.block = block;
             this.data = data;
             this.tileEntity = tileEntity;
         }
diff --git a/game/core/src/main/java/net/minecraft/core/world/Explosion.java b/game/core/src/main/java/net/minecraft/core/world/Explosion.java
index 6677a4c1c..6a2ab01c4 100644
--- a/game/core/src/main/java/net/minecraft/core/world/Explosion.java
+++ b/game/core/src/main/java/net/minecraft/core/world/Explosion.java
@@ -189,7 +189,7 @@ public class Explosion {
             int y1 = chunkposition.y;
             int z1 = chunkposition.z;
 
-            if (this.world.getBlockId(x1, y1, z1) == 0 && Blocks.solid[this.world.getBlockId(x1, y1 - 1, z1)] && this.ExplosionRNG.nextInt(3) == 0) {
+            if (this.world.getBlockId(x1, y1, z1) == Blocks.AIR.id() && Blocks.solid[this.world.getBlockId(x1, y1 - 1, z1)] && this.ExplosionRNG.nextInt(3) == 0) {
                 this.world.setBlockWithNotify(x1, y1, z1, Blocks.FIRE.id());
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java b/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java
index 305cbeb04..7484e458e 100644
--- a/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java
+++ b/game/core/src/main/java/net/minecraft/core/world/ExplosionCannonball.java
@@ -114,7 +114,7 @@ public class ExplosionCannonball extends Explosion {
                 int k3 = chunkposition.z;
                 int l3 = this.world.getBlockId(i3, j3, k3);
                 int i4 = this.world.getBlockId(i3, j3 - 1, k3);
-                if (l3 == 0 && Blocks.solid[i4] && this.ExplosionRNG.nextInt(3) == 0) {
+                if (l3 == Blocks.AIR.id() && Blocks.solid[i4] && this.ExplosionRNG.nextInt(3) == 0) {
                     this.world.setBlockWithNotify(i3, j3, k3, Blocks.FIRE.id());
                 }
             }
diff --git a/game/core/src/main/java/net/minecraft/core/world/MutableWorldSource.java b/game/core/src/main/java/net/minecraft/core/world/MutableWorldSource.java
index f6a4a168a..6d65e1c58 100644
--- a/game/core/src/main/java/net/minecraft/core/world/MutableWorldSource.java
+++ b/game/core/src/main/java/net/minecraft/core/world/MutableWorldSource.java
@@ -1,19 +1,23 @@
 package net.minecraft.core.world;
 
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.Objects;
+
 public interface MutableWorldSource
     extends WorldSource {
 
-    boolean setBlockId(final @NotNull TilePosc tilePos, final int id);
+    boolean setBlockType(final @NotNull TilePosc tilePos, final @NotNull Block<?> block);
 
     @Deprecated
     default boolean setBlock(final int x, final int y, final int z, final int id) {
-        return this.setBlockId(new TilePos(x, y, z), id);
+        return this.setBlockType(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)));
     }
 
     boolean setBlockData(final @NotNull TilePosc tilePos, final int data);
@@ -23,11 +27,11 @@ public interface MutableWorldSource
         return this.setBlockData(new TilePos(x, y, z), data);
     }
 
-    boolean setBlockIdData(final @NotNull TilePosc tilePos, final int id, final int data);
+    boolean setBlockTypeData(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final int data);
 
     @Deprecated
     default boolean setBlockAndMetadata(final int x, final int y, final int z, final int id, final int data) {
-        return this.setBlockIdData(new TilePos(x, y, z), id, data);
+        return this.setBlockTypeData(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)), data);
     }
 
     void setLightValue(final @NotNull LightLayer lightLayer, final @NotNull TilePosc tilePos, final int value);
diff --git a/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java b/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java
index 7bf468882..3b0e2289d 100644
--- a/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java
+++ b/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java
@@ -361,7 +361,7 @@ public final class SpawnerMobs {
                                     world.entityJoinedWorld(entity);
                                     player.wakeUpPlayer(true, false);
                                     final @NotNull TilePos playerDown = new TilePos(player).down();
-                                    world.playBlockEvent(null, playerDown, LevelListener.EVENT_BLOCK_BREAK, world.getBlockId(playerDown));
+                                    world.playBlockEvent(null, playerDown, LevelListener.EVENT_BLOCK_BREAK, world.getBlockType(playerDown).id());
                                     entity.playLivingSound();
                                     spawnedEntity = true;
                                     spawnedEntityForPlayer = true;
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 20b7e44e6..dc966a962 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
@@ -11,7 +11,6 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.material.Materials;
 import net.minecraft.core.block.support.ISupport;
-import net.minecraft.core.block.support.PartialSupport;
 import net.minecraft.core.current.wire.WireHandler;
 import net.minecraft.core.entity.EntityItem;
 import net.minecraft.core.entity.animal.MobFireflyCluster;
@@ -392,19 +391,14 @@ public class World implements MutableWorldSource {
     }
 
     @Override
-    public int getBlockId(final @NotNull TilePosc tilePos) {
+    public @NotNull Block<?> getBlockType(final @NotNull TilePosc tilePos) {
         if (!tilePos.inBounds(this)) {
-            return 0;
+            return Blocks.AIR;
         } else {
-            return this.getChunk(tilePos).getBlockId(new ChunkTilePos(tilePos));
+            return this.getChunk(tilePos).getBlock(new ChunkTilePos(tilePos));
         }
     }
 
-    @Override
-    public @Nullable Block<?> getBlock(final @NotNull TilePosc tilePos) {
-        return Blocks.getBlock(this.getBlockId(tilePos));
-    }
-
     @Override
     public double getBlockTemperature(final @NotNull TilePosc tilePos) {
         if (tilePos.x() < MIN_BLOCK_X || tilePos.z() < MIN_BLOCK_Z || tilePos.x() > MAX_BLOCK_X || tilePos.z() > MAX_BLOCK_Z) {
@@ -530,7 +524,7 @@ public class World implements MutableWorldSource {
     }
 
     public boolean isAirBlock(final @NotNull TilePosc tilePos) {
-        return this.getBlockId(tilePos) == 0;
+        return this.getBlockType(tilePos) == Blocks.AIR;
     }
 
     @Deprecated
@@ -551,6 +545,9 @@ public class World implements MutableWorldSource {
         return this.isBlockLoaded(new TilePos(x, y, z));
     }
 
+    public boolean areBlocksLoaded(final @NotNull AABBdc aabb) {
+        return this.areBlocksLoaded(new TilePos(aabb.minX(), aabb.minY(), aabb.minZ()), new TilePos(aabb.maxX(), aabb.maxY(), aabb.maxZ()));
+    }
     public boolean areBlocksLoaded(final @NotNull TilePosc tilePos, final int range) {
         return this.areBlocksLoaded(tilePos.sub(range, range, range, new TilePos()), tilePos.add(range, range, range, new TilePos()));
     }
@@ -621,53 +618,48 @@ public class World implements MutableWorldSource {
     }
 
     @Override
-    public boolean setBlockIdData(final @NotNull TilePosc tilePos, final int id, final int data) {
+    public boolean setBlockTypeData(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final int data) {
         if (!tilePos.inBounds(this)) {
             return false;
         } else {
-            return this.getChunk(tilePos).setBlockIdData(new ChunkTilePos(tilePos), id, data);
+            return this.getChunk(tilePos).setBlockIdData(new ChunkTilePos(tilePos), block.id(), data);
         }
     }
 
-    public boolean setBlockIdRaw(final @NotNull TilePosc tilePos, final int id) {
-        return this.setBlockIdDataRaw(tilePos, id, this.getBlockData(tilePos));
+    public boolean setBlockTypeRaw(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        return this.setBlockTypeDataRaw(tilePos, block, this.getBlockData(tilePos));
     }
 
     @Deprecated
     public final boolean setBlockRaw(final int x, final int y, final int z, final int id) {
-        return this.setBlockIdRaw(new TilePos(x, y, z), id);
+        return this.setBlockTypeRaw(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)));
     }
 
-    public boolean setBlockIdDataRaw(final @NotNull TilePosc tilePos, final int id, final int data) {
+    public boolean setBlockTypeDataRaw(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final int data) {
         if (!tilePos.inBounds(this)) {
             return false;
         } else {
-            return this.getChunk(tilePos).setBlockIdDataRaw(new ChunkTilePos(tilePos), id, data);
+            return this.getChunk(tilePos).setBlockIdDataRaw(new ChunkTilePos(tilePos), block.id(), data);
         }
     }
 
     @Deprecated
     public final boolean setBlockAndMetadataRaw(final int x, final int y, final int z, final int id, final int metadata) {
-        return this.setBlockIdDataRaw(new TilePos(x, y, z), id, metadata);
+        return this.setBlockTypeDataRaw(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)), metadata);
     }
 
     @Override
-    public boolean setBlockId(final @NotNull TilePosc tilePos, final int id) {
+    public boolean setBlockType(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (!tilePos.inBounds(this)) {
             return false;
         } else {
-            return this.getChunk(tilePos).setBlockId(new ChunkTilePos(tilePos), id);
+            return this.getChunk(tilePos).setBlockId(new ChunkTilePos(tilePos), block.id());
         }
     }
 
     @Override
     public @NotNull Material getBlockMaterial(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        if (block == null) {
-            return Materials.AIR;
-        } else {
-            return block.getMaterial();
-        }
+        return this.getBlockType(tilePos).getMaterial();
     }
 
     @Override
@@ -683,9 +675,9 @@ public class World implements MutableWorldSource {
         if (this.setBlockData(tilePos, data)) {
             this.markBlockNeedsUpdate(tilePos);
 
-            final int id = this.getBlockId(tilePos);
-            if (Blocks.neighborNotifyOnMetadataChangeDisabled[id & 0x3FFF]) {
-                this.notifyBlocksOfNeighborChange(tilePos, id);
+            final @NotNull Block<?> block = this.getBlockType(tilePos);
+            if (block.neighborNotifyOnDataChangeDisabled()) {
+                this.notifyBlocksOfNeighborChange(tilePos, block);
                 return true;
             }
         }
@@ -708,9 +700,9 @@ public class World implements MutableWorldSource {
         }
     }
 
-    public boolean setBlockIdNotify(final @NotNull TilePosc tilePos, final int id) {
-        if (this.setBlockId(tilePos, id)) {
-            this.notifyBlockChange(tilePos, id);
+    public boolean setBlockTypeNotify(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
+        if (this.setBlockType(tilePos, block)) {
+            this.notifyBlockChange(tilePos, block);
             return true;
         }
 
@@ -719,12 +711,12 @@ public class World implements MutableWorldSource {
 
     @Deprecated
     public final boolean setBlockWithNotify(final int x, final int y, final int z, final int id) {
-        return this.setBlockIdNotify(new TilePos(x, y, z), id);
+        return this.setBlockTypeNotify(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)));
     }
 
-    public boolean setBlockIdDataNotify(final @NotNull TilePosc tilePos, final int id, final int data) {
-        if (this.setBlockIdData(tilePos, id, data)) {
-            this.notifyBlockChange(tilePos, id);
+    public boolean setBlockTypeDataNotify(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final int data) {
+        if (this.setBlockTypeData(tilePos, block, data)) {
+            this.notifyBlockChange(tilePos, block);
             return true;
         }
 
@@ -733,7 +725,7 @@ public class World implements MutableWorldSource {
 
     @Deprecated
     public final boolean setBlockAndMetadataWithNotify(final int x, final int y, final int z, final int id, final int data) {
-        return this.setBlockIdDataNotify(new TilePos(x, y, z), id, data);
+        return this.setBlockTypeDataNotify(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)), data);
     }
 
     public void markBlockNeedsUpdate(final @NotNull TilePosc tilePos) {
@@ -747,14 +739,14 @@ public class World implements MutableWorldSource {
         this.markBlockNeedsUpdate(new TilePos(x, y, z));
     }
 
-    public void notifyBlockChange(final @NotNull TilePosc tilePos, final int id) {
+    public void notifyBlockChange(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         this.markBlockNeedsUpdate(tilePos);
-        this.notifyBlocksOfNeighborChange(tilePos, id);
+        this.notifyBlocksOfNeighborChange(tilePos, block);
     }
 
     @Deprecated
     public final void notifyBlockChange(final int x, final int y, final int z, final int id) {
-        this.notifyBlockChange(new TilePos(x, y, z), id);
+        this.notifyBlockChange(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)));
     }
 
     public void markBlocksDirtyVertical(final int x, final int z, final int y0, final int y1) {
@@ -790,29 +782,27 @@ public class World implements MutableWorldSource {
         this.markBlocksDirty(new TilePos(minX, minY, minZ), new TilePos(maxX, maxY, maxZ));
     }
 
-    public void notifyBlocksOfNeighborChange(final @NotNull TilePosc tilePos, final int id) {
+    public void notifyBlocksOfNeighborChange(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         TilePos queryPos = new TilePos();
-        this.notifyBlockOfNeighborChange(tilePos.add(Direction.WEST, queryPos), id);
-        this.notifyBlockOfNeighborChange(tilePos.add(Direction.EAST, queryPos), id);
-        this.notifyBlockOfNeighborChange(tilePos.add(Direction.DOWN, queryPos), id);
-        this.notifyBlockOfNeighborChange(tilePos.add(Direction.UP, queryPos), id);
-        this.notifyBlockOfNeighborChange(tilePos.add(Direction.NORTH, queryPos), id);
-        this.notifyBlockOfNeighborChange(tilePos.add(Direction.SOUTH, queryPos), id);
+        this.notifyBlockOfNeighborChange(tilePos.add(Direction.WEST, queryPos), block);
+        this.notifyBlockOfNeighborChange(tilePos.add(Direction.EAST, queryPos), block);
+        this.notifyBlockOfNeighborChange(tilePos.add(Direction.DOWN, queryPos), block);
+        this.notifyBlockOfNeighborChange(tilePos.add(Direction.UP, queryPos), block);
+        this.notifyBlockOfNeighborChange(tilePos.add(Direction.NORTH, queryPos), block);
+        this.notifyBlockOfNeighborChange(tilePos.add(Direction.SOUTH, queryPos), block);
     }
 
     @Deprecated
     public final void notifyBlocksOfNeighborChange(final int x, final int y, final int z, final int id) {
-        this.notifyBlocksOfNeighborChange(new TilePos(x, y, z), id);
+        this.notifyBlocksOfNeighborChange(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)));
     }
 
-    private void notifyBlockOfNeighborChange(final @NotNull TilePosc tilePos, final int id) {
+    private void notifyBlockOfNeighborChange(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
         if (this.noNeighborUpdate || this.isClientSide) {
             return;
         }
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        if (block != null) {
-            block.onNeighborChanged(this, tilePos, id);
-        }
+
+        this.getBlockType(tilePos).onNeighborChanged(this, tilePos, block);
     }
 
     public boolean canBlockSeeSky(final @NotNull TilePosc tilePos) {
@@ -990,13 +980,15 @@ public class World implements MutableWorldSource {
         Vector3d end2 = new Vector3d(end);
         TilePos blockEnd = new TilePos(end2);
         TilePos blockStart = new TilePos(start2);
-        int id = getBlockId(blockStart);
+        final @NotNull Block<?> block = getBlockType(blockStart);
         int meta = getBlockData(blockStart);
-        Block<?> block = Blocks.blocksList[id];
-        if (
-            (!ignoreNonColliderBlocks ||
-                (block == null) ||
-                ((useSelectorBoxes ? block.getSelectionAABB(this, blockStart) : block.getCollisionAABB(this, blockStart)) != null)) && (id > 0) && (block != null && block.canCollideCheck(meta, shouldCollideWithFluids))) {
+        final @Nullable AABBdc aabb;
+        if (useSelectorBoxes) {
+            aabb = block.getSelectionAABB(this, blockStart);
+        } else {
+            aabb = block.getCollisionAABB(this, blockStart);
+        }
+        if ((!ignoreNonColliderBlocks || aabb != null) && block.canCollideCheck(meta, shouldCollideWithFluids)) {
             HitResult hitResult = block.collisionRayTrace(this, blockStart, start2, end2, useSelectorBoxes);
             if (hitResult != null) {
                 return hitResult;
@@ -1096,10 +1088,15 @@ public class World implements MutableWorldSource {
                 blockStart.z--;
                 startCopy.z++;
             }
-            Block<?> block1 = getBlock(blockStart);
+            final @NotNull Block<?> block1 = getBlockType(blockStart);
+            final @Nullable AABBdc aabb1;
+            if (useSelectorBoxes) {
+                aabb1 = block1.getSelectionAABB(this, blockStart);
+            } else {
+                aabb1 = block1.getCollisionAABB(this, blockStart);
+            }
             int metadata1 = getBlockData(blockStart);
-            if (
-                (!ignoreNonColliderBlocks || (block1 == null) || ((useSelectorBoxes ? block1.getSelectionAABB(this, blockStart) : block1.getCollisionAABB(this, blockStart)) != null)) && (block1 != null) && block1.canCollideCheck(metadata1, shouldCollideWithFluids)) {
+            if ((!ignoreNonColliderBlocks || aabb1 != null) && block1.canCollideCheck(metadata1, shouldCollideWithFluids)) {
                 HitResult hitResult = block1.collisionRayTrace(this, blockStart, start2, end2, useSelectorBoxes);
                 if (hitResult != null) {
                     return hitResult;
@@ -1124,9 +1121,7 @@ public class World implements MutableWorldSource {
         }
     }
 
-    public void playBlockSoundEffect(@Nullable Entity player, double x, double y, double z, Block<?> block, EnumBlockSoundEffectType soundType) {
-        if (block == null) return;
-
+    public void playBlockSoundEffect(@Nullable Entity player, double x, double y, double z, final @NotNull Block<?> block, EnumBlockSoundEffectType soundType) {
         BlockSound sound = block.getSound();
         if (sound == null) return;
 
@@ -1281,7 +1276,7 @@ public class World implements MutableWorldSource {
         for (d.x = minX - 1; d.x <= maxX; d.x++) {
             for (d.z = minZ - 1; d.z <= maxZ; d.z++) {
                 for (d.y = minY - 1; d.y <= maxY; d.y++) {
-                    Block<?> block = getBlock(d);
+                    Block<?> block = getBlockType(d);
                     if (block != null) {
                         int metadata = getBlockData(d);
                         if (block.collidesWithEntity(entity, this, d) && entity.collidesWithBlock(block, metadata)) {
@@ -1319,7 +1314,7 @@ public class World implements MutableWorldSource {
                     continue;
                 }
                 for (tilePos.y = minY - 1; tilePos.y <= maxY; tilePos.y++) {
-                    Block<?> block = getBlock(tilePos);
+                    Block<?> block = getBlockType(tilePos);
                     if (block != null && block.isSolidRender()) {
                         // ignore mesh blocks if entity is instance of an item
                         if (!(entity instanceof EntityItem && (block.id() == Blocks.MESH.id() || block.id() == Blocks.SPIKES.id() || block.id() == Blocks.MOBSPAWNER.id())))
@@ -1421,17 +1416,17 @@ public class World implements MutableWorldSource {
 
     @Deprecated
     public final void scheduleBlockUpdate(final int x, final int y, final int z, final int id, final long delay) {
-        this.scheduleBlockUpdate(new TilePos(x, y, z), id, delay);
+        this.scheduleBlockUpdate(new TilePos(x, y, z), Objects.requireNonNull(Blocks.getBlock(id)), delay);
     }
 
-    public void scheduleBlockUpdate(final @NotNull TilePosc tilePos, final int id, final long delay) {
-        NextTickListEntry entry = new NextTickListEntry(tilePos, id);
+    public void scheduleBlockUpdate(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final long delay) {
+        NextTickListEntry entry = new NextTickListEntry(tilePos, block);
         final byte radius = 8;
 
         if (this.scheduledUpdatesAreImmediate && !this.immediatelyUpdatedPositions.contains(entry)) {
             if (areBlocksLoaded(entry.tilePos.x - radius, entry.tilePos.y - radius, entry.tilePos.z - radius, entry.tilePos.x() + radius, entry.tilePos.y() + radius, entry.tilePos.z() + radius)) {
-                final @NotNull Block<?> block = this.getBlock(entry.tilePos);
-                if (block != null && block.id() == entry.blockId) {
+                final @NotNull Block<?> worldBlock = this.getBlockType(entry.tilePos);
+                if (worldBlock == entry.block) {
                     this.immediatelyUpdatedPositions.add(entry);
                     block.updateTick(this, entry.tilePos, this.rand, false);
                 }
@@ -1439,9 +1434,7 @@ public class World implements MutableWorldSource {
             return;
         }
         if (areBlocksLoaded(tilePos, radius)) {
-            if (id > 0) {
-                entry.setDelay(delay + runtime);
-            }
+            entry.setDelay(delay + runtime);
             if (!this.tickNextTickSet.contains(entry)) {
                 this.tickNextTickSet.add(entry);
                 this.tickNextTickList.add(entry);
@@ -1641,9 +1634,11 @@ public class World implements MutableWorldSource {
         for (tilePos.x = minX; tilePos.x <= maxX; tilePos.x++) {
             for (tilePos.y = minY; tilePos.y <= maxY; tilePos.y++) {
                 for (tilePos.z = minZ; tilePos.z <= maxZ; tilePos.z++) {
-                    Block<?> block = getBlock(tilePos);
-                    if (block != null && block.getMaterial().isLiquid()) {
-                        return true;
+                    if (isBlockLoaded(tilePos)) {
+                        Block<?> block = getBlockType(tilePos);
+                        if (block != null && block.getMaterial().isLiquid()) {
+                            return true;
+                        }
                     }
                 }
             }
@@ -1672,8 +1667,8 @@ public class World implements MutableWorldSource {
         for (tilePos.x = minX; tilePos.x < maxX; tilePos.x++) {
             for (tilePos.y = minY; tilePos.y < maxY; tilePos.y++) {
                 for (tilePos.z = minZ; tilePos.z < maxZ; tilePos.z++) {
-                    Block<?> block = getBlock(tilePos);
-                    if (block == null || !isMaterialInBB(aabb, material)) {
+                    final @NotNull Block<?> block = getBlockType(tilePos);
+                    if (!isMaterialInBB(aabb, material)) {
                         continue;
                     }
                     flag = true;
@@ -1705,7 +1700,7 @@ public class World implements MutableWorldSource {
         for (tilePos.x = minX_i; tilePos.x < maxX_i; tilePos.x++) {
             for (tilePos.y = minY_i; tilePos.y < maxY_i; tilePos.y++) {
                 for (tilePos.z = minZ_i; tilePos.z < maxZ_i; tilePos.z++) {
-                    Block<?> block = getBlock(tilePos);
+                    Block<?> block = getBlockType(tilePos);
                     if (block != null) {
                         boolean isMaterial = false;
                         for (Material m : materials) {
@@ -1739,7 +1734,7 @@ public class World implements MutableWorldSource {
         for (tilePos.x = minX_i; tilePos.x < maxX_i; tilePos.x++) {
             for (tilePos.y = minY_i; tilePos.y < maxY_i; tilePos.y++) {
                 for (tilePos.z = minZ_i; tilePos.z < maxZ_i; tilePos.z++) {
-                    Block<?> block = getBlock(tilePos);
+                    Block<?> block = getBlockType(tilePos);
                     if (block != null) {
                         if (block.getMaterial() != material) continue;
 
@@ -1765,8 +1760,8 @@ public class World implements MutableWorldSource {
         for (tilePos.x = minX; tilePos.x < maxX; tilePos.x++) {
             for (tilePos.y = minY; tilePos.y < maxY; tilePos.y++) {
                 for (tilePos.z = minZ; tilePos.z < maxZ; tilePos.z++) {
-                    Block<?> block = getBlock(tilePos);
-                    if (block == null || block.getMaterial() != material) {
+                    final @NotNull Block<?> block = getBlockType(tilePos);
+                    if (block.getMaterial() != material) {
                         continue;
                     }
                     int j2 = getBlockData(tilePos);
@@ -1828,13 +1823,13 @@ public class World implements MutableWorldSource {
         return (float) i / (float) j;
     }
 
-    public void onBlockHit(final @NotNull Player player, final @NotNull TilePos tilePos, final @NotNull Side side) {
+    public void onBlockHit(final @NotNull Player player, final @NotNull TilePosc tilePos, final @NotNull Side side) {
         final @NotNull TilePos offsetPos = tilePos.add(side.getDirection(), new TilePos());
-        final @Nullable Block<?> block = this.getBlock(offsetPos);
+        final @Nullable Block<?> block = this.getBlockType(offsetPos);
 
         if (block == Blocks.FIRE || block == Blocks.FIRE_COLD) {
             this.playBlockEvent(player, offsetPos, LevelListener.EVENT_FIRE_EXTINGUISH, 0);
-            this.setBlockIdNotify(tilePos, 0);
+            this.setBlockTypeNotify(tilePos, Blocks.AIR);
         }
     }
 
@@ -1894,12 +1889,12 @@ public class World implements MutableWorldSource {
 
     @Override
     public boolean isBlockOpaqueCube(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
+        final @Nullable Block<?> block = this.getBlockType(tilePos);
         return block != null && block.isSolidRender();
     }
 
     public boolean canPlaceOnSurfaceOfBlock(final @NotNull TilePos tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
+        final @Nullable Block<?> block = this.getBlockType(tilePos);
         return block != null && block.canPlaceOnSurfaceOnCondition(this, tilePos.x, tilePos.y, tilePos.z);
     }
 
@@ -1909,12 +1904,7 @@ public class World implements MutableWorldSource {
     }
 
     public @NotNull ISupport getSupport(final @NotNull TilePos tilePos, final @NotNull Side side) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        if (block == null) {
-            return PartialSupport.INSTANCE;
-        }
-
-        return block.getSupport(this, tilePos.x, tilePos.y, tilePos.z, side);
+        return this.getBlockType(tilePos).getSupport(this, tilePos, side);
     }
 
     @Deprecated
@@ -1925,13 +1915,12 @@ public class World implements MutableWorldSource {
     @Override
     public boolean isBlockNormalCube(final @NotNull TilePosc tilePos) {
         // Determines if you suffocate in a block, among other things.
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        return block != null && block.getMaterial().isSolidBlocking() && block.renderAsNormalBlockOnCondition(this, tilePos);
+        final @NotNull Block<?> block = this.getBlockType(tilePos);
+        return block.getMaterial().isSolidBlocking() && block.renderAsNormalBlockOnCondition(this, tilePos);
     }
 
     public boolean canPlaceInsideBlock(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        return block == null || block.hasTag(BlockTags.PLACE_OVERWRITES);
+        return this.getBlockType(tilePos).hasTag(BlockTags.PLACE_OVERWRITES);
     }
 
     @Deprecated
@@ -2172,8 +2161,8 @@ public class World implements MutableWorldSource {
             if (!this.areBlocksLoaded(entry.tilePos.x - radius, entry.tilePos.y - radius, entry.tilePos.z - radius, entry.tilePos.x + radius, entry.tilePos.y + radius, entry.tilePos.z + radius)) {
                 continue;
             }
-            final @Nullable Block<?> block = this.getBlock(entry.tilePos);
-            if (block != null && block.id() == entry.blockId) {
+            final @Nullable Block<?> block = this.getBlockType(entry.tilePos);
+            if (block == entry.block) {
                 block.updateTick(this, entry.tilePos, this.rand, false);
             }
         }
@@ -2193,7 +2182,7 @@ public class World implements MutableWorldSource {
                 this.rand.nextInt(radius) - this.rand.nextInt(radius),
                 randomPos);
 
-            final @Nullable Block<?> block = this.getBlock(randomPos);
+            final @Nullable Block<?> block = this.getBlockType(randomPos);
             if (block != null) {
                 block.animationTick(this, randomPos, random);
             }
@@ -2298,11 +2287,8 @@ public class World implements MutableWorldSource {
             return false;
         }
 
-        final @Nullable Block<?> currentBlock = this.getBlock(tilePos);
-        final @Nullable Block<?> newBlock = Blocks.blocksList[id];
-        if (newBlock == null) {
-            return false;
-        }
+        final @NotNull Block<?> currentBlock = this.getBlockType(tilePos);
+        final @NotNull Block<?> newBlock = Objects.requireNonNull(Blocks.blocksList[id]);
 
         final @Nullable AABBdc bb;
         if (ignoreCollision) {
@@ -2315,7 +2301,7 @@ public class World implements MutableWorldSource {
             return false;
         }
 
-        if (currentBlock == null || currentBlock.hasTag(BlockTags.PLACE_OVERWRITES)) {
+        if (currentBlock.hasTag(BlockTags.PLACE_OVERWRITES)) {
             return newBlock.canPlaceOnSide(this, tilePos, side);
         } else {
             return false;
@@ -2359,7 +2345,7 @@ public class World implements MutableWorldSource {
     }
 
     public boolean hasDirectSignal(final @NotNull TilePosc tilePos, final @NotNull Side side) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
+        final @Nullable Block<?> block = this.getBlockType(tilePos);
         return block != null && block.isEmittingDirectSignal(this, tilePos, side);
     }
 
@@ -2385,13 +2371,10 @@ public class World implements MutableWorldSource {
     }
 
     public boolean hasSignal(final @NotNull TilePosc tilePos, final @NotNull Side side) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
+        final @NotNull Block<?> block = this.getBlockType(tilePos);
         if (this.isBlockNormalCube(tilePos) && block != Blocks.BLOCK_REDSTONE && block != Blocks.PUMPKIN_REDSTONE && block != Blocks.MATCHER_ACTIVE) {
             return this.hasDirectSignal(tilePos);
         }
-        if (block == null) {
-            return false;
-        }
 
         if (block == Blocks.PUMPKIN_REDSTONE) {
             return this.pumpkinHasDirectSignal(tilePos) || block.isEmittingSignal(this, tilePos, side);
@@ -2696,7 +2679,7 @@ public class World implements MutableWorldSource {
     }
 
     public void triggerEvent(final @NotNull TilePosc tilePos, final int index, final int data) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
+        final @Nullable Block<?> block = this.getBlockType(tilePos);
         if (block != null) {
             block.triggerEvent(this, tilePos.x(), tilePos.y(), tilePos.z(), index, data);
         }
diff --git a/game/core/src/main/java/net/minecraft/core/world/WorldSource.java b/game/core/src/main/java/net/minecraft/core/world/WorldSource.java
index 3294d86ed..21aadb3ef 100644
--- a/game/core/src/main/java/net/minecraft/core/world/WorldSource.java
+++ b/game/core/src/main/java/net/minecraft/core/world/WorldSource.java
@@ -15,18 +15,16 @@ import org.jetbrains.annotations.Nullable;
 public interface WorldSource {
     int getHeightBlocks();
 
-    int getBlockId(final @NotNull TilePosc tilePos);
-
     @Deprecated
     default int getBlockId(final int x, final int y, final int z) {
-        return this.getBlockId(new TilePos(x, y, z));
+        return this.getBlockType(new TilePos(x, y, z)).id();
     }
 
-    @Nullable Block<?> getBlock(final @NotNull TilePosc tilePos);
+    @NotNull Block<?> getBlockType(final @NotNull TilePosc tilePos);
 
     @Deprecated
-    default @Nullable Block<?> getBlock(final int x, final int y, final int z) {
-        return this.getBlock(new TilePos(x, y, z));
+    default @NotNull Block<?> getBlock(final int x, final int y, final int z) {
+        return this.getBlockType(new TilePos(x, y, z));
     }
 
     @Nullable TileEntity getTileEntity(final @NotNull TilePosc tilePos);
@@ -37,11 +35,7 @@ public interface WorldSource {
     }
 
     default <T> @Nullable T getBlockLogic(final @NotNull TilePosc tilePos, final @NotNull Class<T> logicClass) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        if (block == null) {
-            return null;
-        }
-
+        final @NotNull Block<?> block = this.getBlockType(tilePos);
         final @NotNull BlockLogic logic = block.getLogic();
         if (logicClass.isAssignableFrom(logic.getClass())) {
             return logicClass.cast(logic);
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
index dc143df72..ac9ff06ab 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
@@ -256,7 +256,7 @@ public class Chunk {
         return this.getBlockId(new ChunkTilePos(x, y, z));
     }
 
-    public @Nullable Block<?> getBlock(final @NotNull ChunkTilePosc tilePos) {
+    public @NotNull Block<?> getBlock(final @NotNull ChunkTilePosc tilePos) {
         return Blocks.getBlock(this.getBlockId(tilePos));
     }
 
@@ -285,8 +285,8 @@ public class Chunk {
         final int currentId = section.getBlockId(new ChunkSectionTilePos(tilePos));
         final int currentData = section.getData(new ChunkSectionTilePos(tilePos));
 
-        final @Nullable Block<?> currentBlock = Blocks.getBlock(currentId);
-        final @Nullable Block<?> newBlock = Blocks.getBlock(id);
+        final @NotNull Block<?> currentBlock = Objects.requireNonNull(Blocks.getBlock(currentId));
+        final @NotNull Block<?> newBlock = Objects.requireNonNull(Blocks.getBlock(id));
 
         if (currentId == id && currentData == data) {
             return false;
@@ -296,7 +296,7 @@ public class Chunk {
         section.setData(new ChunkSectionTilePos(tilePos), data);
 
         final @NotNull TilePos worldPos = new TilePos(this.pos, tilePos);
-        if (!raw && currentBlock != null && !this.world.isClientSide) {
+        if (!raw && !this.world.isClientSide) {
             currentBlock.onRemoved(this.world, worldPos, currentData);
         }
 
@@ -314,7 +314,7 @@ public class Chunk {
         this.world.scheduleLightingUpdate(LightLayer.Block, worldPos);
         this.lightGaps(tilePos.x(), tilePos.z());
 
-        if (!raw && newBlock != null) {
+        if (!raw) {
             newBlock.onPlacedByWorld(this.world, worldPos);
         }
 
@@ -574,7 +574,7 @@ public class Chunk {
 
         if (tileEntity == null) {
             final @Nullable Block<?> block = this.getBlock(tilePos);
-            if (block == null || !block.isEntityTile) {
+            if (!block.isEntityTile) {
                 return null;
             } else {
                 block.onBlockPlacedByWorld(this.world, this.pos.x * CHUNK_SIZE_X + tilePos.x(), tilePos.y(), this.pos.z * CHUNK_SIZE_Z + tilePos.z());
@@ -616,7 +616,7 @@ public class Chunk {
         tileEntity.z = worldPos.z;
 
         final @Nullable Block<?> block = this.getBlock(tilePos);
-        if (block == null || !block.isEntityTile) {
+        if (!block.isEntityTile) {
             LOGGER.warn("Attempted to place a tile entity {} at {} {} {} where there was no tile entity block!", tileEntity.getClass(), worldPos.x, worldPos.y, worldPos.z);
             Thread.dumpStack();
         } else {
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
index e2c46382c..739fdc602 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
@@ -10,12 +10,15 @@ import net.minecraft.core.world.World;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkTilePos;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.season.SeasonManager;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.Objects;
+
 public class ChunkCache
     implements WorldSource {
     private final @NotNull ChunkPos origin;
@@ -25,7 +28,7 @@ public class ChunkCache
     private final int widthX;
     private final int widthZ;
 
-    public ChunkCache(final @NotNull World world, final @NotNull TilePos min, final @NotNull TilePos max, boolean priority) {
+    public ChunkCache(final @NotNull World world, final @NotNull TilePos min, final @NotNull TilePos max, final boolean priority) {
         this.world = world;
         this.origin = new ChunkPos(min);
 
@@ -60,29 +63,24 @@ public class ChunkCache
     }
 
     @Override
-    public int getBlockId(final @NotNull TilePosc tilePos) {
+    public @NotNull Block<?> getBlockType(final @NotNull TilePosc tilePos) {
         if (tilePos.y() < 0 || tilePos.y() >= this.getHeightBlocks()) {
-            return 0;
+            return Blocks.AIR;
         }
 
         final @NotNull ChunkPos cachePos = new ChunkPos(tilePos).sub(this.origin.x, this.origin.z, new ChunkPos());
         if (cachePos.x < 0 || cachePos.x >= this.chunkArray.length || cachePos.z < 0 || cachePos.z >= this.chunkArray[cachePos.x].length) {
-            return 0;
+            return Blocks.AIR;
         }
 
         final @NotNull Chunk chunk = this.chunkArray[cachePos.x][cachePos.z];
-        return chunk.getBlockID(tilePos.x() & (Chunk.CHUNK_SIZE_X - 1), tilePos.y(), tilePos.z() & (Chunk.CHUNK_SIZE_Z - 1));
-    }
-
-    @Override
-    public @Nullable Block<?> getBlock(final @NotNull TilePosc tilePos) {
-        return Blocks.getBlock(this.getBlockId(tilePos));
+        return chunk.getBlock(new ChunkTilePos(tilePos));
     }
 
     @Override
     public @Nullable TileEntity getTileEntity(final @NotNull TilePosc tilePos) {
         final @NotNull ChunkPos cachePos = new ChunkPos(tilePos).sub(this.origin.x, this.origin.z, new ChunkPos());
-        return this.chunkArray[cachePos.x][cachePos.z].getTileEntity(tilePos.x() & (Chunk.CHUNK_SIZE_X - 1), tilePos.y(), tilePos.z() & (Chunk.CHUNK_SIZE_Z - 1));
+        return this.chunkArray[cachePos.x][cachePos.z].getTileEntity(new ChunkTilePos(tilePos));
     }
 
     public boolean getBlockLitInteriorSurface(final @NotNull TilePosc tilePos) {
@@ -178,7 +176,7 @@ public class ChunkCache
             return brightness;
         } else {
             final @NotNull ChunkPos cachePos = new ChunkPos(tilePos).sub(this.origin.x, this.origin.z, new ChunkPos());
-            return this.chunkArray[cachePos.x][cachePos.z].getRawBrightness(tilePos.x() & (Chunk.CHUNK_SIZE_X - 1), tilePos.y(), tilePos.z() & (Chunk.CHUNK_SIZE_Z - 1), this.world.skyDarken);
+            return this.chunkArray[cachePos.x][cachePos.z].getRawBrightness(new ChunkTilePos(tilePos), this.world.skyDarken);
         }
     }
 
@@ -188,30 +186,24 @@ public class ChunkCache
             return 0;
         } else {
             final @NotNull ChunkPos cachePos = new ChunkPos(tilePos).sub(this.origin.x, this.origin.z, new ChunkPos());
-            return this.chunkArray[cachePos.x][cachePos.z].getBlockMetadata(tilePos.x() & (Chunk.CHUNK_SIZE_X - 1), tilePos.y(), tilePos.z() & (Chunk.CHUNK_SIZE_Z - 1));
+            return this.chunkArray[cachePos.x][cachePos.z].getBlockData(new ChunkTilePos(tilePos));
         }
     }
 
     @Override
     public @NotNull Material getBlockMaterial(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        if (block == null) {
-            return Materials.AIR;
-        } else {
-            return block.getMaterial();
-        }
+        return this.getBlockType(tilePos).getMaterial();
     }
 
     @Override
     public boolean isBlockOpaqueCube(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        return block != null && block.isSolidRender();
+        return this.getBlockType(tilePos).isSolidRender();
     }
 
     @Override
     public boolean isBlockNormalCube(final @NotNull TilePosc tilePos) {
-        final @Nullable Block<?> block = this.getBlock(tilePos);
-        return block != null && block.getMaterial().isSolidBlocking() && block.renderAsNormalBlockOnCondition(this, tilePos);
+        final @Nullable Block<?> block = this.getBlockType(tilePos);
+        return block.getMaterial().isSolidBlocking() && block.renderAsNormalBlockOnCondition(this, tilePos);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java
index fc844e0c7..4fe64ebe8 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java
@@ -78,9 +78,9 @@ public class ChunkSection {
     }
 
     public void setBlockId(final @NotNull ChunkSectionTilePosc sectionPos, final int id) {
-        assert id == 0 || Blocks.getBlock(id) != null;
+        assert Blocks.getBlock(id) != null;
 
-        if (!sectionPos.inBounds() || (this.blocks == null && id == 0)) {
+        if (!sectionPos.inBounds() || (this.blocks == null && id == Blocks.AIR.id())) {
             return;
         } else if (this.blocks == null) {
             this.blocks = new short[Chunk.CHUNK_SIZE_X * SECTION_SIZE_Y * Chunk.CHUNK_SIZE_Z];
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/MissingBlockFixer.java b/game/core/src/main/java/net/minecraft/core/world/chunk/MissingBlockFixer.java
index ec62e906c..962050424 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/MissingBlockFixer.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/MissingBlockFixer.java
@@ -2,43 +2,33 @@ package net.minecraft.core.world.chunk;
 
 import com.mojang.logging.LogUtils;
 import net.minecraft.core.block.Blocks;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 
-public class MissingBlockFixer
-{
+public final class MissingBlockFixer {
     private static final Logger LOGGER = LogUtils.getLogger();
-    private static final short[] blocksArray;
+    private static final short @NotNull [] BLOCKS_ARRAY;
 
-    public MissingBlockFixer()
-    {
-    }
-
-    public static void fixMissingBlocks(short[] blocks)
-    {
-        for (int i = 0; i < blocks.length; i++)
-        {
-        	blocks[i] = blocksArray[blocks[i] & 0x3FFF];
-        }
-    }
-
-    static 
-    {
-        blocksArray = new short[Blocks.blocksList.length];
-        try
-        {
-            for (int i = 0; i < Blocks.blocksList.length; i++)
-            {
-                short id = (short)i;
-                if(id != 0 && Blocks.blocksList[id & 0x3FFF] == null)
-                {
-                	id = 0;
+    static {
+        BLOCKS_ARRAY = new short[Blocks.blocksList.length];
+        try {
+            for (int i = 0; i < Blocks.blocksList.length; i++) {
+                short id = (short) i;
+                if (Blocks.blocksList[id & 0x3FFF] == null) {
+                    id = (short) Blocks.AIR.id();
                 }
-                blocksArray[i] = id;
+                BLOCKS_ARRAY[i] = id;
             }
-        }
-        catch (Exception exception)
-        {
+        } catch (final Exception exception) {
             LOGGER.error("Exception initializing blocksArray!", exception);
         }
     }
+
+    public static void fixMissingBlocks(final short @NotNull [] blocks) {
+        for (int i = 0; i < blocks.length; i++) {
+            blocks[i] = BLOCKS_ARRAY[blocks[i] & 0x3FFF];
+        }
+    }
+
+    private MissingBlockFixer() { }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/ChunkGeneratorResult.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/ChunkGeneratorResult.java
index b40f6644a..5b68dbd53 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/ChunkGeneratorResult.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/ChunkGeneratorResult.java
@@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Arrays;
+import java.util.Objects;
 
 public class ChunkGeneratorResult {
     private final short @NotNull [] @Nullable [] sectionBlocksArray;
@@ -16,54 +17,62 @@ public class ChunkGeneratorResult {
     public ChunkGeneratorResult() {
         this.sectionBlocksArray = new short[Chunk.CHUNK_SECTIONS][];
         this.numBlocksInSectionArray = new int[Chunk.CHUNK_SECTIONS];
-        Arrays.fill(this.numBlocksInSectionArray, 0);
     }
 
-    public void setBlock(int x, int y, int z, int id) {
-        if (x < 0 || x >= Chunk.CHUNK_SIZE_X ||
+    public void setBlock(final int x, final int y, final int z, final int id) {
+        if (
+            x < 0 || x >= Chunk.CHUNK_SIZE_X ||
             y < 0 || y >= (Chunk.CHUNK_SECTIONS * ChunkSection.SECTION_SIZE_Y) ||
             z < 0 || z >= Chunk.CHUNK_SIZE_Z ||
-            id < 0) return;
+            id < 0
+        ) {
+            return;
+        }
 
-        int section = y / ChunkSection.SECTION_SIZE_Y;
-        int cy = y % ChunkSection.SECTION_SIZE_Y;
+        final int section = y / ChunkSection.SECTION_SIZE_Y;
+        final int cy = y % ChunkSection.SECTION_SIZE_Y;
 
-        Block<?> newBlock = Blocks.getBlock(id);
+        final @NotNull Block<?> newBlock = Objects.requireNonNull(Blocks.getBlock(id));
 
         // If the array is null and we're only clearing a block, skip creating it; otherwise, create it
         if (this.sectionBlocksArray[section] == null) {
-            if (newBlock == null) {
-                return;
-            } else {
+            if (newBlock != Blocks.AIR) {
                 this.sectionBlocksArray[section] = new short[Chunk.CHUNK_SIZE_X * ChunkSection.SECTION_SIZE_Y * Chunk.CHUNK_SIZE_Z];
+            } else {
+                return;
             }
         }
 
         // Increment or decrement numBlocksInSection depending on whether we're setting or clearing a block
-        Block<?> currentBlock = Blocks.getBlock(getBlock(x, y, z));
-        if (newBlock == null && currentBlock != null) {
+        final @NotNull Block<?> currentBlock = Objects.requireNonNull(Blocks.getBlock(this.getBlock(x, y, z)));
+        if (newBlock == Blocks.AIR && currentBlock != Blocks.AIR) {
             this.numBlocksInSectionArray[section]--;
-        } else if (newBlock != null && currentBlock == null) {
+        } else if (newBlock != Blocks.AIR && currentBlock == Blocks.AIR) {
             this.numBlocksInSectionArray[section]++;
         }
 
         this.sectionBlocksArray[section][ChunkSection.makeBlockIndex(x, cy, z)] = (short) id;
     }
 
-    public int getBlock(int x, int y, int z) {
-        if (x < 0 || x >= Chunk.CHUNK_SIZE_X || y < 0 || y >= (Chunk.CHUNK_SECTIONS * ChunkSection.SECTION_SIZE_Y) || z < 0 || z >= Chunk.CHUNK_SIZE_Z)
+    public int getBlock(final int x, final int y, final int z) {
+        if (
+            x < 0 || x >= Chunk.CHUNK_SIZE_X ||
+            y < 0 || y >= (Chunk.CHUNK_SECTIONS * ChunkSection.SECTION_SIZE_Y) ||
+            z < 0 || z >= Chunk.CHUNK_SIZE_Z
+        ) {
             return 0;
+        }
 
-        int section = y / ChunkSection.SECTION_SIZE_Y;
-        int cy = y % ChunkSection.SECTION_SIZE_Y;
+        final int section = y / ChunkSection.SECTION_SIZE_Y;
+        final int cy = y % ChunkSection.SECTION_SIZE_Y;
 
         if (this.sectionBlocksArray[section] == null) {
-            return 0;
+            return Blocks.AIR.id();
         }
         return this.sectionBlocksArray[section][ChunkSection.makeBlockIndex(x, cy, z)];
     }
 
-    public short[] getSectionBlocks(int ySection) {
+    public short @Nullable [] getSectionBlocks(final int ySection) {
         if (ySection < 0 || ySection >= Chunk.CHUNK_SECTIONS) {
             return null;
         }
diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/TilePosc.java b/game/core/src/main/java/net/minecraft/core/world/pos/TilePosc.java
index e5c2fc578..90abe5021 100644
--- a/game/core/src/main/java/net/minecraft/core/world/pos/TilePosc.java
+++ b/game/core/src/main/java/net/minecraft/core/world/pos/TilePosc.java
@@ -4,6 +4,7 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.world.WorldSource;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.joml.Vector3dc;
 import org.joml.Vector3fc;
 import org.joml.Vector3ic;
@@ -74,7 +75,11 @@ public interface TilePosc {
 
     @NotNull TilePos east(@NotNull TilePos dest);
 
-    default boolean equals(final @NotNull TilePosc tilePos) {
+    default boolean equals(final @Nullable TilePosc tilePos) {
+        if (tilePos == null) {
+            return false;
+        }
+
         return this.x() == tilePos.x() && this.y() == tilePos.y() && this.z() == tilePos.z();
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java b/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
index 8fd2dce1c..0b8a7f2f2 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
@@ -13,6 +13,7 @@ import net.minecraft.core.world.weather.Weathers;
 import net.minecraft.core.world.wind.WindProvider;
 import net.minecraft.core.world.wind.WindProviderGeneric;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Random;
 
@@ -251,8 +252,8 @@ public abstract class WorldType {
         private int maxY = 255;
         private Integer maxPortalY = null;
         private int oceanY = 128;
-        private Block<?> oceanBlock = null;
-        private Block<?> fillerBlock = null;
+        private @Nullable Block<?> oceanBlock = null;
+        private @Nullable Block<?> fillerBlock = null;
         private int dayNightCycleTicks = Global.DAY_LENGTH_TICKS;
         private boolean mayRespawn = false;
         private boolean isRetro = false;
diff --git a/game/core/src/main/resources/lang/en_US/subtitles.lang b/game/core/src/main/resources/lang/en_US/subtitles.lang
index 3f4160498..28d05bfd8 100644
--- a/game/core/src/main/resources/lang/en_US/subtitles.lang
+++ b/game/core/src/main/resources/lang/en_US/subtitles.lang
@@ -1,40 +1,40 @@
 subtitles.mob.sheep=Sheep bleat
-subtitles.mob.chicken=Chicken clucking
+subtitles.mob.chicken=Chicken cluck
 subtitles.mob.chicken.hurt=Chicken hurt
 subtitles.mob.chicken.plop=Chicken plop
-subtitles.mob.pig=Pig oinking
+subtitles.mob.pig=Pig oink
 subtitles.mob.pig.death=Pig death
 subtitles.mob.wolf.howl=Wolf howl
-subtitles.mob.wolf.panting=Wolf panting
+subtitles.mob.wolf.panting=Wolf pant
 subtitles.mob.wolf.hurt=Wolf hurt
-subtitles.mob.wolf.bark=Wolf Bark
+subtitles.mob.wolf.bark=Wolf bark
 subtitles.mob.wolf.growl=Wolf growl
 subtitles.mob.wolf.death=Wolf death
 subtitles.mob.wolf.whine=Wolf whine
-subtitles.mob.wolf.shake=Wolf shaking
+subtitles.mob.wolf.shake=Wolf shake
 subtitles.mob.cow.hurt=Cow hurt
-subtitles.mob.cow=Cow mooing
-subtitles.mob.zombie=Zombie groans
+subtitles.mob.cow=Cow moo
+subtitles.mob.zombie=Zombie groan
 subtitles.mob.zombie.hurt=Zombie hurt
 subtitles.mob.zombie.death=Zombie death
 subtitles.mob.zombiepig.zpighurt=Zombie pigman hurt
-subtitles.mob.zombiepig.zpig=Zombie pigman groans
+subtitles.mob.zombiepig.zpig=Zombie pigman groan
 subtitles.mob.zombiepig.zpigdeath=Zombie pigman death
 subtitles.mob.zombiepig.zpigangry=Zombie pigman angry
-subtitles.mob.skeleton=Skeleton rattles
+subtitles.mob.skeleton=Skeleton rattle
 subtitles.mob.skeleton.death=Skeleton death
 subtitles.mob.skeleton.hurt=Skeleton hurt
 subtitles.mob.ghast.fireball=Ghast fireball
 subtitles.mob.ghast.moan=Ghast moan
 subtitles.mob.ghast.death=Ghast death
-subtitles.mob.ghast.scream=Ghast Scream
+subtitles.mob.ghast.scream=Ghast scream
 subtitles.mob.ghast.affectionate_scream=Ghast affectionate scream
 subtitles.mob.creeper=Creeper hiss
 subtitles.mob.creeper.death=Creeper death
 subtitles.mob.creeper.fuse=Creeper fuse
 subtitles.mob.spider.death=Spider death
 subtitles.mob.spider=Spider hiss
-subtitles.mob.ghast.charge=Ghast charging
+subtitles.mob.ghast.charge=Ghast charge
 subtitles.mob.slime.attack=Slime attack
 subtitles.mob.slime=Slime plop
 subtitles.mob.player.death=Player death
@@ -43,9 +43,9 @@ subtitles.mob.player.hurt=Player hurt
 subtitles.fall.small=Small fall
 subtitles.damage.fall.big=Big fall
 
-subtitles.liquid.water=Water flowing
+subtitles.liquid.water=Water flow
 subtitles.liquid.lava.pop=Lava pop
-subtitles.liquid.lava=Lava bubbling
+subtitles.liquid.lava=Lava bubble
 subtitles.liquid.splash=Water splash
 
 subtitles.portal.portal=Portal ambience
@@ -54,7 +54,7 @@ subtitles.portal.travel=Portal travel
 
 subtitles.item.pickup=Item pickup
 
-subtitles.random.fizz=Fizzing
+subtitles.random.fizz=Fizz
 subtitles.random.drr=Arrow drr
 subtitles.random.fuse=Fuse lit
 subtitles.random.skate=Skating
@@ -67,8 +67,8 @@ subtitles.random.bow=Bow shot
 subtitles.random.hurt=Hurt
 subtitles.random.splash=Splash
 subtitles.random.breath=Breath
-subtitles.random.bite=Player Eating
-subtitles.random.equip=Armor Equipped
+subtitles.random.bite=Player eat
+subtitles.random.equip=Armor equipped
 subtitles.random.stone_scrape=Stone scrape
 
 subtitles.note.snare=Note snare
@@ -93,8 +93,8 @@ subtitles.tile.piston.out=Piston extended
 subtitles.tile.piston.in=Piston retracted
 
 subtitles.tile.tnt.fuse=TNT lit
-subtitles.tile.sensor_block.sense=Mob sensed
-subtitles.tile.mobspawner.spawn=Mob spawned
+subtitles.tile.sensor_block.sense=Mob sense
+subtitles.tile.mobspawner.spawn=Mob spawn
 
 subtitles.tile.dispenser.click=Dispenser click
 subtitles.tile.dispenser.eject=Dispenser eject
@@ -106,4 +106,4 @@ subtitles.tile.activator.use=Activator use
 subtitles.hurt.flesh=Hurt flesh
 
 subtitles.fire.ignite=Fire lit
-subtitles.fire.fire=Fire crackling
+subtitles.fire.fire=Fire crackle
diff --git a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
index 5ae372bd0..86abe3c9b 100644
--- a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
@@ -100,12 +100,12 @@ public class PlayerServer extends Player implements ContainerListener {
         this.gamemode = gamemode;
 
         MenuInventory newContainer = gamemode.getInventoryMenu(this.inventory);
-        if (craftingInventory == inventorySlots)
+        if (containerMenu == inventoryMenu)
         {
-            craftingInventory = newContainer;
+            containerMenu = newContainer;
         }
-        inventorySlots = newContainer;
-        inventorySlots.addSlotListener(this);
+        inventoryMenu = newContainer;
+        inventoryMenu.addSlotListener(this);
         if (!gamemode.hasPlayerFlight())
         {
             noPhysics = false;
@@ -168,7 +168,7 @@ public class PlayerServer extends Player implements ContainerListener {
 
     public void setupCraftingInventoryListener()
     {
-        craftingInventory.addSlotListener(this);
+        containerMenu.addSlotListener(this);
     }
 
     @Override
@@ -182,7 +182,7 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         playerController.tick();
         ticksOfInvuln--;
-        craftingInventory.broadcastChanges();
+        containerMenu.broadcastChanges();
         for (int i = 0; i < 5; i++)
         {
             ItemStack itemstack = getEquipmentInSlot(i);
@@ -295,7 +295,7 @@ public class PlayerServer extends Player implements ContainerListener {
             boolean driftAllowed = mcServer.propertyManager.getBooleanProperty("allow-drift", false);
             if ((netherAllowed && targetDim == Dimension.NETHER) || (driftAllowed && targetDim == Dimension.DRIFT) || (targetDim != Dimension.NETHER && targetDim != Dimension.DRIFT))
             {
-                if (craftingInventory != inventorySlots)
+                if (containerMenu != inventoryMenu)
                 {
                     usePersonalCraftingInventory();
                 }
@@ -410,7 +410,7 @@ public class PlayerServer extends Player implements ContainerListener {
             }
         }
         super.onItemPickup(entity, item);
-        craftingInventory.broadcastChanges();
+        containerMenu.broadcastChanges();
     }
 
     @Override
@@ -494,10 +494,10 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketContainerOpen(currentWindowId, PacketContainerOpen.TYPE_CRAFTING, "Crafting", 9));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuCrafting(inventory, world, tilePos);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuCrafting(inventory, world, tilePos);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     @Override
@@ -511,10 +511,10 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketContainerOpen(currentWindowId, PacketContainerOpen.TYPE_GENERIC_CONTAINER, container.getNameTranslationKey(), container.getContainerSize()));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuContainer(inventory, container);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuContainer(inventory, container);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     public void displayChestScreen(Container container, double x, double y, double z) {
@@ -527,20 +527,20 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketContainerOpen(currentWindowId, PacketContainerOpen.TYPE_FURNACE, tileEntity.getNameTranslationKey(), tileEntity.getContainerSize()));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuFurnace(inventory, tileEntity);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuFurnace(inventory, tileEntity);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     @Override
     public void displayBlastFurnaceScreen(final TileEntityFurnaceBlast tileEntity) {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketContainerOpen(currentWindowId, PacketContainerOpen.TYPE_BLAST_FURNACE, tileEntity.getNameTranslationKey(), tileEntity.getContainerSize()));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuFurnaceBlast(inventory, tileEntity);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuFurnaceBlast(inventory, tileEntity);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     @Override
@@ -548,10 +548,10 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketContainerOpen(currentWindowId, PacketContainerOpen.TYPE_DISPENSER, tileEntity.getNameTranslationKey(), tileEntity.getContainerSize()));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuTrap(inventory, tileEntity);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuTrap(inventory, tileEntity);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     @Override
@@ -559,10 +559,10 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketContainerOpen(currentWindowId, PacketContainerOpen.TYPE_ACTIVATOR, tileEntity.getNameTranslationKey(), tileEntity.getContainerSize()));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuActivator(inventory, tileEntity);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuActivator(inventory, tileEntity);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
 
@@ -571,10 +571,10 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketContainerOpen(currentWindowId, PacketContainerOpen.TYPE_TROMMEL, tileEntity.getNameTranslationKey(), tileEntity.getContainerSize()));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuTrommel(inventory, tileEntity);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuTrommel(inventory, tileEntity);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     @Override
@@ -582,20 +582,20 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         getNextWindowId();
         playerNetServerHandler.sendPacket(new PacketFlagOpen(currentWindowId, tileEntity.x, tileEntity.y, tileEntity.z));
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuFlag(inventory, tileEntity);
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuFlag(inventory, tileEntity);
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     public void displayGUIGuidebook()
     {
         getNextWindowId();
 
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = new MenuGuidebook();
-        craftingInventory.containerId = currentWindowId;
-        craftingInventory.addSlotListener(this);
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = new MenuGuidebook();
+        containerMenu.containerId = currentWindowId;
+        containerMenu.addSlotListener(this);
     }
 
     @Override
@@ -644,7 +644,7 @@ public class PlayerServer extends Player implements ContainerListener {
 
     public void usePersonalCraftingInventory()
     {
-        playerNetServerHandler.sendPacket(new PacketContainerClose(craftingInventory.containerId));
+        playerNetServerHandler.sendPacket(new PacketContainerClose(containerMenu.containerId));
         closeCraftingGui();
     }
 
@@ -663,8 +663,8 @@ public class PlayerServer extends Player implements ContainerListener {
 
     public void closeCraftingGui()
     {
-        craftingInventory.onCraftGuiClosed(this);
-        craftingInventory = inventorySlots;
+        containerMenu.onCraftGuiClosed(this);
+        containerMenu = inventoryMenu;
     }
 
     public void setMovementType(float f, float f1, boolean flag, boolean flag1, float f2, float f3)
diff --git a/game/server/src/main/java/net/minecraft/server/net/PlayerList.java b/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
index bff3c0516..8a6a5ab67 100644
--- a/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
+++ b/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
@@ -699,7 +699,7 @@ public class PlayerList
 
     public void initializePlayerObject(PlayerServer player)
     {
-        player.initializeCraftingInventory(player.inventorySlots);
+        player.initializeCraftingInventory(player.inventoryMenu);
         player.initializeLastFieldValues();
     }
 
diff --git a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
index e9ffef8a7..eb32ab9fc 100644
--- a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
@@ -432,15 +432,15 @@ public class PacketHandlerServer extends PacketHandler
         }
         this.playerEntity.isChangingQuantityOnly = true;
         this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.getCurrentSlot()] = ItemStack.copyItemStack(this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.getCurrentSlot()]);
-        Slot slot = this.playerEntity.craftingInventory.getSlotFor(this.playerEntity.inventory, this.playerEntity.inventory.getCurrentSlot());
-        this.playerEntity.craftingInventory.broadcastChanges();
+        Slot slot = this.playerEntity.containerMenu.getSlotFor(this.playerEntity.inventory, this.playerEntity.inventory.getCurrentSlot());
+        this.playerEntity.containerMenu.broadcastChanges();
         this.playerEntity.isChangingQuantityOnly = false;
         if (slot == null) {
-            LOGGER.warn("Couldn't find slot for index '{}' in {}'s inventory while they were in the {} container!", this.playerEntity.inventory.getCurrentSlot(), this.playerEntity.username, this.playerEntity.craftingInventory.getClass().getSimpleName());
+            LOGGER.warn("Couldn't find slot for index '{}' in {}'s inventory while they were in the {} container!", this.playerEntity.inventory.getCurrentSlot(), this.playerEntity.username, this.playerEntity.containerMenu.getClass().getSimpleName());
             return;
         }
         if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), packet.itemStack)) {
-            sendPacket(new PacketContainerSetSlot(this.playerEntity.craftingInventory.containerId, slot.index, this.playerEntity.inventory.getCurrentItem()));
+            sendPacket(new PacketContainerSetSlot(this.playerEntity.containerMenu.containerId, slot.index, this.playerEntity.inventory.getCurrentItem()));
         }
     }
 
@@ -635,33 +635,33 @@ public class PacketHandlerServer extends PacketHandler
 
     @Override
     public void handleContainerClick(@NotNull PacketContainerClick packetContainerClick) {
-        if (this.playerEntity.craftingInventory.containerId == packetContainerClick.window_Id && this.playerEntity.craftingInventory.isSynched(this.playerEntity)) {
-            ItemStack itemstack = this.playerEntity.craftingInventory.clicked(packetContainerClick.action, packetContainerClick.args, this.playerEntity);
+        if (this.playerEntity.containerMenu.containerId == packetContainerClick.window_Id && this.playerEntity.containerMenu.isSynched(this.playerEntity)) {
+            ItemStack itemstack = this.playerEntity.containerMenu.clicked(packetContainerClick.action, packetContainerClick.args, this.playerEntity);
             if (ItemStack.areItemStacksEqual(packetContainerClick.itemStack, itemstack)) {
                 this.playerEntity.playerNetServerHandler.sendPacket(new PacketContainerAck(packetContainerClick.window_Id, packetContainerClick.actionId, true));
                 this.playerEntity.isChangingQuantityOnly = true;
-                this.playerEntity.craftingInventory.broadcastChanges();
+                this.playerEntity.containerMenu.broadcastChanges();
                 this.playerEntity.updateHeldItem();
                 this.playerEntity.isChangingQuantityOnly = false;
             } else {
-                this.guiIdMap.put(this.playerEntity.craftingInventory.containerId, packetContainerClick.actionId);
+                this.guiIdMap.put(this.playerEntity.containerMenu.containerId, packetContainerClick.actionId);
                 this.playerEntity.playerNetServerHandler.sendPacket(new PacketContainerAck(packetContainerClick.window_Id, packetContainerClick.actionId, false));
-                this.playerEntity.craftingInventory.setSynched(this.playerEntity, false);
+                this.playerEntity.containerMenu.setSynched(this.playerEntity, false);
                 ArrayList<ItemStack> arraylist = new ArrayList<>();
-                for (int i = 0; i < this.playerEntity.craftingInventory.slots.size(); i++) {
-                    arraylist.add(this.playerEntity.craftingInventory.slots.get(i).getItemStack());
+                for (int i = 0; i < this.playerEntity.containerMenu.slots.size(); i++) {
+                    arraylist.add(this.playerEntity.containerMenu.slots.get(i).getItemStack());
                 }
 
-                this.playerEntity.updateCraftingInventory(this.playerEntity.craftingInventory, arraylist);
+                this.playerEntity.updateCraftingInventory(this.playerEntity.containerMenu, arraylist);
             }
         }
     }
 
     @Override
     public void handleContainerAck(@NotNull PacketContainerAck packet) {
-        short short1 = this.guiIdMap.get(this.playerEntity.craftingInventory.containerId);
-        if (packet.shortWindowId == short1 && this.playerEntity.craftingInventory.containerId == packet.windowId && !this.playerEntity.craftingInventory.isSynched(this.playerEntity)) {
-            this.playerEntity.craftingInventory.setSynched(this.playerEntity, true);
+        short short1 = this.guiIdMap.get(this.playerEntity.containerMenu.containerId);
+        if (packet.shortWindowId == short1 && this.playerEntity.containerMenu.containerId == packet.windowId && !this.playerEntity.containerMenu.isSynched(this.playerEntity)) {
+            this.playerEntity.containerMenu.setSynched(this.playerEntity, true);
         }
     }
 
@@ -712,8 +712,8 @@ public class PacketHandlerServer extends PacketHandler
 
     @Override
     public void handleUpdateCreativeInventory(@NotNull PacketUpdateCreativeInventory packet) {
-        if (this.playerEntity.craftingInventory.containerId == packet.windowId && this.playerEntity.craftingInventory instanceof MenuInventoryCreative) {
-            ((MenuInventoryCreative) this.playerEntity.craftingInventory).setInventoryStatus(packet.page, packet.searchText);
+        if (this.playerEntity.containerMenu.containerId == packet.windowId && this.playerEntity.containerMenu instanceof MenuInventoryCreative) {
+            ((MenuInventoryCreative) this.playerEntity.containerMenu).setInventoryStatus(packet.page, packet.searchText);
         }
     }
 
@@ -748,7 +748,7 @@ public class PacketHandlerServer extends PacketHandler
                 this.playerEntity.placementModeOverride = PlacementMode.get(packetCustomPayload.data[3]);
             }
         } else if (PacketCustomPayload.CHANNEL_FLAG.equals(packetCustomPayload.channel)) {
-            if (packetCustomPayload.data.length == 1 + (TileEntityFlag.CANVAS_WIDTH * TileEntityFlag.CANVAS_HEIGHT) && this.playerEntity.craftingInventory instanceof MenuFlag menuFlag) {
+            if (packetCustomPayload.data.length == 1 + (TileEntityFlag.CANVAS_WIDTH * TileEntityFlag.CANVAS_HEIGHT) && this.playerEntity.containerMenu instanceof MenuFlag menuFlag) {
                 TileEntityFlag flag = menuFlag.flag;
 
                 if (flag.owner == null || flag.owner.equals(this.playerEntity.uuid)) {
