diff --git a/.gitignore b/.gitignore
index ec4326404..48e2fc369 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ BiomeLookup.png
 version.txt
 log4j.properties
 /generated/
+/game/client/out/
diff --git a/game/client/build.gradle.kts b/game/client/build.gradle.kts
index 79643b5ff..585899a05 100644
--- a/game/client/build.gradle.kts
+++ b/game/client/build.gradle.kts
@@ -350,7 +350,7 @@ tasks.withType(JavaCompile::class.java) {
 }
 
 tasks.withType(Jar::class.java) {
-    dependsOn(tasks.test, "testShaders")
+//    dependsOn(tasks.test, "testShaders")
 }
 
 tasks.test {
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 c4d9a4201..1f6cfda0a 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -42,7 +42,6 @@ import net.minecraft.client.world.chunk.provider.ChunkProviderThreadedClient;
 import net.minecraft.client.world.save.SaveHandlerClientSP;
 import net.minecraft.client.net.handler.PacketHandlerClient;
 import net.minecraft.client.render.TileEntityRenderDispatcher;
-import net.minecraft.client.render.block.model.BlockModelGrass;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.font.FontRendererDefault;
 import net.minecraft.client.render.terrain.TerrainRendererMultiDraw;
@@ -85,6 +84,7 @@ import net.minecraft.core.net.command.commands.CommandTestFor;
 import net.minecraft.core.net.command.commands.CommandTime;
 import net.minecraft.core.net.command.commands.CommandWeather;
 import net.minecraft.core.net.command.util.CommandHelper;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.pool.ObjectPool;
 import net.minecraft.core.util.helper.Color;
 import net.minecraft.core.util.helper.DyeColor;
@@ -229,11 +229,6 @@ public class Minecraft
     public ParticleEngine particleEngine;
     public Session session;
 
-    public String worldPresetName = null;
-    public String worldPresetSeed = null;
-    public int worldPresetX;
-    public int worldPresetY;
-    public int worldPresetZ;
     public String minecraftUri;
     public boolean hideQuitButton;
     public volatile boolean isGamePaused;
@@ -671,13 +666,6 @@ public class Minecraft
             displayScreen(new ScreenBadJavaArch());
         } else if (this.serverName != null) {
             displayScreen(new ScreenConnecting(this, this.serverName, this.serverPort));
-        } else if (this.worldPresetName != null && this.worldPresetSeed != null) {
-            ScreenSelectWorld screenSelectWorld = new ScreenSelectWorld(null);
-            displayScreen(screenSelectWorld);
-            screenSelectWorld.deletePresetWorld(this.worldPresetName);
-            ScreenCreateWorld screen = new ScreenCreateWorld(null);
-            displayScreen(screen);
-            screen.runPreset(this.worldPresetName, this.worldPresetSeed, this.worldPresetX, this.worldPresetY, this.worldPresetZ);
         } else {
             displayScreen(new ScreenMainMenu());
         }
@@ -995,7 +983,6 @@ public class Minecraft
                     Debug.push("misc");        // 2
 
                     OpenGLHelper.checkError("pre render");
-                    BlockModelGrass.fancyGrass = this.gameSettings.fancyGraphics.value == 1;
                     EntityItem.enableItemClumping = this.gameSettings.enableItemClumping.value;
                     BlockLogicLeavesBase.enableTreeShadowing = this.gameSettings.treeShadows.value;
                     this.sndManager.updateListener(this.thePlayer, this.timer.partialTicks);
@@ -1298,7 +1285,7 @@ public class Minecraft
                         this.playerController.swingItem(true);
                     }
                     if (stack.stackSize <= 0) {
-                        this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.getCurrentItemIndex()] = null;
+                        this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.getCurrentSlot()] = null;
                     } else if (stack.stackSize != numItemsInStack) {
                         this.worldRenderer.itemRenderer.updateEquippedItem();
                     }
@@ -1348,7 +1335,7 @@ public class Minecraft
                     return;
                 }
                 if (stack.stackSize <= 0) {
-                    this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.getCurrentItemIndex()] = null;
+                    this.thePlayer.inventory.mainInventory[this.thePlayer.inventory.getCurrentSlot()] = null;
                 } else if (stack.stackSize != numItemsInStack) {
                     this.worldRenderer.itemRenderer.resetEquippedProgress();
                 }
@@ -1474,7 +1461,7 @@ public class Minecraft
                             this.thePlayer.setFlySpeed(newSpeed);
                             this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.flightSpeed);
                         } else if (!this.gameSettings.keyZoom.isPressed()) {
-                            this.thePlayer.inventory.changeCurrentItem(scrollDelta);
+                            this.thePlayer.inventory.changeCurrentSlot(scrollDelta);
                         }
                     }
                     if (!this.inGameHasFocus && Mouse.getEventButtonState()) {
@@ -1546,7 +1533,7 @@ public class Minecraft
                                 forceReload();
                             } else if (this.gameSettings.keySwitchGamemode.isPressEvent()) {
                                 if (this.currentWorld.getLevelData().getCheatsEnabled() || this.currentWorld.isClientSide) {
-                                    if (this.thePlayer.getGamemode() == Gamemode.creative) {
+                                    if (this.thePlayer.getGamemode() == Gamemodes.CREATIVE) {
                                         this.thePlayer.sendChatMessage("/gamemode 0");
                                     } else {
                                         this.thePlayer.sendChatMessage("/gamemode 1");
@@ -1804,7 +1791,7 @@ public class Minecraft
         }
 
         // Fly
-        if (this.thePlayer.getGamemode().canPlayerFly() && this.gameSettings.keyFly.isPressEvent(currentInputDevice)) {
+        if (this.thePlayer.getGamemode().hasPlayerFlight() && this.gameSettings.keyFly.isPressEvent(currentInputDevice)) {
             if (!this.toggleFlyPressed) this.toggleFlyPressed = true;
             this.flyPressedTime = System.currentTimeMillis();
             return true;
@@ -1812,7 +1799,7 @@ public class Minecraft
 
         // Hotbar switch
         if (this.gameSettings.keyHotBarSwitch.isPressEvent(currentInputDevice)) {
-            if (!this.thePlayer.inventory.currentItemLocked()) {
+            if (!this.thePlayer.inventory.currentSlotLocked()) {
                 if (shift) {
                     this.thePlayer.setHotbarOffset((this.thePlayer.inventory.getHotbarOffset() + 27) % (36));
                     this.hotbarSwapAnimationProgress = -HOTBAR_SWAP_ANIMATION_LENGTH_TICKS;
@@ -1820,7 +1807,7 @@ public class Minecraft
                     this.thePlayer.setHotbarOffset((this.thePlayer.inventory.getHotbarOffset() + 9) % (36));
                     this.hotbarSwapAnimationProgress = HOTBAR_SWAP_ANIMATION_LENGTH_TICKS;
                 }
-                this.thePlayer.inventory.changeCurrentItem(0);
+                this.thePlayer.inventory.changeCurrentSlot(0);
             }
             return true;
         }
@@ -1898,13 +1885,13 @@ public class Minecraft
 
         // Hotbar left
         if (this.gameSettings.keyHotBarLeft.isPressEvent(currentInputDevice)) {
-            this.thePlayer.inventory.changeCurrentItem(1);
+            this.thePlayer.inventory.changeCurrentSlot(1);
             return true;
         }
 
         // Hotbar right
         if (this.gameSettings.keyHotBarRight.isPressEvent(currentInputDevice)) {
-            this.thePlayer.inventory.changeCurrentItem(-1);
+            this.thePlayer.inventory.changeCurrentSlot(-1);
             return true;
         }
 
@@ -1922,7 +1909,7 @@ public class Minecraft
         };
         for (int i = 0; i < hotbarSlots.length; i++) {
             if (hotbarSlots[i].isPressEvent(currentInputDevice)) {
-                this.thePlayer.inventory.setCurrentItemIndex(i + this.thePlayer.inventory.getHotbarOffset(), false);
+                this.thePlayer.inventory.setCurrentSlot(i + this.thePlayer.inventory.getHotbarOffset(), false);
                 return true;
             }
         }
@@ -1952,7 +1939,7 @@ public class Minecraft
     }
 
     private ScreenInventory getInventoryScreen() {
-        if (this.thePlayer.getGamemode() == Gamemode.creative) {
+        if (this.thePlayer.getGamemode() == Gamemodes.CREATIVE) {
             return new ScreenInventoryCreative(this.thePlayer);
         } else {
             return new ScreenInventory(this.thePlayer);
@@ -2001,27 +1988,27 @@ public class Minecraft
                 displayScreen(new ScreenPause());
             }
             if (controller.digitalPad.up.pressedThisFrame()) {
-                if (!this.thePlayer.inventory.currentItemLocked()) {
+                if (!this.thePlayer.inventory.currentSlotLocked()) {
                     this.thePlayer.setHotbarOffset((this.thePlayer.inventory.getHotbarOffset() + 27) % (36));
                     this.hotbarSwapAnimationProgress = -HOTBAR_SWAP_ANIMATION_LENGTH_TICKS;
-                    this.thePlayer.inventory.changeCurrentItem(0);
+                    this.thePlayer.inventory.changeCurrentSlot(0);
                 }
             }
             if (controller.digitalPad.down.pressedThisFrame()) {
-                if (!this.thePlayer.inventory.currentItemLocked()) {
+                if (!this.thePlayer.inventory.currentSlotLocked()) {
                     this.thePlayer.setHotbarOffset((this.thePlayer.inventory.getHotbarOffset() + 9) % (36));
                     this.hotbarSwapAnimationProgress = HOTBAR_SWAP_ANIMATION_LENGTH_TICKS;
-                    this.thePlayer.inventory.changeCurrentItem(0);
+                    this.thePlayer.inventory.changeCurrentSlot(0);
                 }
             }
-            if (controller.digitalPad.left.pressedThisFrame() && this.thePlayer.getGamemode().canPlayerFly()) {
+            if (controller.digitalPad.left.pressedThisFrame() && this.thePlayer.getGamemode().hasPlayerFlight()) {
                 this.thePlayer.setNoclip(!this.thePlayer.noPhysics);
             }
             if (controller.buttonLeftShoulder.pressedThisFrame()) {
-                this.thePlayer.inventory.changeCurrentItem(1);
+                this.thePlayer.inventory.changeCurrentSlot(1);
             }
             if (controller.buttonRightShoulder.pressedThisFrame()) {
-                this.thePlayer.inventory.changeCurrentItem(-1);
+                this.thePlayer.inventory.changeCurrentSlot(-1);
             }
             if (controller.joyLeft.getButton().pressedThisFrame()) {
                 this.gameSettings.thirdPersonView.value++;
@@ -2086,7 +2073,7 @@ public class Minecraft
         changeWorld(world, I18n.getInstance().translateKey("gui.loading.label.generating"));
 
         this.thePlayer.setGamemode(worldConfiguration.getGamemode());
-        if (worldConfiguration.getGamemode() == Gamemode.adventure) {
+        if (worldConfiguration.getGamemode() == Gamemodes.ADVENTURE) {
             this.thePlayer.inventory.insertItem(Items.TOOL_AXE_WOOD.getDefaultStack(), true);
         }
     }
@@ -2387,7 +2374,7 @@ public class Minecraft
         this.currentWorld.getRespawnLocation();
         this.currentWorld.updateEntityList();
         int j = 0;
-        Gamemode playerGamemode = Gamemode.survival;
+        Gamemode playerGamemode = Gamemodes.SURVIVAL;
         if (this.thePlayer != null) {
             j = this.thePlayer.id;
             this.currentWorld.setEntityDead(this.thePlayer);
@@ -2398,7 +2385,7 @@ public class Minecraft
         this.thePlayer.setGamemode(playerGamemode);
         if (previousPlayer != null && previousPlayer.getHeldObject() != null) {
             this.thePlayer.setHeldObject(previousPlayer.getHeldObject());
-            this.thePlayer.inventory.setCurrentItemIndex(previousPlayer.inventory.getCurrentItemIndex(), true);
+            this.thePlayer.inventory.setCurrentSlot(previousPlayer.inventory.getCurrentSlot(), true);
             this.thePlayer.inventory.setHotbarOffset(previousPlayer.inventory.getHotbarOffset(), true);
         }
         this.activeCamera = new EntityCameraFirstPerson(this, this.thePlayer);
@@ -2648,7 +2635,7 @@ public class Minecraft
     }
 
     public boolean canRenderEntityLabel() {
-        return isDebugInfoEnabled() && this.thePlayer != null && this.thePlayer.getGamemode() == Gamemode.creative;
+        return isDebugInfoEnabled() && this.thePlayer != null && this.thePlayer.getGamemode() == Gamemodes.CREATIVE;
     }
 
     public float getOutlineWidth() {
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 3acee0969..522cbf632 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
@@ -102,16 +102,16 @@ public class PlayerLocal extends Player {
     public void setGamemode(Gamemode gamemode) {
         this.gamemode = gamemode;
 
-        MenuInventory newContainer = gamemode.getContainer(this.inventory, !this.world.isClientSide);
+        MenuInventory newContainer = gamemode.getInventoryMenu(this.inventory);
         if (this.craftingInventory == this.inventorySlots) {
             this.craftingInventory = newContainer;
         }
         this.inventorySlots = newContainer;
-        if (!gamemode.canPlayerFly()) {
+        if (!gamemode.hasPlayerFlight()) {
             this.noPhysics = false;
         }
 
-        this.fireImmune = gamemode.isImmuneToFire();
+        this.fireImmune = gamemode.hasFireImmunity();
     }
 
     @Override
@@ -147,7 +147,7 @@ public class PlayerLocal extends Player {
                 this.mc.sndManager.playSound("portal.trigger", SoundCategory.WORLD_SOUNDS, 1.0F, this.random.nextFloat() * 0.4F + 0.8F);
             }
             this.timeInPortal += 0.0125F;
-            if (this.timeInPortal >= 1.0F || getGamemode().instantPortalTravel()) {
+            if (this.timeInPortal >= 1.0F || getGamemode().hasInstantPortalTravel()) {
                 this.timeInPortal = 1.0F;
                 if (!this.world.isClientSide) {
                     this.timeUntilPortal = 10;
@@ -315,7 +315,7 @@ public class PlayerLocal extends Player {
     }
 
     public int getPlayerProtectionAmount() {
-        return this.inventory.getTotalArmourPoints();
+        return this.inventory.getTotalArmorPoints();
     }
 
     public void sendChatMessage(String s) {
diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerRemote.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerRemote.java
index b9d846ee7..e13fb7229 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerRemote.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerRemote.java
@@ -126,7 +126,7 @@ public class PlayerRemote extends Player
         }
         if(slot == 0)
         {
-            inventory.mainInventory[inventory.getCurrentItemIndex()] = itemstack;
+            inventory.mainInventory[inventory.getCurrentSlot()] = itemstack;
         } else
         {
             inventory.armorInventory[slot - 1] = itemstack;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java b/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java
index 92f4bf44c..9f445687c 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java
@@ -34,7 +34,7 @@ public class HeldItemTooltipElement extends Gui {
 			ItemStack item = mc.thePlayer.getCurrentEquippedItem();
 			
 			int id = getItemID(item);
-			int i = mc.thePlayer.inventory.getCurrentItemIndex();
+			int i = mc.thePlayer.inventory.getCurrentSlot();
 			
 			if(id != this.lastItemID || i != this.lastSelectedItem) {
 				updateString(item);
@@ -53,7 +53,7 @@ public class HeldItemTooltipElement extends Gui {
 			ItemStack item = mc.thePlayer.getCurrentEquippedItem();
 
 			int id = getItemID(item);
-			int i = mc.thePlayer.inventory.getCurrentItemIndex();
+			int i = mc.thePlayer.inventory.getCurrentSlot();
 
 			if(id != this.lastItemID || i != this.lastSelectedItem) {
 				updateString(item);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java
index 317689809..b438c7791 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenCreateWorld.java
@@ -1,24 +1,24 @@
 package net.minecraft.client.gui;
 
-import net.minecraft.client.gui.popup.PopupScreen;
-import net.minecraft.client.gui.popup.PopupBuilder;
 import net.minecraft.client.gui.worldsettings.ScreenWorldSettings;
-import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.lang.I18n;
-import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.player.gamemode.Gamemode;
-import net.minecraft.core.world.Dimension;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.world.settings.WorldConfiguration;
-import net.minecraft.core.world.type.WorldTypeGroups;
 import org.jetbrains.annotations.NotNull;
 import org.lwjgl.input.Keyboard;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class ScreenCreateWorld extends Screen {
-    private int overrideSpawnX;
-    private int overrideSpawnY;
-    private int overrideSpawnZ;
+    public static final @NotNull List<@NotNull Gamemode> GAMEMODES = new ArrayList<>();
+    static {
+        GAMEMODES.add(Gamemodes.SURVIVAL);
+        GAMEMODES.add(Gamemodes.CREATIVE);
+        GAMEMODES.add(Gamemodes.HARDCORE);
+        GAMEMODES.add(Gamemodes.ADVENTURE);
+    }
     private TextFieldElement textboxWorldName;
     private TextFieldElement textboxSeed;
     private ButtonElement createWorldButton;
@@ -86,9 +86,8 @@ public class ScreenCreateWorld extends Screen {
 
             this.mc.displayScreen(null);
         } else if (button == this.gamemodeButton) {
-            List<Gamemode> gamemodeList = Gamemode.getPublicGamemodes();
-            this.worldConfiguration.setGamemode(gamemodeList.get((gamemodeList.indexOf(this.worldConfiguration.getGamemode()) + 1) % gamemodeList.size()));
-            this.worldConfiguration.setCheatsEnabled(this.worldConfiguration.getGamemode() == Gamemode.creative);
+            this.worldConfiguration.setGamemode(GAMEMODES.get((GAMEMODES.indexOf(this.worldConfiguration.getGamemode()) + 1) % GAMEMODES.size()));
+            this.worldConfiguration.setCheatsEnabled(this.worldConfiguration.getGamemode() == Gamemodes.CREATIVE);
             syncButtons();
         } else if (button == this.cheatsButton) {
             this.worldConfiguration.setCheatsEnabled(!this.worldConfiguration.getCheatsEnabled());
@@ -165,14 +164,4 @@ public class ScreenCreateWorld extends Screen {
             this.textboxSeed.setFocused(false);
         }
     }
-
-    public void runPreset(String name, String seed, int spawnX, int spawnY, int spawnZ) {
-        this.overrideSpawnX = spawnX;
-        this.overrideSpawnY = spawnY;
-        this.overrideSpawnZ = spawnZ;
-        this.worldConfiguration.setWorldName(name);
-        this.worldConfiguration.setStringSeed(seed);
-        this.worldConfiguration.setGamemode(Gamemode.creative);
-        buttonClicked(this.createWorldButton);
-    }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenGameOver.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenGameOver.java
index 7713cee48..bcc8910ef 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenGameOver.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenGameOver.java
@@ -4,7 +4,7 @@ import net.minecraft.client.entity.player.PlayerLocalMultiplayer;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.packet.PacketKeepAlive;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import org.jetbrains.annotations.NotNull;
 
 import net.minecraft.core.net.command.TextFormatting;
@@ -27,7 +27,7 @@ public class ScreenGameOver extends Screen {
     public void init() {
         I18n i18n = I18n.getInstance();
         this.buttons.clear();
-        String respawnKey = (this.mc.thePlayer.getGamemode() == Gamemode.hardcore || this.mc.thePlayer.getGamemode() == Gamemode.spectator) ? "gui.game_over.button.respawn.spectator" : "gui.game_over.button.respawn";
+        String respawnKey = (this.mc.thePlayer.getGamemode() == Gamemodes.HARDCORE || this.mc.thePlayer.getGamemode() == Gamemodes.SPECTATOR) ? "gui.game_over.button.respawn.spectator" : "gui.game_over.button.respawn";
         this.buttons.add(new ButtonElement(1, this.width / 2 - 100, this.height / 4 + 72, i18n.translateKey(respawnKey)));
         this.buttons.add(new ButtonElement(2, this.width / 2 - 100, this.height / 4 + 96, i18n.translateKey("gui.game_over.button.title_screen")));
         if (this.mc.session == null) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java
index 2f3353b6e..be2276fa4 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenSelectWorld.java
@@ -1,12 +1,17 @@
 package net.minecraft.client.gui;
 
 import com.mojang.nbt.tags.CompoundTag;
+import com.mojang.nbt.tags.IntTag;
+import com.mojang.nbt.tags.StringTag;
+import com.mojang.nbt.tags.Tag;
 import net.minecraft.client.gui.popup.PopupScreen;
 import net.minecraft.client.gui.popup.PopupBuilder;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.core.Global;
+import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.world.save.DimensionData;
 import net.minecraft.core.world.save.ISaveFormat;
 import net.minecraft.core.util.helper.MathHelper;
@@ -293,11 +298,19 @@ public class ScreenSelectWorld extends Screen {
             SaveFile saveFile = ScreenSelectWorld.this.saveList.get(index);
 
             CompoundTag userTag = ScreenSelectWorld.this.userTags.get(saveFile);
-            Gamemode gamemode;
+            Gamemode gamemode = null;
             if (userTag != null) {
-                gamemode = Gamemode.gamemodesList[userTag.getInteger("Gamemode")];
-            } else {
-                gamemode = Gamemode.survival;
+                final @Nullable Tag<?> gamemodeTag = userTag.getTag("Gamemode");
+                if (gamemodeTag != null) {
+                    if (gamemodeTag instanceof final @NotNull StringTag stringTag) {
+                        gamemode = Registries.GAMEMODES.getItem(stringTag.getValue());
+                    } else if (gamemodeTag instanceof final @NotNull IntTag intTag) {
+                        gamemode = Gamemodes.getGamemodeByLegacyId(intTag.getValue());
+                    }
+                }
+            }
+            if (gamemode == null) {
+                gamemode = Gamemodes.SURVIVAL;
             }
 
             final String saveName = saveFile.getDisplayName();
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 a238adc9a..4884fd5f0 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
@@ -258,7 +258,7 @@ public abstract class ScreenContainerAbstract extends Screen {
 
     @Override
     public void mouseClicked(final int mx, final int my, int buttonNum) {
-        if (!this.mc.thePlayer.getGamemode().consumeBlocks()) {
+        if (!this.mc.thePlayer.getGamemode().hasBlockConsumption()) {
             // Duplicate items with middle mouse button
             if (buttonNum == 2) {
                 Slot slot = this.inventorySlots.getSlot(getSlotId(mx, my));
@@ -309,7 +309,7 @@ public abstract class ScreenContainerAbstract extends Screen {
             return;
         }
 
-        if (!this.mc.thePlayer.getGamemode().consumeBlocks()) {
+        if (!this.mc.thePlayer.getGamemode().hasBlockConsumption()) {
             // Duplicate items with middle mouse button
             if (mouseButton == 2) {
                 Slot slot = this.inventorySlots.getSlot(slotId);
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 00e62e2f1..eeec84b0b 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
@@ -19,9 +19,9 @@ import net.minecraft.core.lang.I18n;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.client.option.GameSettings;
-import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.EntityRendererDispatcher;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import org.jetbrains.annotations.NotNull;
 
 import net.minecraft.core.util.helper.Color;
@@ -86,7 +86,7 @@ public class ScreenInventory extends ScreenContainerAbstract {
         boolean compass = false;
         boolean rotaryCalendar = false;
 
-        if (this.mc.thePlayer.getGamemode() == Gamemode.creative) {
+        if (this.mc.thePlayer.getGamemode() == Gamemodes.CREATIVE) {
             clock = true;
             compass = true;
             rotaryCalendar = true;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java
index 279951503..5775a1cb2 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java
@@ -10,7 +10,7 @@ import net.minecraft.core.data.registry.recipe.RecipeSymbol;
 import net.minecraft.core.data.registry.recipe.entry.RecipeEntryTrommel;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.player.inventory.slot.Slot;
 import org.jetbrains.annotations.Nullable;
 
@@ -121,7 +121,7 @@ public class SlotGuidebook extends Slot
 			Minecraft mc = Minecraft.getMinecraft();
 			if (!mc.gameSettings.hideUndiscoveredItems.value) return true;
 		}
-		return player.getStat(item.getItem().getStat(StatList.STAT_PICKED_UP)) > 0 || player.getGamemode() == Gamemode.creative;
+		return player.getStat(item.getItem().getStat(StatList.STAT_PICKED_UP)) > 0 || player.getGamemode() == Gamemodes.CREATIVE;
 	}
 
 	public void scrollRecipe(){
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
index f9d5ccfa4..fbe0adaa0 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
@@ -20,7 +20,7 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.lang.I18n;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.player.inventory.slot.Slot;
 import net.minecraft.client.gui.guidebook.SlotGuidebook;
 import net.minecraft.core.util.helper.MathHelper;
@@ -109,7 +109,7 @@ public class GuidebookPageMob
     protected void renderForeground(TextureManager re, FontRenderer sr, int x, int y, int mouseX, int mouseY, float partialTicks) {
         EntityDispatcher.EntityDispatcherEntry<?> entry = EntityDispatcher.getInstance().entryForClass(this.mobClass);
         this.discovered = mc.statsCounter.readStat(StatList.mobEncounterStats.get(entry != null ? entry.namespaceID : null)) > 0;
-        if (mc.thePlayer.getGamemode() == Gamemode.creative || !mc.gameSettings.hideUndiscoveredItems.value)
+        if (mc.thePlayer.getGamemode() == Gamemodes.CREATIVE || !mc.gameSettings.hideUndiscoveredItems.value)
             this.discovered = true;
 
         Lighting.disable();
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java
index 75bb57e40..20ab809d3 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookSectionMob.java
@@ -6,13 +6,12 @@ import net.minecraft.client.gui.guidebook.GuidebookSection;
 import net.minecraft.client.gui.guidebook.SearchableGuidebookSection;
 import net.minecraft.core.data.registry.recipe.SearchQuery;
 import net.minecraft.core.achievement.stat.StatList;
-import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.lang.I18n;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.collection.Pair;
 
 import java.util.ArrayList;
@@ -91,7 +90,7 @@ public class GuidebookSectionMob
         	Minecraft mc = Minecraft.getMinecraft();
             EntityDispatcher.EntityDispatcherEntry<?> entry = EntityDispatcher.getInstance().entryForClass(mobInfo.getEntityClass());
             boolean discovered = mc.statsCounter.readStat(StatList.mobEncounterStats.get(entry != null ? entry.namespaceID : null)) > 0;
-            if (mc.thePlayer.getGamemode() == Gamemode.creative) discovered = true;
+            if (mc.thePlayer.getGamemode() == Gamemodes.CREATIVE) discovered = true;
 
             if (discovered) {
                 return I18n.getInstance().translateKey(mobInfo.getNameTranslationKey());
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 c648dd819..4de644106 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
@@ -23,6 +23,7 @@ import net.minecraft.client.render.renderer.State;
 import net.minecraft.core.block.BlockLogicPortal;
 import net.minecraft.core.enums.ChatVisibility;
 import net.minecraft.core.enums.HumanArmorShape;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.phys.HitResult;
 import org.jetbrains.annotations.NotNull;
@@ -51,7 +52,6 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.ChatLine;
 import net.minecraft.core.net.command.TextFormatting;
-import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.season.Season;
@@ -146,7 +146,7 @@ public class HudIngame extends Gui {
             boolean compass = false;
             boolean rotaryCalendar = false;
 
-            if (this.mc.thePlayer.getGamemode() == Gamemode.creative) {
+            if (this.mc.thePlayer.getGamemode() == Gamemodes.CREATIVE) {
                 clock = true;
                 compass = true;
                 rotaryCalendar = true;
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 9b49a334d..4b0dd4956 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
@@ -99,7 +99,7 @@ public class HudIngameDoom
         int height = this.mc.resolution.getScaledHeightScreenCoords();
 
         Face face = Face.NEUTRAL;
-        if (this.mc.thePlayer.getGamemode().isPlayerInvulnerable()) {
+        if (this.mc.thePlayer.getGamemode().hasInvulnerablePlayer()) {
             face = Face.GOD;
         } else if (this.mc.thePlayer.getHealth() == 0) {
             face = Face.DEAD;
@@ -168,7 +168,7 @@ public class HudIngameDoom
         int height = this.mc.resolution.getScaledHeightScreenCoords();
 
         int i = 1;
-        int activeSlot = this.mc.thePlayer.inventory.getCurrentItemIndex() % 9;
+        int activeSlot = this.mc.thePlayer.inventory.getCurrentSlot() % 9;
         for (int y = 0; y < 2; y++) {
             for (int x = 0; x < 5; x++) {
                 if (i >= 10) continue;
@@ -226,8 +226,8 @@ public class HudIngameDoom
         int width = this.mc.resolution.getScaledWidthScreenCoords();
         int height = this.mc.resolution.getScaledHeightScreenCoords();
 
-        int currentItem = this.mc.thePlayer.inventory.getCurrentItemIndex();
-        int wrappedCurrentItem = this.mc.thePlayer.inventory.getCurrentItemIndex() % 9;
+        int currentItem = this.mc.thePlayer.inventory.getCurrentSlot();
+        int wrappedCurrentItem = this.mc.thePlayer.inventory.getCurrentSlot() % 9;
 
         int offset = 0;
         if (wrappedCurrentItem >= 5) {
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 d1c35f580..99e610a4d 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().isPlayerInvulnerable() && mc.thePlayer.remainingFireTicks > 0;
+        return mc.gameSettings.immersiveMode.drawHotbar() && mc.playerController.canHurtPlayer() && !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 fced9f1d9..72a5641f4 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
@@ -11,7 +11,7 @@ import net.minecraft.core.block.BlockLogicEdible;
 import net.minecraft.core.item.Item;
 import net.minecraft.core.item.ItemFood;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.phys.HitResult;
 
 import java.util.Random;
@@ -26,7 +26,7 @@ public class HudComponentHealthBar
 
     @Override
     public boolean isVisible() {
-        return mc.playerController.canHurtPlayer() && !mc.thePlayer.getGamemode().isPlayerInvulnerable() && mc.gameSettings.immersiveMode.drawHotbar();
+        return mc.playerController.canHurtPlayer() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.gameSettings.immersiveMode.drawHotbar();
     }
 
     @Override
@@ -45,7 +45,7 @@ public class HudComponentHealthBar
         int health = mc.thePlayer.getHealth();
         int prevHealth = mc.thePlayer.prevHealth;
         this.random.setSeed(hud.updateCounter * 0x4c627L);
-        boolean isHardcore = mc.thePlayer.getGamemode() == Gamemode.hardcore;
+        boolean isHardcore = mc.thePlayer.getGamemode() == Gamemodes.HARDCORE;
 
         for (int i = 0; i < 10; i++) {
             int heartOffset = 0;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java
index 95f9bce85..1872d0e93 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java
@@ -134,7 +134,7 @@ public class HudComponentHotbar
         GLRenderer.setColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Reset color
 
         // Render selector
-        hud.drawGuiIcon((x + 4) + (inv.getCurrentItemIndex() % 9) * 20, y - 1, 24, 24, TextureRegistry.getTexture(mc.thePlayer.getHeldObject() == null ? "minecraft:gui/hud/hotbar_selection" : "minecraft:gui/hud/hotbar_selection_locked"));
+        hud.drawGuiIcon((x + 4) + (inv.getCurrentSlot() % 9) * 20, y - 1, 24, 24, TextureRegistry.getTexture(mc.thePlayer.getHeldObject() == null ? "minecraft:gui/hud/hotbar_selection" : "minecraft:gui/hud/hotbar_selection_locked"));
 
         GLRenderer.pushFrame();
         GLRenderer.modelM4f().translate(0, 0, 1f);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
index 8e0adcd7f..aefc6f87c 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
@@ -10,7 +10,7 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.TextFormatting;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.biome.Biomes;
@@ -64,7 +64,7 @@ public class HudComponentInfoOverlay
         boolean compass = false;
         boolean rotaryCalendar = false;
 
-        if (mc.thePlayer.getGamemode() == Gamemode.creative) {
+        if (mc.thePlayer.getGamemode() == Gamemodes.CREATIVE) {
             clock = true;
             compass = true;
             rotaryCalendar = true;
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 88f4f4a44..3fc7f4bec 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().isPlayerInvulnerable() && mc.thePlayer.isUnderLiquid(Materials.WATER);
+        return mc.gameSettings.immersiveMode.drawHotbar() && mc.playerController.canHurtPlayer() && !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 83778423c..44a7a8e58 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
@@ -50,6 +50,7 @@ import net.minecraft.core.net.entity.NetEntityHandler;
 import net.minecraft.core.net.handler.PacketHandler;
 import net.minecraft.core.net.packet.*;
 import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.player.inventory.menu.MenuAbstract;
 import net.minecraft.core.player.inventory.container.ContainerSimple;
 import net.minecraft.core.sound.SoundTypes;
@@ -69,6 +70,7 @@ import net.minecraft.core.world.saveddata.SavedDataStorage;
 import net.minecraft.core.world.weather.Weather;
 import net.minecraft.core.world.weather.Weathers;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
 import java.io.BufferedReader;
@@ -78,10 +80,7 @@ import java.net.InetAddress;
 import java.net.Socket;
 import java.net.URL;
 import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
 
 public class PacketHandlerClient extends PacketHandler
 {
@@ -340,20 +339,18 @@ public class PacketHandlerClient extends PacketHandler
         final int itemId = packetAddPlayer.currentItem;
         if (itemId == 0)
         {
-            playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentItemIndex()] = null;
+            playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentSlot()] = null;
         }
         else
         {
-            playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentItemIndex()] = new ItemStack(itemId, 1, 0);
+            playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentSlot()] = new ItemStack(itemId, 1, 0);
         }
         playerRemote.absMoveTo(x, y, z, yRot, xRot);
         this.worldClientMP.addEntityToWorld(packetAddPlayer.entityId, playerRemote);
         playerRemote.nickname = StringUtils.substring(packetAddPlayer.nickname, 0, 32);
         playerRemote.chatColor = packetAddPlayer.chatColor;
-        if (packetAddPlayer.gamemode >= 0 && packetAddPlayer.gamemode < Gamemode.gamemodesList.length) {
-            playerRemote.setGamemode(Gamemode.gamemodesList[packetAddPlayer.gamemode]);
-        }
-
+        final @Nullable Gamemode gamemodeFromPacket = Registries.GAMEMODES.getItem(packetAddPlayer.gamemode);
+        playerRemote.setGamemode(Objects.requireNonNullElse(gamemodeFromPacket, Gamemodes.SURVIVAL));
         playerRemote.setHeldObject(packetAddPlayer.heldObjectTag == null ? null : ICarriable.createAndLoadCarriable(playerRemote, packetAddPlayer.heldObjectTag));
     }
 
@@ -1145,7 +1142,10 @@ public class PacketHandlerClient extends PacketHandler
     {
         Entity entity = getEntityByID(packet.entityId);
         if (entity instanceof Player){
-            ((Player) entity).setGamemode(Gamemode.gamemodesList[packet.gamemodeId]);
+            final @Nullable Gamemode gamemodeFromPacket = Registries.GAMEMODES.getItem(packet.gamemodeId);
+            if (gamemodeFromPacket != null) {
+                ((Player) entity).setGamemode(gamemodeFromPacket);
+            }
         }
     }
 
@@ -1168,7 +1168,7 @@ public class PacketHandlerClient extends PacketHandler
     
     @Override
     public void handleSetCarriedItem(@NotNull PacketSetCarriedItem packetSetCarriedItem) {
-        mc.thePlayer.inventory.setCurrentItemIndex(packetSetCarriedItem.id, true);
+        mc.thePlayer.inventory.setCurrentSlot(packetSetCarriedItem.id, true);
     }
 
     @Override
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 2524d34c1..128849c9c 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
@@ -41,7 +41,7 @@ public abstract class PlayerController {
 	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().doBlockBreakingAnim()) {
+		if(!mc.thePlayer.getGamemode().hasBlockBreakingAnimation()) {
 			swingItem(true);
 			
 			ItemStack heldItem = mc.thePlayer.getCurrentEquippedItem();
@@ -70,7 +70,7 @@ public abstract class PlayerController {
 	
 	//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().doBlockBreakingAnim() || !mc.thePlayer.getGamemode().canInteract() || mc.thePlayer.getHeldObject() != null) {
+		if(!mc.thePlayer.getGamemode().hasBlockBreakingAnimation() || !mc.thePlayer.getGamemode().canInteract() || mc.thePlayer.getHeldObject() != null) {
 			return;
 		}
 		
@@ -301,9 +301,9 @@ public abstract class PlayerController {
 		int prevStackSize = stack.stackSize;
 		ItemStack newItemStack = stack.useItemRightClick(world, player);
 		if(newItemStack != stack || newItemStack.stackSize != prevStackSize) {
-			player.inventory.mainInventory[player.inventory.getCurrentItemIndex()] = newItemStack;
+			player.inventory.mainInventory[player.inventory.getCurrentSlot()] = newItemStack;
 			if(newItemStack == null || newItemStack.stackSize <= 0) {
-				player.inventory.mainInventory[player.inventory.getCurrentItemIndex()] = null;
+				player.inventory.mainInventory[player.inventory.getCurrentSlot()] = null;
 			}
 			return true;
 		}
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 2aba8d3e4..039a95ac7 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
@@ -57,7 +57,7 @@ public class PlayerControllerMP extends PlayerController {
 	
 	@Override
 	protected void syncCurrentPlayItem() {
-		int i = mc.thePlayer.inventory.getCurrentItemIndex();
+		int i = mc.thePlayer.inventory.getCurrentSlot();
 		if (i != currentItem) {
 			currentItem = i;
 			netHandler.addToSendQueue(new PacketSetCarriedItem(currentItem));
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 10f31693a..764cf9ece 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
@@ -26,7 +26,7 @@ public class PlayerControllerSP extends PlayerController {
 		if (item != null) {
 			item.onDestroyBlock(mc.currentWorld, id, x, y, z, side, mc.thePlayer);
 		}
-		if (removed && mc.thePlayer.getGamemode().dropBlockOnBreak()) {
+		if (removed && mc.thePlayer.getGamemode().hasItemDrops()) {
 			Blocks.blocksList[id].harvestBlock(mc.currentWorld, mc.thePlayer, x, y, z, meta, tileEntity);
 		}
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/ItemRenderer.java b/game/client/src/main/java/net/minecraft/client/render/ItemRenderer.java
index a21273c1f..367f70d98 100644
--- a/game/client/src/main/java/net/minecraft/client/render/ItemRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/ItemRenderer.java
@@ -281,7 +281,7 @@ public class ItemRenderer {
         this.oHeight = this.height;
         PlayerLocal playerLocal = this.mc.thePlayer;
         ItemStack itemstack = playerLocal.inventory.getCurrentItem();
-        boolean flag = this.lastSlot == playerLocal.inventory.getCurrentItemIndex() && itemstack == this.itemToRender;
+        boolean flag = this.lastSlot == playerLocal.inventory.getCurrentSlot() && itemstack == this.itemToRender;
         if (this.itemToRender == null && itemstack == null) {
             flag = true;
         }
@@ -301,7 +301,7 @@ public class ItemRenderer {
         this.height += f2;
         if (this.height < 0.1F) {
             this.itemToRender = itemstack;
-            this.lastSlot = playerLocal.inventory.getCurrentItemIndex();
+            this.lastSlot = playerLocal.inventory.getCurrentSlot();
         }
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/Lighting.java b/game/client/src/main/java/net/minecraft/client/render/Lighting.java
index 9c7478508..aa4f2e796 100644
--- a/game/client/src/main/java/net/minecraft/client/render/Lighting.java
+++ b/game/client/src/main/java/net/minecraft/client/render/Lighting.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render;
 
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.renderer.GLRenderer;
 import org.jetbrains.annotations.NotNull;
 import org.joml.Math;
@@ -26,7 +27,7 @@ public final class Lighting {
     }
 
     public static void enableLight() {
-        enableLight(0.5f, 0.6f);
+        enableLight(0.5f, 0.5f);
     }
 
     public static void enableLight(float ambientBrightness, float lightBrightness) {
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 acfee9305..bbb159fe4 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
@@ -1,7 +1,5 @@
 package net.minecraft.client.render;
 
-import java.util.Arrays;
-
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
@@ -16,13 +14,13 @@ final public class LightingCache {
     private static final int CACHE_RANGE = 1;
     private static final int CACHE_SIZE = CACHE_RANGE * 2 + 1;
 
-    private final boolean[] brightnessCached = new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
+    private int brightnessCached = 0; // new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
     private final float[] brightnessValue = new float[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
 
-    private final boolean[] opacityCached = new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
-    private final boolean[] opacityValue = new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
+    private int opacityCached = 0; // new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
+    private int opacityValue = 0; // new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
 
-    private final boolean[] lightmapCoordCached = new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
+    private int lightmapCoordCached = 0; // new boolean[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
     private final int[] lightmapCoordValue = new int[CACHE_SIZE * CACHE_SIZE * CACHE_SIZE];
 
     private final @NotNull TilePos offset = new TilePos(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
@@ -40,9 +38,9 @@ final public class LightingCache {
         if (!tilePos.equals(this.offset) || this.block != block || this.access != source) {
             this.block = block;
             this.access = source;
-            Arrays.fill(this.brightnessCached, false);
-            Arrays.fill(this.opacityCached, false);
-            Arrays.fill(this.lightmapCoordCached, false);
+            this.brightnessCached = 0;
+            this.opacityCached = 0;
+            this.lightmapCoordCached = 0;
             this.offset.set(tilePos);
         }
     }
@@ -66,9 +64,9 @@ final public class LightingCache {
     public float getBrightness(int relX, int relY, int relZ) {
         int index = (relX + CACHE_RANGE) * CACHE_SIZE * CACHE_SIZE + (relY + CACHE_RANGE) * CACHE_SIZE + (relZ + CACHE_RANGE);
 
-        if (!this.brightnessCached[index]) {
+        if (!bitGet(this.brightnessCached, index)) {
             this.brightnessValue[index] = calcBrightness(this.offset.add(relX, relY, relZ, this.queryPos));
-            this.brightnessCached[index] = true;
+            this.brightnessCached = bitSet(this.brightnessCached, index);
         }
 
         return this.brightnessValue[index];
@@ -76,20 +74,36 @@ 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 (!this.opacityCached[index]) {
-            this.opacityValue[index] = Blocks.solid[this.access.getBlockId(this.offset.add(relX, relY, relZ, this.queryPos))];
-            this.opacityCached[index] = true;
+        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.opacityCached = bitSet(this.opacityCached, index);
         }
-        return this.opacityValue[index];
+        return bitGet(this.opacityValue, index);
     }
 
     public int getLightmapCoord(int relX, int relY, int relZ) {
         int index = (relX + CACHE_RANGE) * CACHE_SIZE * CACHE_SIZE + (relY + CACHE_RANGE) * CACHE_SIZE + (relZ + CACHE_RANGE);
-        if (!this.lightmapCoordCached[index]) {
+        if (!bitGet(this.lightmapCoordCached, index)) {
             int lightEmission = this.block.emission;
             this.lightmapCoordValue[index] = this.access.getLightmapCoord(this.offset.add(relX, relY, relZ, this.queryPos), lightEmission);
-            this.lightmapCoordCached[index] = true;
+            this.lightmapCoordCached = bitSet(this.lightmapCoordCached, index);
         }
         return this.lightmapCoordValue[index];
     }
+
+    private static boolean bitGet(int value, int index) {
+        return (value & (1 << index)) != 0;
+    }
+
+    private static int bitSet(int value, int index) {
+        return (value | (1 << index));
+    }
+
+    private static int bitSetState(int value, int index, boolean state) {
+        if (state) {
+            return (value | (1 << index));
+        } else {
+            return (value & ~(1 << index));
+        }
+    }
 }
\ No newline at end of file
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 4ae3f4066..77983d73f 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
@@ -2,13 +2,13 @@ package net.minecraft.client.render;
 
 import it.unimi.dsi.fastutil.objects.ObjectArrayList;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLeaves;
 import net.minecraft.client.render.particle.Particle;
 import net.minecraft.client.render.particle.ParticleDispatcher;
 import net.minecraft.client.gui.ScreenPhotoMode;
 import net.minecraft.client.gui.modelviewer.ScreenModelViewer;
 import net.minecraft.client.gui.options.ScreenOptions;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
-import net.minecraft.client.render.block.model.BlockModelLeaves;
 import net.minecraft.client.render.camera.EntityCamera;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.colorizer.Colorizers;
@@ -34,6 +34,7 @@ import net.minecraft.core.block.support.PartialSupport;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemDiscMusic;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.Color;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
@@ -43,7 +44,6 @@ import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.enums.EnumBlockSoundEffectType;
 import net.minecraft.core.item.Item;
-import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.BoundingVolume;
@@ -229,7 +229,7 @@ public class RenderGlobal
     public void allChanged() {
         ScreenOptions.queueReload = false;
         updateStars();
-        BlockModelLeaves.setGraphicsLevel(this.mc.gameSettings.fancyGraphics.value == 1);
+        BlockModelGenericLeaves.setGraphicsLevel(this.mc.gameSettings.fancyGraphics.value == 1);
         this.renderDistance = this.mc.gameSettings.renderDistance.value;
         if (this.world == null) return;
 
@@ -1491,7 +1491,7 @@ public class RenderGlobal
         }
 
         float entityRadius = 10.0f;
-        if (this.mc.thePlayer.getGamemode() == Gamemode.creative) {
+        if (this.mc.thePlayer.getGamemode() == Gamemodes.CREATIVE) {
             entityRadius = 100.0f;
         }
         List<Entity> entitiesNearby = this.world.getEntitiesWithinAABBExcludingEntity(null, MathHelper.aabbGrow(this.mc.thePlayer.bb, entityRadius, entityRadius, entityRadius, new AABBd()));
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 ff7fa1795..130c9ce4e 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
@@ -643,19 +643,19 @@ public class WorldRenderer {
 
         Debug.change("terrain");
         GLRenderer.pushFrame();
+        GLRenderer.setDepthFunc(CompareFunc.LESS_EQUAL);
         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);
-
+        Lighting.enableLight();
         GLRenderer.setShader(Shaders.TERRAIN);
         GLRenderer.globalSetUniforms(Shaders.TERRAIN);
         this.lightmapHelper.enableLightmapRendering();
         this.mc.terrainRenderer.renderSolidTerrain(partialTicks);
         GLRenderer.popFrame();
 
-        Lighting.enableLight();
         Debug.change("entities");
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
         renderGlobal.renderEntities(this.mc.activeCamera, partialTicks);
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 240654c51..7ce4d673a 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
@@ -22,7 +22,7 @@ public abstract class BlockModel<T extends BlockLogic> {
     }
     public abstract boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos);
     public abstract boolean renderNoCulling(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos);
-    public abstract boolean renderWithOverrideTexture(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, IconCoordinate textureIndex);
+    public abstract boolean renderWithOverrideTexture(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, IconCoordinate overrideTexture);
     public abstract void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord);
 
     public abstract boolean shouldItemRender3d();
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelActivator.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelActivator.java
deleted file mode 100644
index 425153ec1..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelActivator.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicActivator;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelActivator<T extends BlockLogic> extends BlockModelVeryRotatable<T> {
-    public final IconCoordinate[] poweredTextures = {
-        TextureRegistry.getTexture("minecraft:block/activator/bottom_active"),
-        TextureRegistry.getTexture("minecraft:block/activator/top_active"),
-        TextureRegistry.getTexture("minecraft:block/activator/side_active"),
-        TextureRegistry.getTexture("minecraft:block/activator/front_active"),
-        TextureRegistry.getTexture("minecraft:block/activator/side_active"),
-        TextureRegistry.getTexture("minecraft:block/activator/side_active")
-    };
-
-    public BlockModelActivator(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if ((data & BlockLogicActivator.MASK_POWERED) != 0) {
-            return this.poweredTextures[getRotatedSide(side, data).getId()];
-        } else {
-            return super.getBlockTextureFromSideAndMetadata(side, data);
-        }
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelAlgae.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelAlgae.java
deleted file mode 100644
index 60628cccf..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelAlgae.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.block.color.BlockColorDispatcher;
-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.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelAlgae<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelAlgae(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        AABBdc bounds = this.block.getBoundsFromState(worldSource, tilePos);
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-
-        int color = BlockColorDispatcher.getInstance().getDispatch(this.block).getWorldColor(worldSource, tilePos, 0);
-        float red = (float) (color >> 16 & 0xff) / 255F;
-        float green = (float) (color >> 8 & 0xff) / 255F;
-        float blue = (float) (color & 0xff) / 255F;
-
-        tessellator.setColorOpaque3f(red, green, blue);
-        IconCoordinate tex = getBlockTextureFromSideAndMetadata(Side.TOP, worldSource.getBlockData(tilePos));
-        renderBlocks.renderTopFace(tessellator, bounds, tilePos.x(), tilePos.y() - 0.1125, tilePos.z(), tex);
-        renderBlocks.renderBottomFace(tessellator, bounds, tilePos.x(), tilePos.y() + 0.0125, tilePos.z(), tex);
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        if (side == Side.TOP) {
-            return true;
-        }
-        return super.shouldSideBeRendered(source, bounds, tilePos, side);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBasket.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBasket.java
deleted file mode 100644
index 4be4cc289..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBasket.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.BlockLogicBasket;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBd;
-
-public class BlockModelBasket<T extends BlockLogicBasket> extends BlockModelStandard<T> {
-    protected IconCoordinate fillTexture = TextureRegistry.getTexture("minecraft:block/basket/fill");
-
-    public BlockModelBasket(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        AABBd bounds = new AABBd(this.block.getBounds());
-        // Render basket
-        final float onePix = 1.0f / 16;
-        final float basketHeight = onePix * 16;
-
-        // Basket walls
-        bounds.setMin(0, 0, 0).setMax(1, onePix, 1);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos); // Bottom
-
-        renderBlocks.setRenderSide(Side.EAST, false);
-        renderBlocks.setRenderSide(Side.WEST, false);
-        renderBlocks.setRenderSide(Side.BOTTOM, false);
-        bounds.setMin(0, 0, 0).setMax(1, basketHeight, onePix);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos); // North
-        bounds.setMin(0, 0, 1 - onePix).setMax(1, basketHeight, 1); // south
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos); // South
-        renderBlocks.renderBitMask = 0;
-
-        renderBlocks.setRenderSide(Side.NORTH, false);
-        renderBlocks.setRenderSide(Side.SOUTH, false);
-        renderBlocks.setRenderSide(Side.BOTTOM, false);
-        bounds.setMin(0, 0, 0).setMax(onePix, basketHeight, 1);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos); // West
-        bounds.setMin(1 - onePix, 0, 0).setMax(1, basketHeight, 1);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos); // East
-        bounds.setMin(0.0f, 0.0f, 0.0f).setMax(1.0f, 1.0f, 1.0f);
-        renderBlocks.renderBitMask = 0;
-
-        final int height = this.block.getLogic().getFillLevel(worldSource, tilePos);
-        // Interior
-        if (height > 0) {
-            renderBlocks.renderTopFace(tessellator, bounds, tilePos.x(), (tilePos.y() - 1) + onePix + onePix * height, tilePos.z(), this.fillTexture);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBed.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBed.java
deleted file mode 100644
index e2f3ba68c..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBed.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicBed;
-import net.minecraft.core.util.helper.Side;
-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.jetbrains.annotations.Nullable;
-import org.joml.primitives.AABBd;
-
-public class BlockModelBed<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected IconCoordinate underTexture = TextureRegistry.getTexture("minecraft:block/bed/bottom");
-    protected final IconCoordinate[] bedTextures = new IconCoordinate[6];
-
-    public BlockModelBed(Block<T> block) {
-        super(block);
-        this.bedTextures[0] = TextureRegistry.getTexture("minecraft:block/bed/foot_front");
-        this.bedTextures[1] = TextureRegistry.getTexture("minecraft:block/bed/foot_side");
-        this.bedTextures[2] = TextureRegistry.getTexture("minecraft:block/bed/foot_top");
-        this.bedTextures[3] = TextureRegistry.getTexture("minecraft:block/bed/head_front");
-        this.bedTextures[4] = TextureRegistry.getTexture("minecraft:block/bed/head_side");
-        this.bedTextures[5] = TextureRegistry.getTexture("minecraft:block/bed/head_top");
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        TilePos queryPos = new TilePos();
-        AABBd bounds = new AABBd(this.block.getBoundsFromState(worldSource, tilePos));
-        renderBlocks.enableAO = true;
-        renderBlocks.cache.setupCache(this.block, worldSource, tilePos);
-
-        final int meta = worldSource.getBlockData(tilePos);
-        final int direction = BlockLogicBed.getDirection(meta);
-        final boolean isFootOfBed = BlockLogicBed.isBlockFootOfBed(meta);
-
-        final double minY = bounds.minY;
-        bounds.minY += 0.1875D;
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1f, 1f, 1f, Side.BOTTOM, meta);
-        bounds.minY = minY;
-
-        if (direction == 0) {
-            renderBlocks.uvRotateTop = 1;
-        } else if (direction == 2) {
-            renderBlocks.uvRotateTop = 2;
-        } else if (direction == 1) {
-            renderBlocks.uvRotateTop = 3;
-        }
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.TOP, meta);
-
-        renderBlocks.uvRotateTop = 0;
-        final int f17 = isFootOfBed ? BlockLogicBed.headOfBedMap[BlockLogicBed.footToHeadMap[direction]] : BlockLogicBed.headOfBedMap[direction];
-
-        if (f17 != 2 && (renderBlocks.renderAllFaces || shouldSideBeRendered(worldSource, bounds, tilePos.north(queryPos), Side.NORTH))) {
-            renderBlocks.flipTexture = direction == 3;
-            renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.NORTH, meta);
-        }
-
-        if (f17 != 3 && (renderBlocks.renderAllFaces || shouldSideBeRendered(worldSource, bounds, tilePos.south(queryPos), Side.SOUTH))) {
-            renderBlocks.flipTexture = direction == 1;
-            renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.SOUTH, meta);
-        }
-
-        if (f17 != 4 && (renderBlocks.renderAllFaces || shouldSideBeRendered(worldSource, bounds, tilePos.west(queryPos), Side.WEST))) {
-            renderBlocks.flipTexture = direction == 2;
-            renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.WEST, meta);
-        }
-
-        if (f17 != 5 && (renderBlocks.renderAllFaces || shouldSideBeRendered(worldSource, bounds, tilePos.east(queryPos), Side.EAST))) {
-            renderBlocks.flipTexture = direction == 0;
-            renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.EAST, meta);
-        }
-        renderBlocks.resetRenderBlocks();
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (side == Side.BOTTOM) {
-            return this.underTexture;
-        }
-        int k = BlockLogicBed.getDirection(data);
-        int l = BlockLogicBed.bedDirection[k][side.getId()];
-        if (BlockLogicBed.isBlockFootOfBed(data)) {
-            if (l == 2) {
-                return this.bedTextures[3];
-            }
-            if (l == 5 || l == 4) {
-                return this.bedTextures[4];
-            } else {
-                return this.bedTextures[5];
-            }
-        }
-        if (l == 3) {
-            return this.bedTextures[0];
-        }
-        if (l == 5 || l == 4) {
-            return this.bedTextures[1];
-        } else {
-            return this.bedTextures[2];
-        }
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
deleted file mode 100644
index aa39973d3..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicBrazier;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.util.helper.Side;
-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.joml.primitives.AABBd;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelBrazier<T extends BlockLogicBrazier>
-    extends BlockModelStandard<T> {
-    protected IconCoordinate sideTexture = TextureRegistry.getTexture("minecraft:block/brazier/side");
-    protected IconCoordinate baseTexture = TextureRegistry.getTexture("minecraft:block/brazier/base");
-    protected BlockModelStandard<?> fireModel = new BlockModelFire<>(Blocks.FIRE, true).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fire");
-
-    public BlockModelBrazier(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        TilePos queryPos = new TilePos();
-        tessellator.setColorOpaque1i(0xFFFFFF);
-
-        renderBlocks.enableAO = true;
-        renderBlocks.cache.setupCache(this.block, worldSource, tilePos);
-        AABBd bounds = new AABBd(this.block.getBounds());
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.NORTH, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.SOUTH, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.EAST, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.WEST, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, Side.BOTTOM, 0);
-
-        final double zFightOffset = 0.005;
-        bounds.setMin(-zFightOffset, -zFightOffset, -zFightOffset).setMax(1 + zFightOffset, 1 + zFightOffset, 1 + zFightOffset);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos.south(queryPos), 0, 0, 0, Side.NORTH, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos.north(queryPos), 0, 0, 0, Side.SOUTH, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos.west(queryPos), 0, 0, 0, Side.EAST, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos.east(queryPos), 0, 0, 0, Side.WEST, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos.down(queryPos), 0, 0, 0, Side.TOP, 0);
-        renderBlocks.enableAO = false;
-
-        if (this.block.getLogic().isBurning()) {
-            this.fireModel.render(tessellator, worldSource, tilePos);
-        }
-
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        AABBdc bounds = this.block.getBounds();
-
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, this.baseTexture);
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, -1.0D, 0.0D, this.baseTexture);
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, this.sideTexture);
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 1.0D, this.sideTexture);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, this.sideTexture);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, -1.0D, this.sideTexture);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, this.sideTexture);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 1.0D, 0.0D, 0.0D, this.sideTexture);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, this.sideTexture);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, -1.0D, 0.0D, 0.0D, this.sideTexture);
-        tessellator.draw();
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-
-    @Override
-    public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        return true;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelButtonPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelButtonPainted.java
deleted file mode 100644
index dadade9ea..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelButtonPainted.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelButtonPainted<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected final IconCoordinate[] texCoords = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-
-    public BlockModelButtonPainted(final Block<T> block) {
-        super(block);
-        for (final DyeColor c : DyeColor.blockOrderedColors()) {
-            this.texCoords[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/planks/" + c.colorID);
-        }
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(final @NotNull Side side, final int meta) {
-        return this.texCoords[(meta >> 4) & DyeColor.MASK_COLOR];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCactus.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCactus.java
deleted file mode 100644
index 5b029acf9..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCactus.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBd;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelCactus<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelCactus(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        final float sidesOffset = 0.0625F;
-
-        AABBd bounds = new AABBd(this.block.getBounds());
-        bounds.setMin(sidesOffset, 0, 0).setMax(1 - sidesOffset, 1, 1);
-        renderBlocks.setRenderSide(Side.SOUTH, false);
-        renderBlocks.setRenderSide(Side.NORTH, false);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-        renderBlocks.renderBitMask = 0b111111;
-
-        bounds.setMin(0, 0, sidesOffset).setMax(1, 1, 1 - sidesOffset);
-        renderBlocks.setRenderSide(Side.SOUTH, true);
-        renderBlocks.setRenderSide(Side.NORTH, true);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-        renderBlocks.renderBitMask = 0;
-
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        AABBdc bounds = getBlockBoundsForItemRender();
-        final float sidesOffset = 0.0625F;
-
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setColor1i(getStandaloneTintColor(metadata));
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.BOTTOM, metadata));
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.TOP, metadata));
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        tessellator.offsetTranslation(0.0F, 0.0F, sidesOffset);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.NORTH, metadata));
-        tessellator.offsetTranslation(0.0F, 0.0F, -sidesOffset);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        tessellator.offsetTranslation(0.0F, 0.0F, -sidesOffset);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.SOUTH, metadata));
-        tessellator.offsetTranslation(0.0F, 0.0F, sidesOffset);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        tessellator.offsetTranslation(sidesOffset, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.WEST, metadata));
-        tessellator.offsetTranslation(-sidesOffset, 0.0F, 0.0F);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        tessellator.offsetTranslation(-sidesOffset, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.EAST, metadata));
-        tessellator.offsetTranslation(sidesOffset, 0.0F, 0.0F);
-        tessellator.draw();
-
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCake.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCake.java
deleted file mode 100644
index 78244c2f9..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCake.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelCake<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected IconCoordinate cakeInner = TextureRegistry.getTexture("minecraft:block/cake/inner");
-
-    public BlockModelCake(Block<T> block) {
-        super(block);
-        float f = 0.0625F;
-        float f1 = 0.5F;
-        withCustomItemBounds(f, 0.0F, f, 1.0F - f, f1, 1.0F - f);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (data > 0 && side == Side.WEST) {
-            return this.cakeInner;
-        }
-        return super.getBlockTextureFromSideAndMetadata(side, data);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCandle.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCandle.java
deleted file mode 100644
index 809d8f7a1..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCandle.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-
-public class BlockModelCandle<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelCandle(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        boolean isLit = (worldSource.getBlockData(tilePos) & 0b00000001) == 0;
-        float brightness = isLit ? 1.0f : renderBlocks.getBlockBrightness(worldSource, tilePos);
-
-        float minX = tilePos.x() + 0.5f - (1.5f / 16f);
-        float minY = tilePos.y() + 0f;
-        float minZ = tilePos.z() + 0.5f - (1.5f / 16f);
-        float maxX = tilePos.x() + 0.5f + (1.5f / 16f);
-        float maxY = tilePos.y() + 0.5f;
-        float maxZ = tilePos.z() + 0.5f + (1.5f / 16f);
-        float wickMaxY = maxY + (6f / 16f);
-
-        IconCoordinate texIndex = getParticleTexture(Side.TOP, 0);
-        if (renderBlocks.overrideBlockTexture != null) {
-            texIndex = renderBlocks.overrideBlockTexture;
-        }
-        double texU = texIndex.getIconUMin();
-        double texV = texIndex.getIconVMin();
-
-        double onePix = 1f / 16;
-
-        double uOffset = isLit ? 0.0f : (onePix * 3);
-
-        double sideMinU = texIndex.getSubIconU(uOffset);
-        double sideMaxU = texIndex.getSubIconU(uOffset + (onePix * 3));
-        double sideMinV = texIndex.getSubIconV((onePix * 3));
-        double sideMaxV = texIndex.getSubIconV((onePix * 3) + (onePix * 8));
-
-        double topMinU = texIndex.getSubIconU(uOffset);
-        double topMaxU = texIndex.getSubIconU(uOffset + (onePix * 3));
-        double topMinV = texV;
-        double topMaxV = texIndex.getSubIconV(onePix * 3);
-
-        double bottomMinU = texIndex.getSubIconU(onePix * 3);
-        double bottomMaxU = texIndex.getSubIconU((onePix * 3) + (onePix * 3));
-        double bottomMinV = texV;
-        double bottomMaxV = texIndex.getSubIconV(onePix * 3);
-
-        double wickMinU = texIndex.getSubIconU((onePix * 6) + uOffset);
-        double wickMaxU = texIndex.getSubIconU((onePix * 6) + uOffset + (onePix * 3));
-        double wickMinV = texV;
-        double wickMaxV = texIndex.getSubIconV(onePix * 6);
-
-
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-
-        // Render sides
-        tessellator.addVertexWithUV(maxX, minY, minZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(minX, minY, minZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(minX, maxY, minZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(maxX, maxY, minZ, sideMinU, sideMinV);
-
-        tessellator.addVertexWithUV(minX, minY, maxZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(maxX, minY, maxZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(maxX, maxY, maxZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(minX, maxY, maxZ, sideMinU, sideMinV);
-
-        tessellator.addVertexWithUV(maxX, minY, maxZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(maxX, minY, minZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(maxX, maxY, minZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(maxX, maxY, maxZ, sideMinU, sideMinV);
-
-        tessellator.addVertexWithUV(minX, minY, minZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(minX, minY, maxZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(minX, maxY, maxZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(minX, maxY, minZ, sideMinU, sideMinV);
-
-        // Render top
-        tessellator.addVertexWithUV(minX, maxY, maxZ, topMinU, topMaxV);
-        tessellator.addVertexWithUV(maxX, maxY, maxZ, topMaxU, topMaxV);
-        tessellator.addVertexWithUV(maxX, maxY, minZ, topMaxU, topMinV);
-        tessellator.addVertexWithUV(minX, maxY, minZ, topMinU, topMinV);
-
-        // Render bottom
-        tessellator.addVertexWithUV(minX, minY, minZ, bottomMinU, bottomMinV);
-        tessellator.addVertexWithUV(maxX, minY, minZ, bottomMaxU, bottomMinV);
-        tessellator.addVertexWithUV(maxX, minY, maxZ, bottomMaxU, bottomMaxV);
-        tessellator.addVertexWithUV(minX, minY, maxZ, bottomMinU, bottomMaxV);
-
-        // Render wick
-        tessellator.addVertexWithUV(minX, maxY, minZ, wickMinU, wickMaxV);
-        tessellator.addVertexWithUV(maxX, maxY, maxZ, wickMaxU, wickMaxV);
-        tessellator.addVertexWithUV(maxX, wickMaxY, maxZ, wickMaxU, wickMinV);
-        tessellator.addVertexWithUV(minX, wickMaxY, minZ, wickMinU, wickMinV);
-
-        tessellator.addVertexWithUV(minX, wickMaxY, minZ, wickMaxU, wickMinV);
-        tessellator.addVertexWithUV(maxX, wickMaxY, maxZ, wickMinU, wickMinV);
-        tessellator.addVertexWithUV(maxX, maxY, maxZ, wickMinU, wickMaxV);
-        tessellator.addVertexWithUV(minX, maxY, minZ, wickMaxU, wickMaxV);
-
-        tessellator.addVertexWithUV(minX, maxY, maxZ, wickMinU, wickMaxV);
-        tessellator.addVertexWithUV(maxX, maxY, minZ, wickMaxU, wickMaxV);
-        tessellator.addVertexWithUV(maxX, wickMaxY, minZ, wickMaxU, wickMinV);
-        tessellator.addVertexWithUV(minX, wickMaxY, maxZ, wickMinU, wickMinV);
-
-        tessellator.addVertexWithUV(minX, wickMaxY, maxZ, wickMaxU, wickMinV);
-        tessellator.addVertexWithUV(maxX, wickMaxY, minZ, wickMinU, wickMinV);
-        tessellator.addVertexWithUV(maxX, maxY, minZ, wickMinU, wickMaxV);
-        tessellator.addVertexWithUV(minX, maxY, maxZ, wickMaxU, wickMaxV);
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelChest.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelChest.java
deleted file mode 100644
index f7226e3aa..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelChest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.*;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.useless.dragonfly.DisplayPos;
-
-public class BlockModelChest<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected static final DisplayPos CHEST_GUI = new DisplayPos(0, 0, 0, 30, 45, 0, 0.625f, 0.625f, 0.625f);
-    protected static final DisplayPos CHEST_HEAD = new DisplayPos(0, 0, 0, 0, -180, 0, 1f, 1f, 1f);
-    protected static final DisplayPos CHEST_FIRST_PERSON_RIGHT_HAND = new DisplayPos(0, 0, 0, 0, -45, 0, 0.4f, 0.4f, 0.4f);
-
-    protected IconCoordinate chestFrontSingle;
-    protected IconCoordinate chestFrontLeft;
-    protected IconCoordinate chestFrontRight;
-    protected IconCoordinate chestBackLeft;
-    protected IconCoordinate chestBackRight;
-    protected IconCoordinate chestTopLeft;
-    protected IconCoordinate chestTopRight;
-    protected IconCoordinate chestSide;
-    protected IconCoordinate chestTop;
-
-    public BlockModelChest(Block<T> block, String rootKey) {
-        super(block);
-        this.chestFrontSingle = TextureRegistry.getTexture(rootKey + "front");
-        this.chestFrontLeft = TextureRegistry.getTexture(rootKey + "left_front");
-        this.chestFrontRight = TextureRegistry.getTexture(rootKey + "right_front");
-        this.chestTopLeft = TextureRegistry.getTexture(rootKey + "top_left");
-        this.chestTopRight = TextureRegistry.getTexture(rootKey + "top_right");
-        this.chestBackLeft = TextureRegistry.getTexture(rootKey + "left_back");
-        this.chestBackRight = TextureRegistry.getTexture(rootKey + "right_back");
-        this.chestSide = TextureRegistry.getTexture(rootKey + "side");
-        this.chestTop = TextureRegistry.getTexture(rootKey + "top");
-
-        setDisplayPos(DisplayPos.GUI, CHEST_GUI);
-        setDisplayPos(DisplayPos.HEAD, CHEST_HEAD);
-        setDisplayPos(DisplayPos.FIRST_PERSON_RIGHT_HAND, CHEST_FIRST_PERSON_RIGHT_HAND);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        int meta = worldSource.getBlockData(tilePos);
-        final Direction dir = BlockLogicChest.getDirectionFromMeta(meta);
-        switch (dir) {
-            case NORTH:
-                renderBlocks.uvRotateTop = 3;
-                renderBlocks.uvRotateBottom = 3;
-                break;
-            case EAST:
-                renderBlocks.uvRotateTop = 2;
-                renderBlocks.uvRotateBottom = 1;
-                break;
-
-            case WEST:
-                renderBlocks.uvRotateTop = 1;
-                renderBlocks.uvRotateBottom = 2;
-                break;
-        }
-
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, this.block.getBoundsFromState(worldSource, tilePos), tilePos);
-        renderBlocks.resetRenderBlocks();
-        return true;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        int meta = source.getBlockData(tilePos);
-
-        Side facing = BlockLogicChest.getDirectionFromMeta(meta).getSide();
-        BlockLogicChest.Type type = BlockLogicChest.getTypeFromMeta(meta);
-
-        if (side == Side.TOP || side == Side.BOTTOM) {
-            if (type == BlockLogicChest.Type.RIGHT) {
-                return this.chestTopRight;
-            }
-            if (type == BlockLogicChest.Type.LEFT) {
-                return this.chestTopLeft;
-            }
-
-            return this.chestTop;
-        }
-
-        if (type == BlockLogicChest.Type.SINGLE) {
-            if (side == facing) {
-                return this.chestFrontSingle;
-            }
-        }
-
-        if (type == BlockLogicChest.Type.LEFT) {
-            if (side == facing) {
-                return this.chestFrontLeft;
-            }
-            if (side == facing.getOpposite()) {
-                return this.chestBackRight;
-            }
-        }
-        if (type == BlockLogicChest.Type.RIGHT) {
-            if (side == facing) {
-                return this.chestFrontRight;
-            }
-            if (side == facing.getOpposite()) {
-                return this.chestBackLeft;
-            }
-        }
-        if (side.getAxis() != Axis.Y) {
-            return this.chestSide;
-        }
-
-        return this.chestTop;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (side == Side.SOUTH) return this.chestFrontSingle;
-        if (side.isHorizontal()) return this.chestSide;
-        return this.chestTop;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelChestPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelChestPainted.java
deleted file mode 100644
index 1179a1c46..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelChestPainted.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicChest;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelChestPainted<T extends BlockLogic> extends BlockModelChest<T> {
-    public static final IconCoordinate[][] texCoords = new IconCoordinate[DyeColor.COLOR_AMOUNT][];
-    public static final int TEX_SINGLE_FRONT = 0;
-    public static final int TEX_LEFT_FRONT = 1;
-    public static final int TEX_RIGHT_FRONT = 2;
-    public static final int TEX_LEFT_BACK = 3;
-    public static final int TEX_RIGHT_BACK = 4;
-    public static final int TEX_SIDE = 5;
-    public static final int TEX_TOP = 6;
-    public static final int TEX_LEFT_TOP = 7;
-    public static final int TEX_RIGHT_TOP = 8;
-
-    static {
-        for (DyeColor c : DyeColor.blockOrderedColors()){
-            String rootKey = "minecraft:block/chest/planks_" + c.colorID + "/";
-            texCoords[c.blockMeta] = new IconCoordinate[9];
-            texCoords[c.blockMeta][TEX_SINGLE_FRONT] = TextureRegistry.getTexture(rootKey + "front");
-            texCoords[c.blockMeta][TEX_LEFT_FRONT] = TextureRegistry.getTexture(rootKey + "left_front");
-            texCoords[c.blockMeta][TEX_RIGHT_FRONT] = TextureRegistry.getTexture(rootKey + "right_front");
-            texCoords[c.blockMeta][TEX_LEFT_BACK] = TextureRegistry.getTexture(rootKey + "left_back");
-            texCoords[c.blockMeta][TEX_RIGHT_BACK] = TextureRegistry.getTexture(rootKey + "right_back");
-            texCoords[c.blockMeta][TEX_SIDE] = TextureRegistry.getTexture(rootKey + "side");
-            texCoords[c.blockMeta][TEX_TOP] = TextureRegistry.getTexture(rootKey + "top");
-            texCoords[c.blockMeta][TEX_LEFT_TOP] = TextureRegistry.getTexture(rootKey + "top_left");
-            texCoords[c.blockMeta][TEX_RIGHT_TOP] = TextureRegistry.getTexture(rootKey + "top_right");
-        }
-    }
-    public BlockModelChestPainted(Block<T> block) {
-        super(block, "minecraft:block/chest/planks/");
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource blockAccess, @NotNull TilePosc tilePos, @NotNull Side side) {
-        int meta = blockAccess.getBlockData(tilePos);
-        int color = meta >> 4;
-
-        Side facing = BlockLogicChest.getDirectionFromMeta(meta).getSide();
-        BlockLogicChest.Type type = BlockLogicChest.getTypeFromMeta(meta);
-
-        if(side == Side.TOP || side == Side.BOTTOM) {
-            if(type == BlockLogicChest.Type.LEFT) {
-                return texCoords[color][7];
-            }
-            if(type == BlockLogicChest.Type.RIGHT) {
-                return texCoords[color][8];
-            }
-
-            return texCoords[color][6];
-        }
-
-        if(type == BlockLogicChest.Type.SINGLE) {
-            if(side == facing) {
-                return texCoords[color][TEX_SINGLE_FRONT];
-            }
-        }
-
-        if(type == BlockLogicChest.Type.LEFT) {
-            if(side == facing) {
-                return texCoords[color][TEX_LEFT_FRONT];
-            }
-            if(side == facing.getOpposite()) {
-                return texCoords[color][TEX_RIGHT_BACK];
-            }
-        }
-        if(type == BlockLogicChest.Type.RIGHT) {
-            if(side == facing) {
-                return texCoords[color][TEX_RIGHT_FRONT];
-            }
-            if(side == facing.getOpposite()) {
-                return texCoords[color][TEX_LEFT_BACK];
-            }
-        }
-        if(side.getAxis() != Axis.Y) {
-            return texCoords[color][TEX_SIDE];
-        }
-
-        return texCoords[color][TEX_TOP];
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        int color = data >> 4;
-        if (side == Side.SOUTH) return texCoords[color][TEX_SINGLE_FRONT];
-        if (side.isHorizontal()) return texCoords[color][TEX_SIDE];
-        return texCoords[color][TEX_TOP];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCobbledNetherrack.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCobbledNetherrack.java
deleted file mode 100644
index 09d16022f..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCobbledNetherrack.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.material.Material;
-import net.minecraft.core.block.material.Materials;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.Side;
-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.jetbrains.annotations.Nullable;
-
-public class BlockModelCobbledNetherrack<T extends BlockLogic> extends BlockModelStandard<T> {
-    private final IconCoordinate ashSide = TextureRegistry.getTexture("minecraft:block/cobbled_netherrack/ashen_side");
-
-    public BlockModelCobbledNetherrack(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        Material material = source.getBlockMaterial(tilePos.up(new TilePos()));
-        if ((material == Materials.TOP_ASH || material == Materials.ASH) && (side.getAxis() != Axis.Y)) {
-            return this.ashSide;
-        } else return super.getBlockTexture(source, tilePos, side);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCropsPumpkin.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCropsPumpkin.java
deleted file mode 100644
index 47f1ab21b..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCropsPumpkin.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelCropsPumpkin<T extends BlockLogic> extends BlockModelStandard<T> {
-    public static final IconCoordinate[] GROWTH_STAGE_TEXTURES_TOP = {
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage1_top"),
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage2_top"),
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage3_top"),
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage4_top")
-    };
-    public static final IconCoordinate[] GROWTH_STAGE_TEXTURES_SIDE = {
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage1_side"),
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage2_side"),
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage3_side"),
-        TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage4_side")
-    };
-
-    public static final IconCoordinate LEAF_TEXTURE = TextureRegistry.getTexture("minecraft:block/crops_pumpkin/stage0");
-
-    public BlockModelCropsPumpkin(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        float brightness = 1.0f;
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-
-        final int meta = worldSource.getBlockData(tilePos);
-        IconCoordinate leafTexture = LEAF_TEXTURE;
-        if (renderBlocks.overrideBlockTexture != null) {
-            leafTexture = renderBlocks.overrideBlockTexture;
-        }
-        double uMin = leafTexture.getIconUMin();
-        double uMax = leafTexture.getIconUMax();
-        double vMin = leafTexture.getIconVMin();
-        double vMax = leafTexture.getIconVMax();
-
-        double xMin = tilePos.x() + 0.5D - 0.25D;
-        double xMax = tilePos.x() + 0.5D + 0.25D;
-        double yMin = tilePos.y() + 0.0D;
-        double yMax = tilePos.y() + (3.0D / 16.0D);
-        double zMin = tilePos.z() + 0.5D - 0.5D;
-        double zMax = tilePos.z() + 0.5D + 0.5D;
-        double extra = (10d / 16d);
-        tessellator.addVertexWithUV(xMin - extra, yMax, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yMin, zMax, uMin, vMax);
-        tessellator.addVertexWithUV(xMax, yMin, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMin - extra, yMax, zMin, uMax, vMin);
-
-        tessellator.addVertexWithUV(xMin - extra, yMax, zMin, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yMin, zMin, uMin, vMax);
-        tessellator.addVertexWithUV(xMax, yMin, zMax, uMax, vMax);
-        tessellator.addVertexWithUV(xMin - extra, yMax, zMax, uMax, vMin);
-
-        tessellator.addVertexWithUV(xMax + extra, yMax, zMin, uMin, vMin);
-        tessellator.addVertexWithUV(xMin, yMin, zMin, uMin, vMax);
-        tessellator.addVertexWithUV(xMin, yMin, zMax, uMax, vMax);
-        tessellator.addVertexWithUV(xMax + extra, yMax, zMax, uMax, vMin);
-
-        tessellator.addVertexWithUV(xMax + extra, yMax, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMin, yMin, zMax, uMin, vMax);
-        tessellator.addVertexWithUV(xMin, yMin, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMax + extra, yMax, zMin, uMax, vMin);
-        if (meta >= 1)
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, this.block.getBoundsFromState(worldSource, tilePos), tilePos);
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (data < 1 || data > 4) {
-            data = 1;
-        }
-        if (side == Side.TOP || side == Side.BOTTOM) {
-            return GROWTH_STAGE_TEXTURES_TOP[data - 1];
-        } else {
-            return GROWTH_STAGE_TEXTURES_SIDE[data - 1];
-        }
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCropsWheat.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCropsWheat.java
deleted file mode 100644
index 2086855af..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCropsWheat.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicCropsWheat;
-import net.minecraft.core.util.helper.MathHelper;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelCropsWheat<T extends BlockLogic> extends BlockModelStandard<T> {
-    public final IconCoordinate[] growthStageTextures = {
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage0"),
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage1"),
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage2"),
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage3"),
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage4"),
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage5"),
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage6"),
-        TextureRegistry.getTexture("minecraft:block/crops_wheat/stage7")
-    };
-
-    public BlockModelCropsWheat(Block<T> block) {
-        super(block);
-        assert this.growthStageTextures.length == BlockLogicCropsWheat.MAX_GROWTH_STATE + 1 : "There must be a texture for each wheat growth stage!";
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        float brightness = 1.0f;
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-
-        IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.BOTTOM, worldSource.getBlockData(tilePos));
-        if (renderBlocks.overrideBlockTexture != null) {
-            texture = renderBlocks.overrideBlockTexture;
-        }
-        double uMin = texture.getIconUMin();
-        double uMax = texture.getIconUMax();
-        double vMin = texture.getIconVMin();
-        double vMax = texture.getIconVMax();
-        double xMin = tilePos.x() + 0.5D - 0.25D;
-        double xMax = tilePos.x() + 0.5D + 0.25D;
-        double zMin = tilePos.z() + 0.5D - 0.5D;
-        double zMax = tilePos.z() + 0.5D + 0.5D;
-
-        double yd = (float) tilePos.y() - 0.0625F;
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMin, uMin, vMin);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMin, uMin, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMax, uMax, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMax, uMax, vMin);
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMax, uMin, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMin, uMax, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMax, uMin, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMin, uMax, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMin, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMin, uMin, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMax, uMax, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMax, uMax, vMin);
-
-        xMin = tilePos.x() + 0.5D - 0.5D;
-        xMax = tilePos.x() + 0.5D + 0.5D;
-        zMin = tilePos.z() + 0.5D - 0.25D;
-        zMax = tilePos.z() + 0.5D + 0.25D;
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMin, uMin, vMin);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMin, uMin, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMin, uMax, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMin, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMin, uMin, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMin, uMax, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMax, uMin, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMax, uMax, vMax);
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMax, uMax, vMin);
-        tessellator.addVertexWithUV(xMin, yd + 1.0D, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMin, yd + 0.0D, zMax, uMin, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 0.0D, zMax, uMax, vMax);
-        tessellator.addVertexWithUV(xMax, yd + 1.0D, zMax, uMax, vMin);
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        return this.growthStageTextures[MathHelper.clamp(data, 0, BlockLogicCropsWheat.MAX_GROWTH_STATE)];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java
index bf2d2ab94..16b5112a7 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCrossedSquares.java
@@ -5,7 +5,6 @@ import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.Blocks;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.pos.TilePosc;
@@ -80,15 +79,6 @@ public class BlockModelCrossedSquares<T extends BlockLogic> extends BlockModelSt
         double yd = tilePos.y();
         double zd = tilePos.z();
 
-        // Shift grass position with deterministic position based random
-        if (this.block == Blocks.TALLGRASS || this.block == Blocks.TALLGRASS_FERN || this.block == Blocks.SPINIFEX) {
-            long dRandom = (tilePos.x() * 0x2fc20fL) ^ (long) tilePos.z() * 0x6ebfff5L ^ (long) tilePos.y();
-            dRandom = dRandom * dRandom * 0x285b825L + dRandom * 11L;
-            xd += ((double) ((float) (dRandom >> 16 & 15L) / 15F) - 0.5D) * 0.5D;
-            yd += ((double) ((float) (dRandom >> 20 & 15L) / 15F) - 1.0D) * 0.2D;
-            zd += ((double) ((float) (dRandom >> 24 & 15L) / 15F) - 0.5D) * 0.5D;
-        }
-
         int metadata = worldSource.getBlockData(tilePos);
         IconCoordinate texIndex = getBlockTextureFromSideAndMetadata(Side.BOTTOM, metadata);
         if (renderBlocks.overrideBlockTexture != null) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCrystallineNetherrack.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCrystallineNetherrack.java
deleted file mode 100644
index 3581b561e..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelCrystallineNetherrack.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.block.color.BlockColorDispatcher;
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelCrystallineNetherrack<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected IconCoordinate overlay;
-
-    public BlockModelCrystallineNetherrack(Block<T> block) {
-        super(block);
-        this.overlay = TextureRegistry.getTexture("minecraft:block/nether_crystal/overlay");
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        AABBdc bounds = this.block.getBoundsFromState(worldSource, tilePos);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos, 1.0f, 1.0f, 1.0f);
-        renderBlocks.overrideBlockTexture = this.overlay;
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-        renderBlocks.overrideBlockTexture = null;
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        renderBlocks.useInventoryTint = false;
-        super.renderStandalone(tessellator, metadata, lightmapCoord);
-        renderBlocks.useInventoryTint = true;
-
-        AABBdc bounds = this.block.getBounds();
-        IconCoordinate tex = this.overlay;
-
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setColor1i(BlockColorDispatcher.getInstance().getDispatch(this.block).getFallbackColor(metadata, 0));
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, tex);
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, tex);
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, tex);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, tex);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, tex);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, tex);
-        tessellator.draw();
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-}
\ No newline at end of file
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 0a51d39b8..295654d4c 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
@@ -1,22 +1,74 @@
 package net.minecraft.client.render.block.model;
 
+import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.block.model.generic.BlockModelGeneric;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericActivator;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericAxis;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericBasket;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericBed;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericBrazier;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericButton;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericButtonPainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericCake;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericChest;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericChestPainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericCropsPumpkin;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericDoor;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericDoorPainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericFarmland;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericFence;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericFenceGate;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericFenceGatePainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericFencePainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericFenceThin;
+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.BlockModelGenericLayer;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLever;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericMatcher;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPebbles;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPie;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPiston;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPistonHead;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPortal;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPressurePlate;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPressurePlatePainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericRope;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericRotatable;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericJar;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLamp;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLantern;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLeaves;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLeavesCacao;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLeavesCherryFlowering;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericRepeater;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericShifted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPlanksPainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericSlab;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericSlabPainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericSpikes;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericStairs;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericStairsPainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericTorch;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericTrapdoor;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericTrapdoorPainted;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericVeryRotatable;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericCropsWheat;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericWool;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 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 org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
 import org.useless.dragonfly.data.block.mojang.BlockModelMojangData;
 
-import java.util.Objects;
-
-import static net.minecraft.client.render.block.model.BlockModelStandard.BLOCK_TEXTURES;
-import static net.minecraft.client.render.block.model.BlockModelStandard.RETRO_BLOCK_TEXTURES;
-
 public final class BlockModelDispatcher
     extends Dispatcher<Block<?>, 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};
 
@@ -45,9 +97,12 @@ public final class BlockModelDispatcher
         return modelEmpty;
     }
 
-    private static @NotNull BlockModelMojangData loadDataModel(@NotNull final String id) {
+    public static @NotNull BlockModelMojangData loadDataModel(@NotNull final String id) {
         final Minecraft mc = Minecraft.getMinecraft();
-        return Objects.requireNonNull(BlockModelMojangData.Cache.loadModelData(mc.texturePackList, id), "Cannot find model for id '" + id + "'!");
+        BlockModelMojangData model = BlockModelMojangData.Cache.loadModelData(mc.texturePackList, id);
+        if (model != null) return model;
+        LOGGER.error("Could not find model for id '{}'!", id);
+        return BlockModelMojangData.Cache.getMissingModel();
     }
 
     private BlockModelDispatcher() {
@@ -59,756 +114,486 @@ public final class BlockModelDispatcher
     public void reload() {
         BlockModelMojangData.Cache.resetCache();
         this.dispatches.clear();
-        addDispatch(new BlockModelStandard<>(Blocks.STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/stone"));
-        addDispatch(new BlockModelStandard<>(Blocks.BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.MARBLE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/marble"));
-        addDispatch(new BlockModelStandard<>(Blocks.SLATE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/slate_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/slate_side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/permafrost"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_STONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_stone")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/cobbled_stone_retro")
-        );
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_STONE_MOSSY)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_stone_mossy")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/cobbled_stone_mossy_retro")
-        );
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_permafrost"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_BASALT_MOSSY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_basalt_mossy"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_LIMESTONE_MOSSY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_limestone_mossy"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_GRANITE_MOSSY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_granite_mossy"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.STONE_POLISHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_stone_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_stone_side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.GRANITE_POLISHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_granite_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_granite_side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.LIMESTONE_POLISHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_limestone_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_limestone_side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.BASALT_POLISHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_basalt_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_basalt_side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.SLATE_POLISHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_slate_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_slate_side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.PERMAFROST_POLISHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_permafrost_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_permafrost_side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.NETHERRACK_POLISHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_netherrack_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_netherrack_side", S_SIDES));
-
-        addDispatch(new BlockModelAxisAligned<>(Blocks.PILLAR_MARBLE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pillar_marble/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pillar_marble/side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.CAPSTONE_MARBLE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/capstone_marble/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/capstone_marble/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.SANDSTONE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/sandstone/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/sandstone/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/sandstone/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.STONE_CARVED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_stone_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/carved_stone", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.GRANITE_CARVED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_granite_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/carved_granite", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.LIMESTONE_CARVED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_limestone_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/carved_limestone", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.BASALT_CARVED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_basalt_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/carved_basalt", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.PERMAFROST_CARVED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_permafrost_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/carved_permafrost", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.NETHERRACK_CARVED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_netherrack_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/carved_netherrack", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.PLANKS_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-        addDispatch(new BlockModelPlanksPainted<>(Blocks.PLANKS_OAK_PAINTED));
-
-        addDispatch(new BlockModelTorch<>(Blocks.TORCH_COAL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/torch_coal"));
-
-        addDispatch(new BlockModelLadder<>(Blocks.LADDER_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ladder"));
-
-        addDispatch(new BlockModelFence<>(Blocks.FENCE_PLANKS_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-        addDispatch(new BlockModelFencePainted<>(Blocks.FENCE_PLANKS_OAK_PAINTED));
-
-        addDispatch(new BlockModelFenceGate<>(Blocks.FENCE_GATE_PLANKS_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-        addDispatch(new BlockModelFenceGatePainted<>(Blocks.FENCE_GATE_PLANKS_OAK_PAINTED));
-
-        addDispatch(new BlockModelStandard<>(Blocks.BOOKSHELF_PLANKS_OAK)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/bookshelf/top", S_TB)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/bookshelf/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/bookshelf/side", S_SIDES)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/bookshelf/side_retro", S_SIDES)
-        );
-
-        addDispatch(new BlockModelWool<>(Blocks.WOOL));
-        addDispatch(new BlockModelRope<>(Blocks.ROPE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/rope"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_CLAY)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_clay")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/brick_clay_retro")
-        );
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_STONE_POLISHED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_polished_stone"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_STONE_POLISHED_MOSSY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_polished_stone_mossy"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_SANDSTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_sandstone"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_GOLD).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_gold"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_LAPIS).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_lapis"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_MARBLE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_marble"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_SLATE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_slate"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_stone"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_permafrost"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_IRON).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_iron"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_STEEL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_steel"));
-
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_PLANKS_OAK));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_COBBLE_STONE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_SANDSTONE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_STONE_POLISHED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_STONE_POLISHED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_MARBLE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_CLAY));
-        addDispatch(new BlockModelSlabMarble<>(Blocks.SLAB_CAPSTONE_MARBLE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_COBBLE_BASALT));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_COBBLE_LIMESTONE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_COBBLE_GRANITE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_BASALT));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_LIMESTONE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_GRANITE));
-        addDispatch(new BlockModelSlabPainted<>(Blocks.SLAB_PLANKS_PAINTED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_SLATE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_STONE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_GRANITE_POLISHED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_LIMESTONE_POLISHED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BASALT_POLISHED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_PERMAFROST_POLISHED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_COBBLE_PERMAFROST));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_SANDSTONE));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_PERMAFROST));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_IRON));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_GOLD));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_STEEL));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_LAPIS));
-
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_PLANKS_OAK));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_STONE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_STONE_POLISHED));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_MARBLE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_BASALT));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_LIMESTONE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_GRANITE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_BASALT));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_LIMESTONE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_GRANITE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_CLAY));
-        addDispatch(new BlockModelStairsPainted<>(Blocks.STAIRS_PLANKS_PAINTED));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_SLATE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_STONE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_SANDSTONE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_PERMAFROST));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_SANDSTONE));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_PERMAFROST));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_IRON));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_GOLD));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_STEEL));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_LAPIS));
-
-        addDispatch(new BlockModelStandard<>(Blocks.OBSIDIAN).setAllTextures(BLOCK_TEXTURES, "minecraft:block/obsidian"));
-
-        addDispatch(new BlockModelGlass<>(Blocks.GLASS, "minecraft:block/glass/").setAllTextures(BLOCK_TEXTURES, "minecraft:block/glass"));
-        addDispatch(new BlockModelGlass<>(Blocks.GLASS_TINTED, "minecraft:block/glass_tinted/").onRenderLayer(1).setAllTextures(BLOCK_TEXTURES, "minecraft:block/glass_tinted"));
-        addDispatch(new BlockModelTransparent<>(Blocks.GLASS_STEEL, false).setAllTextures(BLOCK_TEXTURES, "minecraft:block/glass_steel"));
-
-        addDispatch(new BlockModelGrass<>(Blocks.GRASS)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass/side", S_SIDES)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/grass_retro/top", Side.TOP)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/grass_retro/bottom", Side.BOTTOM)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/grass_retro/side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.GRASS_RETRO)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_retro/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_retro/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_retro/side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.GRASS_SCORCHED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_scorched/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_scorched/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_scorched/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.PATH_DIRT)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_path/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_path/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/grass_path/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.DIRT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/dirt"));
-        addDispatch(new BlockModelStandard<>(Blocks.DIRT_SCORCHED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/dirt_scorched"));
-        addDispatch(new BlockModelStandard<>(Blocks.DIRT_SCORCHED_RICH).setAllTextures(BLOCK_TEXTURES, "minecraft:block/dirt_scorched_rich"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.MUD).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mud"));
-        addDispatch(new BlockModelStandard<>(Blocks.MUD_BAKED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mud_baked"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.SPONGE_DRY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sponge"));
-        addDispatch(new BlockModelStandard<>(Blocks.SPONGE_WET).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sponge_wet"));
-        addDispatch(new BlockModelPumice<>(Blocks.PUMICE_DRY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/pumice"));
-        addDispatch(new BlockModelPumice<>(Blocks.PUMICE_WET).setAllTextures(BLOCK_TEXTURES, "minecraft:block/pumice_overlay"));
-
-        addDispatch(new BlockModelStoneMossy<>(Blocks.MOSS_STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/stone"));
-        addDispatch(new BlockModelStoneMossy<>(Blocks.MOSS_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/basalt"));
-        addDispatch(new BlockModelStoneMossy<>(Blocks.MOSS_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/limestone"));
-        addDispatch(new BlockModelStoneMossy<>(Blocks.MOSS_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/granite"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.SAND).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sand").setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/sand_retro"));
-        addDispatch(new BlockModelStandard<>(Blocks.GRAVEL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/gravel"));
-        addDispatch(new BlockModelStandard<>(Blocks.SULFUR).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sulfur"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.BEDROCK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/bedrock"));
-        addDispatch(new BlockModelFullyRotatable<>(Blocks.BONESHALE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/bone_shale/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/bone_shale/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/bone_shale/side", S_SIDES));
+        addDispatch(new BlockModelGeneric<>(Blocks.STONE, loadDataModel("minecraft:block/stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BASALT, loadDataModel("minecraft:block/basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.LIMESTONE, loadDataModel("minecraft:block/limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.GRANITE, loadDataModel("minecraft:block/granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.MARBLE, loadDataModel("minecraft:block/marble")));
+        addDispatch(new BlockModelGeneric<>(Blocks.SLATE, loadDataModel("minecraft:block/slate")));
+        addDispatch(new BlockModelGeneric<>(Blocks.PERMAFROST, loadDataModel( "minecraft:block/permafrost")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_STONE, loadDataModel("minecraft:block/cobbled_stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_STONE_MOSSY, loadDataModel("minecraft:block/cobbled_stone_mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_BASALT, loadDataModel("minecraft:block/cobbled_basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_LIMESTONE, loadDataModel("minecraft:block/cobbled_limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_GRANITE, loadDataModel("minecraft:block/cobbled_granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_PERMAFROST, loadDataModel("minecraft:block/cobbled_permafrost")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_BASALT_MOSSY, loadDataModel("minecraft:block/cobbled_basalt_mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_LIMESTONE_MOSSY, loadDataModel("minecraft:block/cobbled_limestone_mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_GRANITE_MOSSY, loadDataModel("minecraft:block/cobbled_granite_mossy")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.STONE_POLISHED, loadDataModel("minecraft:block/polished_stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.GRANITE_POLISHED, loadDataModel("minecraft:block/polished_granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.LIMESTONE_POLISHED, loadDataModel("minecraft:block/polished_limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BASALT_POLISHED, loadDataModel("minecraft:block/polished_basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.SLATE_POLISHED, loadDataModel("minecraft:block/polished_slate")));
+        addDispatch(new BlockModelGeneric<>(Blocks.PERMAFROST_POLISHED, loadDataModel("minecraft:block/polished_permafrost")));
+        addDispatch(new BlockModelGeneric<>(Blocks.NETHERRACK_POLISHED, loadDataModel("minecraft:block/polished_netherrack")));
+
+        addDispatch(new BlockModelGenericAxis<>(Blocks.PILLAR_MARBLE, loadDataModel("minecraft:block/pillar_marble")));
+        addDispatch(new BlockModelGeneric<>(Blocks.CAPSTONE_MARBLE, loadDataModel("minecraft:block/capstone_marble")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.SANDSTONE, loadDataModel("minecraft:block/sandstone")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.STONE_CARVED, loadDataModel("minecraft:block/carved_stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.GRANITE_CARVED, loadDataModel("minecraft:block/carved_granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.LIMESTONE_CARVED, loadDataModel("minecraft:block/carved_limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BASALT_CARVED, loadDataModel("minecraft:block/carved_basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.PERMAFROST_CARVED, loadDataModel("minecraft:block/carved_permafrost")));
+        addDispatch(new BlockModelGeneric<>(Blocks.NETHERRACK_CARVED, loadDataModel("minecraft:block/carved_netherrack")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.PLANKS_OAK, loadDataModel("minecraft:block/planks/oak")));
+        addDispatch(new BlockModelGenericPlanksPainted<>(Blocks.PLANKS_OAK_PAINTED, loadDataModel("minecraft:block/planks/white")));
+
+        addDispatch(new BlockModelGenericTorch<>(Blocks.TORCH_COAL, "minecraft:block/torch_coal").render3D(false));
+
+        addDispatch(new BlockModelGenericRotatable<>(Blocks.LADDER_OAK, loadDataModel("minecraft:block/ladder")).render3D(false));
+
+        addDispatch(new BlockModelGenericFence<>(Blocks.FENCE_PLANKS_OAK, "minecraft:block/fence/oak"));
+        addDispatch(new BlockModelGenericFencePainted<>(Blocks.FENCE_PLANKS_OAK_PAINTED));
+
+        addDispatch(new BlockModelGenericFenceGate<>(Blocks.FENCE_GATE_PLANKS_OAK, "minecraft:block/fencegate/oak"));
+        addDispatch(new BlockModelGenericFenceGatePainted<>(Blocks.FENCE_GATE_PLANKS_OAK_PAINTED));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.BOOKSHELF_PLANKS_OAK, loadDataModel("minecraft:block/bookshelf")));
+
+        addDispatch(new BlockModelGenericWool<>(Blocks.WOOL, loadDataModel("minecraft:block/wool/white")));
+        addDispatch(new BlockModelGenericRope<>(Blocks.ROPE));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_CLAY, loadDataModel("minecraft:block/brick_clay")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_STONE_POLISHED, loadDataModel("minecraft:block/brick_stone_polished")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_STONE_POLISHED_MOSSY, loadDataModel("minecraft:block/brick_stone_polished_mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_SANDSTONE, loadDataModel("minecraft:block/brick_sandstone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_GOLD, loadDataModel("minecraft:block/brick_gold")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_LAPIS, loadDataModel("minecraft:block/brick_lapis")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_BASALT, loadDataModel("minecraft:block/brick_basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_LIMESTONE, loadDataModel("minecraft:block/brick_limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_GRANITE, loadDataModel("minecraft:block/brick_granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_MARBLE, loadDataModel("minecraft:block/brick_marble")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_SLATE, loadDataModel("minecraft:block/brick_slate")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_STONE, loadDataModel("minecraft:block/brick_stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_PERMAFROST, loadDataModel("minecraft:block/brick_permafrost")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_IRON, loadDataModel("minecraft:block/brick_iron")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_STEEL, loadDataModel("minecraft:block/brick_steel")));
+
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_PLANKS_OAK, loadDataModel("minecraft:block/slab/planks/oak/lower"), loadDataModel("minecraft:block/slab/planks/oak/upper"), loadDataModel("minecraft:block/slab/planks/oak/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_COBBLE_STONE, loadDataModel("minecraft:block/slab/cobbled_stone/lower"), loadDataModel("minecraft:block/slab/cobbled_stone/upper"), loadDataModel("minecraft:block/slab/cobbled_stone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_SANDSTONE, loadDataModel("minecraft:block/slab/sandstone/lower"), loadDataModel("minecraft:block/slab/sandstone/upper"), loadDataModel("minecraft:block/slab/sandstone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_STONE_POLISHED, loadDataModel("minecraft:block/slab/brick_stone_polished/lower"), loadDataModel("minecraft:block/slab/brick_stone_polished/upper"), loadDataModel("minecraft:block/slab/brick_stone_polished/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_STONE_POLISHED, loadDataModel("minecraft:block/slab/polished_stone/lower"), loadDataModel("minecraft:block/slab/polished_stone/upper"), loadDataModel("minecraft:block/slab/polished_stone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_MARBLE, loadDataModel("minecraft:block/slab/brick_marble/lower"), loadDataModel("minecraft:block/slab/brick_marble/upper"), loadDataModel("minecraft:block/slab/brick_marble/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_CLAY, loadDataModel("minecraft:block/slab/brick_clay/lower"), loadDataModel("minecraft:block/slab/brick_clay/upper"), loadDataModel("minecraft:block/slab/brick_clay/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_CAPSTONE_MARBLE, loadDataModel("minecraft:block/slab/capstone_marble/lower"), loadDataModel("minecraft:block/slab/capstone_marble/upper"), loadDataModel("minecraft:block/slab/capstone_marble/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_COBBLE_BASALT, loadDataModel("minecraft:block/slab/cobbled_basalt/lower"), loadDataModel("minecraft:block/slab/cobbled_basalt/upper"), loadDataModel("minecraft:block/slab/cobbled_basalt/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_COBBLE_LIMESTONE, loadDataModel("minecraft:block/slab/cobbled_limestone/lower"), loadDataModel("minecraft:block/slab/cobbled_limestone/upper"), loadDataModel("minecraft:block/slab/cobbled_limestone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_COBBLE_GRANITE, loadDataModel("minecraft:block/slab/cobbled_granite/lower"), loadDataModel("minecraft:block/slab/cobbled_granite/upper"), loadDataModel("minecraft:block/slab/cobbled_granite/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_BASALT, loadDataModel("minecraft:block/slab/brick_basalt/lower"), loadDataModel("minecraft:block/slab/brick_basalt/upper"), loadDataModel("minecraft:block/slab/brick_basalt/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_LIMESTONE, loadDataModel("minecraft:block/slab/brick_limestone/lower"), loadDataModel("minecraft:block/slab/brick_limestone/upper"), loadDataModel("minecraft:block/slab/brick_limestone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_GRANITE, loadDataModel("minecraft:block/slab/brick_granite/lower"), loadDataModel("minecraft:block/slab/brick_granite/upper"), loadDataModel("minecraft:block/slab/brick_granite/full")));
+        addDispatch(new BlockModelGenericSlabPainted<>(Blocks.SLAB_PLANKS_PAINTED));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_SLATE, loadDataModel("minecraft:block/slab/brick_slate/lower"), loadDataModel("minecraft:block/slab/brick_slate/upper"), loadDataModel("minecraft:block/slab/brick_slate/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_STONE, loadDataModel("minecraft:block/slab/brick_stone/lower"), loadDataModel("minecraft:block/slab/brick_stone/upper"), loadDataModel("minecraft:block/slab/brick_stone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_GRANITE_POLISHED, loadDataModel("minecraft:block/slab/polished_granite/lower"), loadDataModel("minecraft:block/slab/polished_granite/upper"), loadDataModel("minecraft:block/slab/polished_granite/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_LIMESTONE_POLISHED, loadDataModel("minecraft:block/slab/polished_limestone/lower"), loadDataModel("minecraft:block/slab/polished_limestone/upper"), loadDataModel("minecraft:block/slab/polished_limestone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BASALT_POLISHED, loadDataModel("minecraft:block/slab/polished_basalt/lower"), loadDataModel("minecraft:block/slab/polished_basalt/upper"), loadDataModel("minecraft:block/slab/polished_basalt/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_PERMAFROST_POLISHED, loadDataModel("minecraft:block/slab/polished_permafrost/lower"), loadDataModel("minecraft:block/slab/polished_permafrost/upper"), loadDataModel("minecraft:block/slab/polished_permafrost/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_COBBLE_PERMAFROST, loadDataModel("minecraft:block/slab/cobbled_permafrost/lower"), loadDataModel("minecraft:block/slab/cobbled_permafrost/upper"), loadDataModel("minecraft:block/slab/cobbled_permafrost/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_SANDSTONE, loadDataModel("minecraft:block/slab/brick_sandstone/lower"), loadDataModel("minecraft:block/slab/brick_sandstone/upper"), loadDataModel("minecraft:block/slab/brick_sandstone/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_PERMAFROST, loadDataModel("minecraft:block/slab/brick_permafrost/lower"), loadDataModel("minecraft:block/slab/brick_permafrost/upper"), loadDataModel("minecraft:block/slab/brick_permafrost/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_IRON, loadDataModel("minecraft:block/slab/brick_iron/lower"), loadDataModel("minecraft:block/slab/brick_iron/upper"), loadDataModel("minecraft:block/slab/brick_iron/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_GOLD, loadDataModel("minecraft:block/slab/brick_gold/lower"), loadDataModel("minecraft:block/slab/brick_gold/upper"), loadDataModel("minecraft:block/slab/brick_gold/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_STEEL, loadDataModel("minecraft:block/slab/brick_steel/lower"), loadDataModel("minecraft:block/slab/brick_steel/upper"), loadDataModel("minecraft:block/slab/brick_steel/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_LAPIS, loadDataModel("minecraft:block/slab/brick_lapis/lower"), loadDataModel("minecraft:block/slab/brick_lapis/upper"), loadDataModel("minecraft:block/slab/brick_lapis/full")));
+
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_PLANKS_OAK, loadDataModel("minecraft:block/stairs/planks/oak")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_COBBLE_STONE, loadDataModel("minecraft:block/stairs/cobbled_stone")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_STONE_POLISHED, loadDataModel("minecraft:block/stairs/brick_stone_polished")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_MARBLE, loadDataModel("minecraft:block/stairs/brick_marble")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_COBBLE_BASALT, loadDataModel("minecraft:block/stairs/cobbled_basalt")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_COBBLE_LIMESTONE, loadDataModel("minecraft:block/stairs/cobbled_limestone")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_COBBLE_GRANITE, loadDataModel("minecraft:block/stairs/cobbled_granite")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_BASALT, loadDataModel("minecraft:block/stairs/brick_basalt")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_LIMESTONE, loadDataModel("minecraft:block/stairs/brick_limestone")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_GRANITE, loadDataModel("minecraft:block/stairs/brick_granite")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_CLAY, loadDataModel("minecraft:block/stairs/brick_clay")));
+        addDispatch(new BlockModelGenericStairsPainted<>(Blocks.STAIRS_PLANKS_PAINTED));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_SLATE, loadDataModel("minecraft:block/stairs/brick_slate")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_STONE, loadDataModel("minecraft:block/stairs/brick_stone")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_SANDSTONE, loadDataModel("minecraft:block/stairs/sandstone")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_COBBLE_PERMAFROST, loadDataModel("minecraft:block/stairs/cobbled_permafrost")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_SANDSTONE, loadDataModel("minecraft:block/stairs/brick_sandstone")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_PERMAFROST, loadDataModel("minecraft:block/stairs/brick_permafrost")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_IRON, loadDataModel("minecraft:block/stairs/brick_iron")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_GOLD, loadDataModel("minecraft:block/stairs/brick_gold")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_STEEL, loadDataModel("minecraft:block/stairs/brick_steel")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_LAPIS, loadDataModel("minecraft:block/stairs/brick_lapis")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.OBSIDIAN, loadDataModel("minecraft:block/obsidian")));
+
+        addDispatch(new BlockModelGlass<>(Blocks.GLASS, "minecraft:block/glass/").setAllTextures("minecraft:block/glass"));
+        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 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")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.DIRT, loadDataModel("minecraft:block/dirt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.DIRT_SCORCHED, loadDataModel("minecraft:block/dirt_scorched")));
+        addDispatch(new BlockModelGeneric<>(Blocks.DIRT_SCORCHED_RICH, loadDataModel("minecraft:block/dirt_scorched_rich")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.MUD, loadDataModel("minecraft:block/mud")));
+        addDispatch(new BlockModelGeneric<>(Blocks.MUD_BAKED, loadDataModel("minecraft:block/mud_baked")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.SPONGE_DRY, loadDataModel("minecraft:block/sponge")));
+        addDispatch(new BlockModelGeneric<>(Blocks.SPONGE_WET, loadDataModel("minecraft:block/sponge_wet")));
+        addDispatch(new BlockModelGeneric<>(Blocks.PUMICE_DRY, loadDataModel("minecraft:block/pumice")));
+        addDispatch(new BlockModelGeneric<>(Blocks.PUMICE_WET, loadDataModel("minecraft:block/pumice_wet")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.MOSS_STONE, loadDataModel("minecraft:block/stone_mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.MOSS_BASALT, loadDataModel("minecraft:block/basalt_mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.MOSS_LIMESTONE, loadDataModel("minecraft:block/limestone_mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.MOSS_GRANITE, loadDataModel("minecraft:block/granite_mossy")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.SAND, loadDataModel("minecraft:block/sand")));
+        addDispatch(new BlockModelGeneric<>(Blocks.GRAVEL, loadDataModel("minecraft:block/gravel")));
+        addDispatch(new BlockModelGeneric<>(Blocks.SULFUR, loadDataModel("minecraft:block/sulfur")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.BEDROCK, loadDataModel("minecraft:block/bedrock")));
+        addDispatch(new BlockModelGenericFullyRotatable<>(Blocks.BONESHALE, loadDataModel("minecraft:block/bone_shale")));
 
         addDispatch(new BlockModelFluid<>(Blocks.FLUID_WATER_FLOWING)
             .onRenderLayer(1)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/water_flowing")
-            .setTex(BLOCK_TEXTURES, "minecraft:block/water_still", Side.TOP));
+            .setAllTextures("minecraft:block/water_flowing")
+            .setTex("minecraft:block/water_still", Side.TOP));
         addDispatch(new BlockModelFluid<>(Blocks.FLUID_WATER_STILL)
             .onRenderLayer(1)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/water_still", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/water_flowing", S_SIDES));
+            .setTex("minecraft:block/water_still", S_TB)
+            .setTex("minecraft:block/water_flowing", S_SIDES));
         addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_FLOWING)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/lava_flowing")
-            .setTex(BLOCK_TEXTURES, "minecraft:block/lava_still", Side.TOP));
+            .setAllTextures("minecraft:block/lava_flowing")
+            .setTex("minecraft:block/lava_still", Side.TOP));
         addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_STILL)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/lava_still", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/lava_flowing", S_SIDES));
-
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_OAK)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/oak_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/oak_side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_PINE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/pine_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/pine_side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_BIRCH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/birch_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/birch_side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_CHERRY)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/cherry_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/cherry_side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_EUCALYPTUS)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/eucalyptus_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/eucalyptus_side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_OAK_MOSSY)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/oak_mossy_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/oak_mossy_side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_THORN)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/thorn_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/thorn_side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.LOG_PALM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/palm_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/log/palm_side", S_SIDES));
-
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_OAK, "minecraft:block/leaves/oak", true));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_OAK_RETRO, "minecraft:block/leaves/oak_retro"));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_PINE, "minecraft:block/leaves/pine"));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_BIRCH, "minecraft:block/leaves/birch"));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_CHERRY, "minecraft:block/leaves/cherry"));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_EUCALYPTUS, "minecraft:block/leaves/eucalyptus"));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_SHRUB, "minecraft:block/leaves/shrub"));
-        addDispatch(new BlockModelLeavesCherryFlowering<>(Blocks.LEAVES_CHERRY_FLOWERING));
-        addDispatch(new BlockModelLeavesCacao<>(Blocks.LEAVES_CACAO));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_THORN, "minecraft:block/leaves/caatinga"));
-        addDispatch(new BlockModelLeaves<>(Blocks.LEAVES_PALM, "minecraft:block/leaves/palm"));
-
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_OAK)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/oak")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/sapling/oak_retro"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_OAK_RETRO).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/oak_retro"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_PINE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/pine"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_BIRCH).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/birch"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_CHERRY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/cherry"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_EUCALYPTUS).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/eucalyptus"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_SHRUB).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/shrub"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_CACAO).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/cacao"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_THORN).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/thorn"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SAPLING_PALM).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sapling/palm"));
-
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.TALLGRASS).setAllTextures(BLOCK_TEXTURES, "minecraft:block/tallgrass"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.TALLGRASS_FERN).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fern"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.DEADBUSH).setAllTextures(BLOCK_TEXTURES, "minecraft:block/deadbush"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SPINIFEX).setAllTextures(BLOCK_TEXTURES, "minecraft:block/spinifex"));
-        addDispatch(new BlockModelAlgae<>(Blocks.ALGAE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/algae").withCustomItemBounds(0.0f, 0.01f, 0.0f, 1.0f, 0.0125f, 1.0f));
-
-        addDispatch(new BlockModelFlowerStackable<>(Blocks.FLOWER_YELLOW, "minecraft:block/flower_yellow/"));
-        addDispatch(new BlockModelFlowerStackable<>(Blocks.FLOWER_RED, "minecraft:block/flower_red/"));
-        addDispatch(new BlockModelFlowerStackable<>(Blocks.FLOWER_PINK, "minecraft:block/flower_pink/"));
-        addDispatch(new BlockModelFlowerStackable<>(Blocks.FLOWER_PURPLE, "minecraft:block/flower_purple/"));
-        addDispatch(new BlockModelFlowerStackable<>(Blocks.FLOWER_LIGHT_BLUE, "minecraft:block/flower_lightblue/"));
-        addDispatch(new BlockModelFlowerStackable<>(Blocks.FLOWER_ORANGE, "minecraft:block/flower_orange/"));
-
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.MUSHROOM_BROWN).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mushroom_brown"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.MUSHROOM_RED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mushroom_red"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_COAL_STONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/coal/stone")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/ore/coal/stone_retro"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_COAL_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/coal/basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_COAL_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/coal/limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_COAL_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/coal/granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_COAL_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/coal/permafrost"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_IRON_STONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/iron/stone")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/ore/iron/stone_retro"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_IRON_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/iron/basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_IRON_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/iron/limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_IRON_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/iron/granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_IRON_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/iron/permafrost"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_GOLD_STONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/gold/stone")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/ore/gold/stone_retro"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_GOLD_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/gold/basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_GOLD_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/gold/limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_GOLD_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/gold/granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_GOLD_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/gold/permafrost"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_LAPIS_STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/lapis/stone"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_LAPIS_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/lapis/basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_LAPIS_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/lapis/limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_LAPIS_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/lapis/granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_LAPIS_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/lapis/permafrost"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_STONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/stone")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/ore/redstone/stone_retro"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/permafrost"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_GLOWING_STONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/stone_active")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/ore/redstone/stone_retro_active"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_GLOWING_BASALT)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/basalt_active"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_GLOWING_LIMESTONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/limestone_active"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_GLOWING_GRANITE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/granite_active"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_REDSTONE_GLOWING_PERMAFROST)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/redstone/permafrost_active"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_DIAMOND_STONE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/diamond/stone")
-            .setAllTextures(RETRO_BLOCK_TEXTURES, "minecraft:block/ore/diamond/stone_retro"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_DIAMOND_BASALT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/diamond/basalt"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_DIAMOND_LIMESTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/diamond/limestone"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_DIAMOND_GRANITE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/diamond/granite"));
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_DIAMOND_PERMAFROST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/diamond/permafrost"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.CRYSTAL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/nether_crystal/crystal"));
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.CRYSTAL_STALK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/nether_crystal/stalk"));
-        addDispatch(new BlockModelCrystallineNetherrack<>(Blocks.NETHERRACK_CRYSTALLINE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/nether_crystal/crystal_netherrack"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.ORE_NETHERCOAL_NETHERRACK)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/ore/nethercoal/netherrack"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_COAL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_coal"));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_IRON)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_iron/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_iron/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_iron/side", S_SIDES)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_iron/top_retro", Side.TOP)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_iron/bottom_retro", Side.BOTTOM)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_iron/side_retro", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_GOLD)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_gold/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_gold/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_gold/side", S_SIDES)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_gold/top_retro", Side.TOP)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_gold/bottom_retro", Side.BOTTOM)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_gold/side_retro", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_LAPIS).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_lapis"));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_REDSTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_redstone"));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_DIAMOND)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_diamond/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_diamond/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_diamond/side", S_SIDES)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_diamond/top_retro", Side.TOP)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_diamond/bottom_retro", Side.BOTTOM)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/block_diamond/side_retro", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_NETHER_COAL)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_nethercoal"));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_STEEL)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_steel/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_steel/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_steel/side", S_SIDES));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_QUARTZ).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_quartz"));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_OLIVINE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_olivine"));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_CHARCOAL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_charcoal"));
+            .setTex("minecraft:block/lava_still", S_TB)
+            .setTex("minecraft:block/lava_flowing", S_SIDES));
+
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_OAK, loadDataModel("minecraft:block/log/oak")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_PINE, loadDataModel("minecraft:block/log/pine")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_BIRCH, loadDataModel("minecraft:block/log/birch")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_CHERRY, loadDataModel("minecraft:block/log/cherry")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_EUCALYPTUS, loadDataModel("minecraft:block/log/eucalyptus")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_OAK_MOSSY, loadDataModel("minecraft:block/log/oak_mossy")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_THORN, loadDataModel("minecraft:block/log/thorn")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_PALM, loadDataModel("minecraft:block/log/palm")));
+
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_OAK, "minecraft:block/leaves/oak"));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_OAK_RETRO, "minecraft:block/leaves/oak_retro"));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_PINE, "minecraft:block/leaves/pine"));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_BIRCH, "minecraft:block/leaves/birch"));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_CHERRY, "minecraft:block/leaves/cherry"));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_EUCALYPTUS, "minecraft:block/leaves/eucalyptus"));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_SHRUB, "minecraft:block/leaves/shrub"));
+        addDispatch(new BlockModelGenericLeavesCherryFlowering<>(Blocks.LEAVES_CHERRY_FLOWERING));
+        addDispatch(new BlockModelGenericLeavesCacao<>(Blocks.LEAVES_CACAO));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_THORN, "minecraft:block/leaves/thorn"));
+        addDispatch(new BlockModelGenericLeaves<>(Blocks.LEAVES_PALM, "minecraft:block/leaves/palm"));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_OAK, loadDataModel("minecraft:block/sapling/oak")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_OAK_RETRO, loadDataModel("minecraft:block/sapling/oak_retro")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_PINE, loadDataModel("minecraft:block/sapling/pine")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_BIRCH, loadDataModel("minecraft:block/sapling/birch")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_CHERRY, loadDataModel("minecraft:block/sapling/cherry")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_EUCALYPTUS, loadDataModel("minecraft:block/sapling/eucalyptus")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_SHRUB, loadDataModel("minecraft:block/sapling/shrub")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_CACAO, loadDataModel("minecraft:block/sapling/cacao")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_THORN, loadDataModel("minecraft:block/sapling/thorn")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.SAPLING_PALM, loadDataModel("minecraft:block/sapling/palm")).render3D(false));
+
+        addDispatch(new BlockModelGenericShifted<>(Blocks.TALLGRASS, loadDataModel("minecraft:block/tallgrass")).render3D(false));
+        addDispatch(new BlockModelGenericShifted<>(Blocks.TALLGRASS_FERN, loadDataModel("minecraft:block/fern")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.DEADBUSH, loadDataModel("minecraft:block/deadbush")).render3D(false));
+        addDispatch(new BlockModelGenericShifted<>(Blocks.SPINIFEX, loadDataModel("minecraft:block/spinifex")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.ALGAE, loadDataModel("minecraft:block/algae")).render3D(false));
+
+        addDispatch(new BlockModelGenericFlowerStackable<>(Blocks.FLOWER_YELLOW, "minecraft:block/flower_yellow/").render3D(false));
+        addDispatch(new BlockModelGenericFlowerStackable<>(Blocks.FLOWER_RED, "minecraft:block/flower_red/").render3D(false));
+        addDispatch(new BlockModelGenericFlowerStackable<>(Blocks.FLOWER_PINK, "minecraft:block/flower_pink/").render3D(false));
+        addDispatch(new BlockModelGenericFlowerStackable<>(Blocks.FLOWER_PURPLE, "minecraft:block/flower_purple/").render3D(false));
+        addDispatch(new BlockModelGenericFlowerStackable<>(Blocks.FLOWER_LIGHT_BLUE, "minecraft:block/flower_lightblue/").render3D(false));
+        addDispatch(new BlockModelGenericFlowerStackable<>(Blocks.FLOWER_ORANGE, "minecraft:block/flower_orange/").render3D(false));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.MUSHROOM_BROWN, loadDataModel("minecraft:block/mushroom_brown")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.MUSHROOM_RED, loadDataModel("minecraft:block/mushroom_red")).render3D(false));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_COAL_STONE, loadDataModel("minecraft:block/ore/coal/stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_COAL_BASALT, loadDataModel("minecraft:block/ore/coal/basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_COAL_LIMESTONE, loadDataModel("minecraft:block/ore/coal/limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_COAL_GRANITE, loadDataModel("minecraft:block/ore/coal/granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_COAL_PERMAFROST, loadDataModel("minecraft:block/ore/coal/permafrost")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_IRON_STONE, loadDataModel("minecraft:block/ore/iron/stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_IRON_BASALT, loadDataModel("minecraft:block/ore/iron/basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_IRON_LIMESTONE, loadDataModel("minecraft:block/ore/iron/limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_IRON_GRANITE, loadDataModel("minecraft:block/ore/iron/granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_IRON_PERMAFROST, loadDataModel("minecraft:block/ore/iron/permafrost")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_GOLD_STONE, loadDataModel("minecraft:block/ore/gold/stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_GOLD_BASALT, loadDataModel("minecraft:block/ore/gold/basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_GOLD_LIMESTONE, loadDataModel("minecraft:block/ore/gold/limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_GOLD_GRANITE, loadDataModel("minecraft:block/ore/gold/granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_GOLD_PERMAFROST, loadDataModel("minecraft:block/ore/gold/permafrost")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_LAPIS_STONE, loadDataModel("minecraft:block/ore/lapis/stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_LAPIS_BASALT, loadDataModel("minecraft:block/ore/lapis/basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_LAPIS_LIMESTONE, loadDataModel("minecraft:block/ore/lapis/limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_LAPIS_GRANITE, loadDataModel("minecraft:block/ore/lapis/granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_LAPIS_PERMAFROST, loadDataModel("minecraft:block/ore/lapis/permafrost")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_STONE, loadDataModel("minecraft:block/ore/redstone/stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_BASALT, loadDataModel("minecraft:block/ore/redstone/basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_LIMESTONE, loadDataModel("minecraft:block/ore/redstone/limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_GRANITE, loadDataModel("minecraft:block/ore/redstone/granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_PERMAFROST, loadDataModel("minecraft:block/ore/redstone/permafrost")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_GLOWING_STONE, loadDataModel("minecraft:block/ore/redstone/stone_active")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_GLOWING_BASALT, loadDataModel("minecraft:block/ore/redstone/basalt_active")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_GLOWING_LIMESTONE, loadDataModel("minecraft:block/ore/redstone/limestone_active")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_GLOWING_GRANITE, loadDataModel("minecraft:block/ore/redstone/granite_active")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_REDSTONE_GLOWING_PERMAFROST, loadDataModel("minecraft:block/ore/redstone/permafrost_active")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_DIAMOND_STONE, loadDataModel("minecraft:block/ore/diamond/stone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_DIAMOND_BASALT, loadDataModel("minecraft:block/ore/diamond/basalt")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_DIAMOND_LIMESTONE, loadDataModel("minecraft:block/ore/diamond/limestone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_DIAMOND_GRANITE, loadDataModel("minecraft:block/ore/diamond/granite")));
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_DIAMOND_PERMAFROST, loadDataModel("minecraft:block/ore/diamond/permafrost")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.CRYSTAL, loadDataModel("minecraft:block/nether_crystal/crystal")));
+        addDispatch(new BlockModelGeneric<>(Blocks.CRYSTAL_STALK, loadDataModel("minecraft:block/nether_crystal/stalk")).render3D(false));
+        addDispatch(new BlockModelGeneric<>(Blocks.NETHERRACK_CRYSTALLINE, loadDataModel("minecraft:block/nether_crystal/crystal_netherrack")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ORE_NETHERCOAL_NETHERRACK, loadDataModel("minecraft:block/ore/nethercoal/netherrack")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_COAL, loadDataModel("minecraft:block/block_coal")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_IRON, loadDataModel("minecraft:block/block_iron")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_GOLD, loadDataModel("minecraft:block/block_gold")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_LAPIS, loadDataModel("minecraft:block/block_lapis")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_REDSTONE, loadDataModel("minecraft:block/block_redstone")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_DIAMOND, loadDataModel("minecraft:block/block_diamond")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_NETHER_COAL, loadDataModel("minecraft:block/block_nethercoal")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_STEEL, loadDataModel("minecraft:block/block_steel")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_QUARTZ, loadDataModel("minecraft:block/block_quartz")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_OLIVINE, loadDataModel("minecraft:block/block_olivine")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_CHARCOAL, loadDataModel("minecraft:block/block_charcoal")));
 
         addDispatch(new BlockModelWireRedstone<>(Blocks.WIRE_REDSTONE));
 
-        addDispatch(new BlockModelTorchRedstone<>(Blocks.TORCH_REDSTONE_IDLE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/torch_redstone_idle"));
-        addDispatch(new BlockModelTorchRedstone<>(Blocks.TORCH_REDSTONE_ACTIVE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/torch_redstone_active"));
+        addDispatch(new BlockModelGenericTorch<>(Blocks.TORCH_REDSTONE_IDLE, "minecraft:block/torch_redstone_idle").render3D(false));
+        addDispatch(new BlockModelGenericTorch<>(Blocks.TORCH_REDSTONE_ACTIVE, "minecraft:block/torch_redstone_active").render3D(false));
 
-        final float width = 0.1875F;
-        final float height = 0.125F;
-        final float depth = 0.125F;
-        addDispatch(new BlockModelStandard<>(Blocks.BUTTON_STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/stone").withCustomItemBounds(0.5F - width, 0.5F - height, 0.5F - depth, 0.5F + width, 0.5F + height, 0.5F + depth));
-        addDispatch(new BlockModelStandard<>(Blocks.BUTTON_PLANKS).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak").withCustomItemBounds(0.5F - width, 0.5F - height, 0.5F - depth, 0.5F + width, 0.5F + height, 0.5F + depth));
-        addDispatch(new BlockModelButtonPainted<>(Blocks.BUTTON_PLANKS_PAINTED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak").withCustomItemBounds(0.5F - width, 0.5F - height, 0.5F - depth, 0.5F + width, 0.5F + height, 0.5F + depth));
+        addDispatch(new BlockModelGenericButton<>(Blocks.BUTTON_STONE, "minecraft:block/button/stone"));
+        addDispatch(new BlockModelGenericButton<>(Blocks.BUTTON_PLANKS, "minecraft:block/button/planks/oak"));
+        addDispatch(new BlockModelGenericButtonPainted<>(Blocks.BUTTON_PLANKS_PAINTED));
 
-        addDispatch(new BlockModelLever<>(Blocks.LEVER_COBBLE_STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/lever_cobbled_stone"));
+        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 BlockModelStandard<>(Blocks.PRESSURE_PLATE_STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/stone").withCustomItemBounds(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2));
-        addDispatch(new BlockModelStandard<>(Blocks.PRESSURE_PLATE_PLANKS_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak").withCustomItemBounds(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2));
-        addDispatch(new BlockModelStandard<>(Blocks.PRESSURE_PLATE_COBBLE_STONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_stone").withCustomItemBounds(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2));
-        addDispatch(new BlockModelPressurePlatePainted<>(Blocks.PRESSURE_PLATE_PLANKS_OAK_PAINTED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak").withCustomItemBounds(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2));
-
-        addDispatch(new BlockModelVeryRotatable<>(Blocks.MOTION_SENSOR_IDLE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/motion_sensor/side")
-            .setTex(BLOCK_TEXTURES, "minecraft:block/motion_sensor/idle_front", Side.SOUTH));
-        addDispatch(new BlockModelVeryRotatable<>(Blocks.MOTION_SENSOR_ACTIVE)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/motion_sensor/side")
-            .setTex(BLOCK_TEXTURES, "minecraft:block/motion_sensor/active_front", Side.SOUTH));
-
-        addDispatch(new BlockModelRepeater(Blocks.REPEATER_IDLE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/repeater/idle_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_stone_top", S_SIDES));
-        addDispatch(new BlockModelRepeater(Blocks.REPEATER_ACTIVE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/repeater/active_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/polished_stone_top", S_SIDES));
-
-        addDispatch(new BlockModelPiston<>(Blocks.PISTON_BASE,
-            TextureRegistry.getTexture("minecraft:block/piston/face"))
-            .setPistonTextures("minecraft:block/piston/side", "minecraft:block/piston/top", "minecraft:block/piston/bottom")
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/piston/face")
-            .withCustomItemBounds(0, 0, 0, 1, 1, 1));
-        addDispatch(new BlockModelPiston<>(Blocks.PISTON_BASE_STICKY,
-            TextureRegistry.getTexture("minecraft:block/piston_sticky/face"))
-            .setPistonTextures("minecraft:block/piston_sticky/side", "minecraft:block/piston_sticky/top", "minecraft:block/piston_sticky/bottom")
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/piston_sticky/face")
-            .withCustomItemBounds(0, 0, 0, 1, 1, 1));
-        addDispatch(new BlockModelPiston<>(Blocks.PISTON_BASE_STEEL,
-            TextureRegistry.getTexture("minecraft:block/piston_steel/face"), 6 / 16d)
-            .setPistonTextures("minecraft:block/piston_steel/side", "minecraft:block/piston_steel/top", "minecraft:block/piston_steel/bottom")
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/piston_steel/face")
-            .withCustomItemBounds(0, 0, 0, 1, 1, 1));
-
-        addDispatch(new BlockModelPistonHead(Blocks.PISTON_HEAD, TextureRegistry.getTexture("minecraft:block/piston/head"), TextureRegistry.getTexture("minecraft:block/piston/shaft")).setAllTextures(BLOCK_TEXTURES, "minecraft:block/piston/face"));
-        addDispatch(new BlockModelEmpty<>(Blocks.PISTON_MOVING).setAllTextures(BLOCK_TEXTURES, (IconCoordinate) null));
-        addDispatch(new BlockModelPistonHead(Blocks.PISTON_HEAD_STEEL, TextureRegistry.getTexture("minecraft:block/piston_steel/head"), TextureRegistry.getTexture("minecraft:block/piston_steel/shaft"), 6 / 16d, 8d / 16d).setAllTextures(BLOCK_TEXTURES, "minecraft:block/piston_steel/face"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.NOTEBLOCK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/noteblock"));
-
-        addDispatch(new BlockModelRail<>(Blocks.RAIL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/rail/straight"));
-        addDispatch(new BlockModelRail<>(Blocks.RAIL_POWERED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/rail_powered/idle"));
-        addDispatch(new BlockModelRail<>(Blocks.RAIL_DETECTOR).setAllTextures(BLOCK_TEXTURES, "minecraft:block/rail_detector/straight"));
-
-        addDispatch(new BlockModelSpikes<>(Blocks.SPIKES)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/spikes/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/spikes/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/spikes/side", S_SIDES));
-
-        addDispatch(new BlockModelVeryRotatable<>(Blocks.DISPENSER_COBBLE_STONE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/dispenser/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/dispenser/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/dispenser/side", Side.NORTH, Side.EAST, Side.WEST)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/dispenser/front", Side.SOUTH));
-        addDispatch(new BlockModelActivator<>(Blocks.ACTIVATOR_COBBLE_NETHERRACK)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/activator/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/activator/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/activator/side", Side.NORTH, Side.EAST, Side.WEST)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/activator/front", Side.SOUTH));
-
-        addDispatch(new BlockModelTrapDoor<>(Blocks.TRAPDOOR_PLANKS_OAK)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/planks/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/planks/side", S_SIDES));
-        addDispatch(new BlockModelTrapDoor<>(Blocks.TRAPDOOR_IRON)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/iron/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/iron/side", S_SIDES));
-        addDispatch(new BlockModelTrapDoor<>(Blocks.TRAPDOOR_GLASS)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/glass/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/glass/side", S_SIDES));
-        addDispatch(new BlockModelTrapDoorPainted<>(Blocks.TRAPDOOR_PLANKS_PAINTED));
-        addDispatch(new BlockModelTrapDoor<>(Blocks.TRAPDOOR_STEEL)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/steel/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trapdoor/steel/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.TNT)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/tnt/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/tnt/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/tnt/side", S_SIDES));
-
-        addDispatch(new BlockModelDoor<>(Blocks.DOOR_PLANKS_OAK_BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/bottom", S_SIDES));
-        addDispatch(new BlockModelDoor<>(Blocks.DOOR_PLANKS_OAK_TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/top", S_SIDES));
-        addDispatch(new BlockModelDoor<>(Blocks.DOOR_IRON_BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/iron/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/iron/bottom", S_SIDES));
-        addDispatch(new BlockModelDoor<>(Blocks.DOOR_IRON_TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/iron/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/iron/top", S_SIDES));
-        addDispatch(new BlockModelDoorPainted<>(Blocks.DOOR_PLANKS_PAINTED_BOTTOM, false)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/bottom", S_SIDES));
-        addDispatch(new BlockModelDoorPainted<>(Blocks.DOOR_PLANKS_PAINTED_TOP, true)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/planks/top", S_SIDES));
-        addDispatch(new BlockModelDoorGlass<>(Blocks.DOOR_GLASS_BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/glass/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/glass/bottom", S_SIDES));
-        addDispatch(new BlockModelDoorGlass<>(Blocks.DOOR_GLASS_TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/glass/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/glass/top", S_SIDES));
-        addDispatch(new BlockModelDoor<>(Blocks.DOOR_STEEL_BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/steel/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/steel/bottom", S_SIDES));
-        addDispatch(new BlockModelDoor<>(Blocks.DOOR_STEEL_TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/steel/frame_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/door/steel/top", S_SIDES));
-
-        addDispatch(new BlockModelTransparent<>(Blocks.MESH, true).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mesh"));
-        addDispatch(new BlockModelTransparent<>(Blocks.MESH_GOLD, true).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mesh_gold"));
-
-        addDispatch(new BlockModelBed<>(Blocks.BED));
-        addDispatch(new BlockModelSeat<>(Blocks.SEAT)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/seat/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/seat/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/seat/side", S_SIDES));
-
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.COBWEB).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobweb"));
-        addDispatch(new BlockModelFire<>(Blocks.FIRE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fire"));
-        addDispatch(new BlockModelBrazier<>(Blocks.BRAZIER_INACTIVE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/brazier/base", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/brazier/side", S_SIDES));
-        addDispatch(new BlockModelBrazier<>(Blocks.BRAZIER_ACTIVE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/brazier/base", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/brazier/side", S_SIDES));
-        addDispatch(new BlockModelFire<>(Blocks.FIRE_COLD).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fire_cold"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.MOBSPAWNER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mobspawner"));
-        addDispatch(new BlockModelTransparent<>(Blocks.MOBSPAWNER_DEACTIVATED, true).setAllTextures(BLOCK_TEXTURES, "minecraft:block/mobspawner"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.WORKBENCH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/workbench/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/workbench/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/workbench/front", Side.NORTH, Side.SOUTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/workbench/side", Side.WEST, Side.EAST));
-
-        addDispatch(new BlockModelFurnace<>(Blocks.FURNACE_STONE_IDLE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/idle_front", Side.NORTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/side", Side.WEST, Side.EAST, Side.SOUTH));
-        addDispatch(new BlockModelFurnace<>(Blocks.FURNACE_STONE_ACTIVE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/active_front", Side.NORTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_stone/side", Side.WEST, Side.EAST, Side.SOUTH));
-        addDispatch(new BlockModelFurnace<>(Blocks.FURNACE_BLAST_IDLE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/idle_front", Side.NORTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/side", Side.WEST, Side.EAST, Side.SOUTH));
-        addDispatch(new BlockModelFurnace<>(Blocks.FURNACE_BLAST_ACTIVE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/active_front", Side.NORTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/furnace_blast/side", Side.WEST, Side.EAST, Side.SOUTH));
-
-        addDispatch(new BlockModelHorizontalRotation<>(Blocks.TROMMEL_IDLE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/idle_front", Side.NORTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/idle_back", Side.SOUTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/side", Side.WEST)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/side_slot", Side.EAST));
-        addDispatch(new BlockModelHorizontalRotation<>(Blocks.TROMMEL_ACTIVE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/active_front", Side.NORTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/active_back", Side.SOUTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/side", Side.WEST)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/trommel/side_slot", Side.EAST));
-
-        addDispatch(new BlockModelStandard<>(Blocks.CHEST_LEGACY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/chest/planks/top"));
-        addDispatch(new BlockModelStandard<>(Blocks.CHEST_LEGACY_PAINTED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/chest/planks/top"));
-        addDispatch(new BlockModelChest<>(Blocks.CHEST_PLANKS_OAK, "minecraft:block/chest/planks/").setAllTextures(BLOCK_TEXTURES, "minecraft:block/chest/planks/top"));
-        addDispatch(new BlockModelChestPainted<>(Blocks.CHEST_PLANKS_OAK_PAINTED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/chest/planks/top"));
-
-        addDispatch(new BlockModelCropsWheat<>(Blocks.CROPS_WHEAT));
-        addDispatch(new BlockModelCropsPumpkin<>(Blocks.CROPS_PUMPKIN));
-
-        addDispatch(new BlockModelFarmland<>(Blocks.FARMLAND_DIRT).setAllTextures(BLOCK_TEXTURES, "minecraft:block/farmland/dry"));
-
-        addDispatch(new BlockModelEmpty<>(Blocks.SIGN_POST_PLANKS_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-        addDispatch(new BlockModelEmpty<>(Blocks.SIGN_WALL_PLANKS_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-        addDispatch(new BlockModelEmpty<>(Blocks.FLAG).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-        addDispatch(new BlockModelSignPainted<>(Blocks.SIGN_POST_PLANKS_OAK_PAINTED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-        addDispatch(new BlockModelSignPainted<>(Blocks.SIGN_WALL_PLANKS_OAK_PAINTED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/planks/oak"));
-
-        addDispatch(new BlockModelLayer<>(Blocks.LAYER_SNOW).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_snow"));
-        addDispatch(new BlockModelLayer<>(Blocks.LAYER_LEAVES_OAK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/leaves/oak_fancy"));
-        addDispatch(new BlockModelLayer<>(Blocks.LAYER_SLATE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/slate_top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/slate_side", S_SIDES));
-        addDispatch(new BlockModelLayer<>(Blocks.LAYER_ASH).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_ash"));
-
-        addDispatch(new BlockModelTransparent<>(Blocks.ICE, false).onRenderLayer(1).setAllTextures(BLOCK_TEXTURES, "minecraft:block/ice"));
-        addDispatch(new BlockModelStandard<>(Blocks.PERMAICE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/permaice"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_SNOW).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_snow"));
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_ASH).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_ash"));
-
-        addDispatch(new BlockModelCactus<>(Blocks.CACTUS).withCustomItemBounds(0, 0, 0, 1, 1, 1)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/cactus/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/cactus/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/cactus/side", S_SIDES)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/cactus/top_retro", Side.TOP)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/cactus/bottom_retro", Side.BOTTOM)
-            .setTex(RETRO_BLOCK_TEXTURES, "minecraft:block/cactus/side_retro", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.BLOCK_CLAY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/block_clay"));
-
-        addDispatch(new BlockModelCrossedSquares<>(Blocks.SUGARCANE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/sugarcane"));
-
-        addDispatch(new BlockModelAxisAligned<>(Blocks.BLOCK_SUGARCANE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_sugarcane/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_sugarcane/side", S_SIDES));
-        addDispatch(new BlockModelAxisAligned<>(Blocks.BLOCK_SUGARCANE_BAKED)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_baked_sugarcane/top", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/block_baked_sugarcane/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.JUKEBOX)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/jukebox/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/jukebox/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/jukebox/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.PUMPKIN)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin/side", S_SIDES));
-        addDispatch(new BlockModelVeryRotatable<>(Blocks.PUMPKIN_CARVED_IDLE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved/front", Side.SOUTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved/side", Side.WEST, Side.EAST, Side.NORTH));
-        addDispatch(new BlockModelVeryRotatable<>(Blocks.PUMPKIN_CARVED_ACTIVE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved_lit/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved_lit/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved_lit/front", Side.SOUTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_carved_lit/side", Side.WEST, Side.EAST, Side.NORTH));
-        addDispatch(new BlockModelVeryRotatable<>(Blocks.PUMPKIN_REDSTONE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_redstone/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_redstone/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_redstone/front", Side.SOUTH)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_redstone/side", Side.WEST, Side.EAST, Side.NORTH));
-
-
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_NETHERRACK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_netherrack/normal"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_NETHERRACK_IGNEOUS)
-            .setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_netherrack/igneous"));
-        addDispatch(new BlockModelStandard<>(Blocks.COBBLE_NETHERRACK_MOSSY).setAllTextures(BLOCK_TEXTURES, "minecraft:block/cobbled_netherrack/mossy"));
-        addDispatch(new BlockModelStandard<>(Blocks.NETHERRACK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/netherrack"));
-        addDispatch(new BlockModelStandard<>(Blocks.BRICK_NETHERRACK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/brick_netherrack"));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_NETHERRACK_POLISHED));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_COBBLE_NETHERRACK));
-        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_NETHERRACK));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_NETHERRACK));
-        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_NETHERRACK));
-
-        addDispatch(new BlockModelStandard<>(Blocks.SOULSAND).setAllTextures(BLOCK_TEXTURES, "minecraft:block/soulsand"));
-        addDispatch(new BlockModelStandard<>(Blocks.SOULSCHIST).setAllTextures(BLOCK_TEXTURES, "minecraft:block/soulschist"));
-
-        addDispatch(new BlockModelStandard<>(Blocks.GLOWSTONE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/glowstone"));
-
-        addDispatch(new BlockModelPortal<>(Blocks.PORTAL_NETHER, "minecraft:block/portal_nether/").setAllTextures(BLOCK_TEXTURES, "minecraft:block/portal_nether"));
-        addDispatch(new BlockModelPortal<>(Blocks.PORTAL_DRIFT, "minecraft:block/portal_drift/").setAllTextures(BLOCK_TEXTURES, "minecraft:block/portal_nether"));
-
-        addDispatch(new BlockModelCake<>(Blocks.CAKE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/cake/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/cake/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/cake/side", S_SIDES));
-        addDispatch(new BlockModelPiePumpkin<>(Blocks.PUMPKIN_PIE)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_pie/top", Side.TOP)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_pie/bottom", Side.BOTTOM)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/pumpkin_pie/side", S_SIDES));
-
-        addDispatch(new BlockModelLamp<>(Blocks.LAMP_IDLE));
-        addDispatch(new BlockModelLamp<>(Blocks.LAMP_ACTIVE));
-        addDispatch(new BlockModelLamp<>(Blocks.LAMP_INVERTED_IDLE));
-        addDispatch(new BlockModelLamp<>(Blocks.LAMP_INVERTED_ACTIVE));
-
-        addDispatch(new BlockModelLantern<>(Blocks.LANTERN_FIREFLY_GREEN).setAllTextures(BLOCK_TEXTURES, "minecraft:block/lantern_firefly/green"));
-        addDispatch(new BlockModelLantern<>(Blocks.LANTERN_FIREFLY_BLUE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/lantern_firefly/blue"));
-        addDispatch(new BlockModelLantern<>(Blocks.LANTERN_FIREFLY_ORANGE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/lantern_firefly/orange"));
-        addDispatch(new BlockModelLantern<>(Blocks.LANTERN_FIREFLY_RED).setAllTextures(BLOCK_TEXTURES, "minecraft:block/lantern_firefly/red"));
-        addDispatch(new BlockModelJar<>(Blocks.JAR_GLASS));
-
-        addDispatch(new BlockModelJarButterfly<>(Blocks.JAR_BUTTERFLY_BLUE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/jar_butterfly"));
-        addDispatch(new BlockModelJarButterfly<>(Blocks.JAR_BUTTERFLY_ORANGE).setAllTextures(BLOCK_TEXTURES, "minecraft:block/jar_butterfly"));
-        addDispatch(new BlockModelJarButterfly<>(Blocks.JAR_BUTTERFLY_PINK).setAllTextures(BLOCK_TEXTURES, "minecraft:block/jar_butterfly"));
-        addDispatch(new BlockModelJarButterfly<>(Blocks.JAR_BUTTERFLY_SILVER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/jar_butterfly"));
-
-        addDispatch(new BlockModelPebbles<>(Blocks.OVERLAY_PEBBLES));
-
-        addDispatch(new BlockModelFenceThin<>(Blocks.FENCE_CHAINLINK, TextureRegistry.getTexture("minecraft:block/fence_chain/center"), null, TextureRegistry.getTexture("minecraft:block/fence_chain/top"), TextureRegistry.getTexture("minecraft:block/fence_chain/column")).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fence_chain/center"));
-        addDispatch(new BlockModelFenceThin<>(Blocks.FENCE_PAPER_WALL, TextureRegistry.getTexture("minecraft:block/fence_paper/center"), null, null, TextureRegistry.getTexture("minecraft:block/fence_paper/column")).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fence_paper/center"));
-        addDispatch(new BlockModelFenceThin<>(Blocks.FENCE_STEEL, TextureRegistry.getTexture("minecraft:block/fence_steel/center"), null, TextureRegistry.getTexture("minecraft:block/fence_steel/top"), TextureRegistry.getTexture("minecraft:block/fence_steel/column")).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fence_steel/center"));
-
-        addDispatch(new BlockModelBasket<>(Blocks.BASKET)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/basket/bottom", S_TB)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/basket/side", S_SIDES));
-
-        addDispatch(new BlockModelStandard<>(Blocks.PAPER_WALL).setAllTextures(BLOCK_TEXTURES, "minecraft:block/paperwall"));
-
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_STONE_LOWER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/stone"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_STONE_UPPER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/stone"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_BASALT_LOWER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/basalt"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_BASALT_UPPER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/basalt"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_LIMESTONE_LOWER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/limestone"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_LIMESTONE_UPPER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/limestone"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_GRANITE_LOWER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/granite"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_GRANITE_UPPER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/granite"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_MARBLE_LOWER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/marble"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_MARBLE_UPPER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/marble"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_PIGMAN_LOWER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/marble"));
-        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_PIGMAN_UPPER).setAllTextures(BLOCK_TEXTURES, "minecraft:block/marble"));
-
-        addDispatch(new BlockModelMatcher<>(Blocks.MATCHER, false)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/matcher/side", S_SIDES)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/matcher/front0", S_TB));
-
-        addDispatch(new BlockModelMatcher<>(Blocks.MATCHER_ACTIVE, true)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/matcher/side_active", S_SIDES)
-            .setTex(BLOCK_TEXTURES, "minecraft:block/matcher/front0", S_TB));
+        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"));
+        addDispatch(new BlockModelGenericPressurePlatePainted<>(Blocks.PRESSURE_PLATE_PLANKS_OAK_PAINTED));
+
+        addDispatch(new BlockModelGenericVeryRotatable<>(Blocks.MOTION_SENSOR_IDLE, loadDataModel("minecraft:block/motion_sensor_idle")));
+        addDispatch(new BlockModelGenericVeryRotatable<>(Blocks.MOTION_SENSOR_ACTIVE, loadDataModel("minecraft:block/motion_sensor_active")));
+
+        addDispatch(new BlockModelGenericRepeater<>(Blocks.REPEATER_IDLE));
+        addDispatch(new BlockModelGenericRepeater<>(Blocks.REPEATER_ACTIVE));
+
+        addDispatch(new BlockModelGenericPiston<>(Blocks.PISTON_BASE, loadDataModel("minecraft:block/piston/base"), loadDataModel("minecraft:block/piston/extended")));
+        addDispatch(new BlockModelGenericPiston<>(Blocks.PISTON_BASE_STICKY, loadDataModel("minecraft:block/piston_sticky/base"), loadDataModel("minecraft:block/piston_sticky/extended")));
+        addDispatch(new BlockModelGenericPiston<>(Blocks.PISTON_BASE_STEEL, loadDataModel("minecraft:block/piston_steel/base"), loadDataModel("minecraft:block/piston_steel/extended")));
+
+        addDispatch(new BlockModelEmpty<>(Blocks.PISTON_MOVING).setAllTextures((IconCoordinate) null));
+        addDispatch(new BlockModelGenericPistonHead<>(Blocks.PISTON_HEAD,
+            loadDataModel("minecraft:block/piston/head"), loadDataModel("minecraft:block/piston_sticky/head"), loadDataModel("minecraft:block/piston_steel/head"),
+            loadDataModel("minecraft:block/piston/head_half"), loadDataModel("minecraft:block/piston_sticky/head_half"), loadDataModel("minecraft:block/piston_steel/head_half")));
+        addDispatch(new BlockModelGenericPistonHead<>(Blocks.PISTON_HEAD_STEEL,
+            loadDataModel("minecraft:block/piston/head"), loadDataModel("minecraft:block/piston_sticky/head"), loadDataModel("minecraft:block/piston_steel/head"),
+            loadDataModel("minecraft:block/piston/head_half"), loadDataModel("minecraft:block/piston_sticky/head_half"), loadDataModel("minecraft:block/piston_steel/head_half")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.NOTEBLOCK, loadDataModel("minecraft:block/noteblock")));
+
+        addDispatch(new BlockModelRail<>(Blocks.RAIL).setAllTextures("minecraft:block/rail/straight"));
+        addDispatch(new BlockModelRail<>(Blocks.RAIL_POWERED).setAllTextures("minecraft:block/rail_powered/idle"));
+        addDispatch(new BlockModelRail<>(Blocks.RAIL_DETECTOR).setAllTextures("minecraft:block/rail_detector/straight"));
+
+        addDispatch(new BlockModelGenericSpikes<>(Blocks.SPIKES).render3D(false));
+
+        addDispatch(new BlockModelGenericVeryRotatable<>(Blocks.DISPENSER_COBBLE_STONE, loadDataModel("minecraft:block/dispenser")));
+        addDispatch(new BlockModelGenericActivator<>(Blocks.ACTIVATOR_COBBLE_NETHERRACK));
+
+        addDispatch(new BlockModelGenericTrapdoor<>(Blocks.TRAPDOOR_PLANKS_OAK, "minecraft:block/trapdoor/planks/oak"));
+        addDispatch(new BlockModelGenericTrapdoor<>(Blocks.TRAPDOOR_IRON, "minecraft:block/trapdoor/iron"));
+        addDispatch(new BlockModelGenericTrapdoor<>(Blocks.TRAPDOOR_GLASS, "minecraft:block/trapdoor/glass"));
+        addDispatch(new BlockModelGenericTrapdoorPainted<>(Blocks.TRAPDOOR_PLANKS_PAINTED));
+        addDispatch(new BlockModelGenericTrapdoor<>(Blocks.TRAPDOOR_STEEL, "minecraft:block/trapdoor/steel"));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.TNT, loadDataModel("minecraft:block/tnt")));
+
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_PLANKS_OAK_BOTTOM, "minecraft:block/door/planks/oak", true));
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_PLANKS_OAK_TOP, "minecraft:block/door/planks/oak", false));
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_IRON_BOTTOM, "minecraft:block/door/iron", true));
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_IRON_TOP, "minecraft:block/door/iron", false));
+        addDispatch(new BlockModelGenericDoorPainted<>(Blocks.DOOR_PLANKS_PAINTED_BOTTOM, true));
+        addDispatch(new BlockModelGenericDoorPainted<>(Blocks.DOOR_PLANKS_PAINTED_TOP, false));
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_GLASS_BOTTOM, "minecraft:block/door/glass", true));
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_GLASS_TOP, "minecraft:block/door/glass", false));
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_STEEL_BOTTOM, "minecraft:block/door/steel", true));
+        addDispatch(new BlockModelGenericDoor<>(Blocks.DOOR_STEEL_TOP, "minecraft:block/door/steel", false));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.MESH, loadDataModel("minecraft:block/mesh")));
+        addDispatch(new BlockModelGeneric<>(Blocks.MESH_GOLD, loadDataModel("minecraft:block/mesh_gold")));
+
+        addDispatch(new BlockModelGenericBed<>(Blocks.BED));
+        addDispatch(new BlockModelGeneric<>(Blocks.SEAT, loadDataModel("minecraft:block/seat")));
+
+        addDispatch(new BlockModelCrossedSquares<>(Blocks.COBWEB).setAllTextures("minecraft:block/cobweb"));
+        addDispatch(new BlockModelFire<>(Blocks.FIRE).setAllTextures("minecraft:block/fire"));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRAZIER_INACTIVE, loadDataModel("minecraft:block/brazier")));
+        addDispatch(new BlockModelGenericBrazier<>(Blocks.BRAZIER_ACTIVE, loadDataModel("minecraft:block/brazier")));
+        addDispatch(new BlockModelFire<>(Blocks.FIRE_COLD).setAllTextures("minecraft:block/fire_cold"));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.MOBSPAWNER, loadDataModel("minecraft:block/mobspawner")));
+        addDispatch(new BlockModelGeneric<>(Blocks.MOBSPAWNER_DEACTIVATED, loadDataModel("minecraft:block/mobspawner_deactivated")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.WORKBENCH, loadDataModel("minecraft:block/workbench")));
+
+        addDispatch(new BlockModelGenericFurnace<>(Blocks.FURNACE_STONE_IDLE, "minecraft:block/furnace_stone/idle"));
+        addDispatch(new BlockModelGenericFurnace<>(Blocks.FURNACE_STONE_ACTIVE, "minecraft:block/furnace_stone/active"));
+        addDispatch(new BlockModelGenericFurnace<>(Blocks.FURNACE_BLAST_IDLE, "minecraft:block/furnace_blast/idle"));
+        addDispatch(new BlockModelGenericFurnace<>(Blocks.FURNACE_BLAST_ACTIVE, "minecraft:block/furnace_blast/active"));
+
+        addDispatch(new BlockModelGenericRotatable<>(Blocks.TROMMEL_IDLE, loadDataModel("minecraft:block/trommel")));
+        addDispatch(new BlockModelGenericRotatable<>(Blocks.TROMMEL_ACTIVE, loadDataModel("minecraft:block/trommel_active")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.CHEST_LEGACY, loadDataModel("minecraft:block/chest/legacy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.CHEST_LEGACY_PAINTED, loadDataModel("minecraft:block/chest/legacy")));
+        addDispatch(new BlockModelGenericChest<>(Blocks.CHEST_PLANKS_OAK, loadDataModel("minecraft:block/chest/single/planks"), loadDataModel("minecraft:block/chest/left/planks"), loadDataModel("minecraft:block/chest/right/planks")));
+        addDispatch(new BlockModelGenericChestPainted<>(Blocks.CHEST_PLANKS_OAK_PAINTED));
+
+        addDispatch(new BlockModelGenericCropsWheat<>(Blocks.CROPS_WHEAT));
+        addDispatch(new BlockModelGenericCropsPumpkin<>(Blocks.CROPS_PUMPKIN));
+
+        addDispatch(new BlockModelGenericFarmland<>(Blocks.FARMLAND_DIRT));
+
+        addDispatch(new BlockModelEmpty<>(Blocks.SIGN_POST_PLANKS_OAK).setAllTextures("minecraft:block/planks/oak"));
+        addDispatch(new BlockModelEmpty<>(Blocks.SIGN_WALL_PLANKS_OAK).setAllTextures("minecraft:block/planks/oak"));
+        addDispatch(new BlockModelEmpty<>(Blocks.FLAG).setAllTextures("minecraft:block/planks/oak"));
+        addDispatch(new BlockModelSignPainted<>(Blocks.SIGN_POST_PLANKS_OAK_PAINTED).setAllTextures("minecraft:block/planks/oak"));
+        addDispatch(new BlockModelSignPainted<>(Blocks.SIGN_WALL_PLANKS_OAK_PAINTED).setAllTextures("minecraft:block/planks/oak"));
+
+        addDispatch(new BlockModelGenericLayer<>(Blocks.LAYER_SNOW, "minecraft:block/layer/snow"));
+        addDispatch(new BlockModelGenericLayer<>(Blocks.LAYER_LEAVES_OAK, "minecraft:block/layer/leaves_oak"));
+        addDispatch(new BlockModelGenericLayer<>(Blocks.LAYER_SLATE, "minecraft:block/layer/slate"));
+        addDispatch(new BlockModelGenericLayer<>(Blocks.LAYER_ASH, "minecraft:block/layer/ash"));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.ICE, loadDataModel("minecraft:block/ice")).forceCullSelf(true));
+        addDispatch(new BlockModelGeneric<>(Blocks.PERMAICE, loadDataModel("minecraft:block/permaice")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_SNOW, loadDataModel("minecraft:block/block_snow")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_ASH, loadDataModel("minecraft:block/block_ash")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.CACTUS, loadDataModel("minecraft:block/cactus")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_CLAY, loadDataModel("minecraft:block/block_clay")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.SUGARCANE, loadDataModel("minecraft:block/sugarcane")));
+
+        addDispatch(new BlockModelGenericAxis<>(Blocks.BLOCK_SUGARCANE, loadDataModel("minecraft:block/block_sugarcane")));
+        addDispatch(new BlockModelGenericAxis<>(Blocks.BLOCK_SUGARCANE_BAKED, loadDataModel("minecraft:block/block_baked_sugarcane")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.JUKEBOX, loadDataModel("minecraft:block/jukebox")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.PUMPKIN, loadDataModel("minecraft:block/pumpkin")));
+        addDispatch(new BlockModelGenericVeryRotatable<>(Blocks.PUMPKIN_CARVED_IDLE, loadDataModel("minecraft:block/pumpkin_carved")));
+        addDispatch(new BlockModelGenericVeryRotatable<>(Blocks.PUMPKIN_CARVED_ACTIVE, loadDataModel("minecraft:block/pumpkin_carved_lit")));
+        addDispatch(new BlockModelGenericVeryRotatable<>(Blocks.PUMPKIN_REDSTONE, loadDataModel("minecraft:block/pumpkin_redstone")));
+
+
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_NETHERRACK, loadDataModel("minecraft:block/cobbled_netherrack/normal")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_NETHERRACK_IGNEOUS, loadDataModel("minecraft:block/cobbled_netherrack/igneous")));
+        addDispatch(new BlockModelGeneric<>(Blocks.COBBLE_NETHERRACK_MOSSY, loadDataModel("minecraft:block/cobbled_netherrack/mossy")));
+        addDispatch(new BlockModelGeneric<>(Blocks.NETHERRACK, loadDataModel("minecraft:block/netherrack")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BRICK_NETHERRACK, loadDataModel("minecraft:block/brick_netherrack")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_NETHERRACK_POLISHED, loadDataModel("minecraft:block/slab/polished_netherrack/lower"), loadDataModel("minecraft:block/slab/polished_netherrack/upper"), loadDataModel("minecraft:block/slab/polished_netherrack/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_COBBLE_NETHERRACK, loadDataModel("minecraft:block/slab/cobbled_netherrack/lower"), loadDataModel("minecraft:block/slab/cobbled_netherrack/upper"), loadDataModel("minecraft:block/slab/cobbled_netherrack/full")));
+        addDispatch(new BlockModelGenericSlab<>(Blocks.SLAB_BRICK_NETHERRACK, loadDataModel("minecraft:block/slab/brick_netherrack/lower"), loadDataModel("minecraft:block/slab/brick_netherrack/upper"), loadDataModel("minecraft:block/slab/brick_netherrack/full")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_COBBLE_NETHERRACK, loadDataModel("minecraft:block/stairs/cobbled_netherrack")));
+        addDispatch(new BlockModelGenericStairs<>(Blocks.STAIRS_BRICK_NETHERRACK, loadDataModel("minecraft:block/stairs/brick_netherrack")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.SOULSAND, loadDataModel("minecraft:block/soulsand")));
+        addDispatch(new BlockModelGeneric<>(Blocks.SOULSCHIST, loadDataModel("minecraft:block/soulschist")));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.GLOWSTONE, loadDataModel("minecraft:block/glowstone")));
+
+        addDispatch(new BlockModelGenericPortal<>(Blocks.PORTAL_NETHER, "minecraft:block/portal_nether/"));
+        addDispatch(new BlockModelGenericPortal<>(Blocks.PORTAL_DRIFT, "minecraft:block/portal_drift/"));
+
+        addDispatch(new BlockModelGenericCake<>(Blocks.CAKE));
+        addDispatch(new BlockModelGenericPie<>(Blocks.PUMPKIN_PIE));
+
+        addDispatch(new BlockModelGenericLamp<>(Blocks.LAMP_IDLE, "minecraft:block/lamp/idle/%s", "minecraft:block/lamp/active/%s"));
+        addDispatch(new BlockModelGenericLamp<>(Blocks.LAMP_ACTIVE, "minecraft:block/lamp/active/%s", "minecraft:block/lamp/active/%s"));
+        addDispatch(new BlockModelGenericLamp<>(Blocks.LAMP_INVERTED_IDLE, "minecraft:block/lamp/idle_inverted/%s", "minecraft:block/lamp/active_inverted/%s"));
+        addDispatch(new BlockModelGenericLamp<>(Blocks.LAMP_INVERTED_ACTIVE, "minecraft:block/lamp/active_inverted/%s", "minecraft:block/lamp/active_inverted/%s"));
+
+        addDispatch(new BlockModelGenericLantern<>(Blocks.LANTERN_FIREFLY_GREEN, loadDataModel("minecraft:block/lantern_firefly/green"), loadDataModel("minecraft:block/lantern_firefly/green_hanging")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.LANTERN_FIREFLY_BLUE, loadDataModel("minecraft:block/lantern_firefly/blue"), loadDataModel("minecraft:block/lantern_firefly/blue_hanging")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.LANTERN_FIREFLY_ORANGE, loadDataModel("minecraft:block/lantern_firefly/orange"), loadDataModel("minecraft:block/lantern_firefly/orange_hanging")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.LANTERN_FIREFLY_RED, loadDataModel("minecraft:block/lantern_firefly/red"), loadDataModel("minecraft:block/lantern_firefly/red_hanging")));
+        addDispatch(new BlockModelGenericJar<>(Blocks.JAR_GLASS));
+
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_BLUE, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_ORANGE, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_PINK, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_SILVER, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
+        addDispatch(new BlockModelGenericPebbles<>(Blocks.OVERLAY_PEBBLES));
+
+        addDispatch(new BlockModelGenericFenceThin<>(Blocks.FENCE_CHAINLINK, "minecraft:block/fence_thin/chain"));
+        addDispatch(new BlockModelGenericFenceThin<>(Blocks.FENCE_PAPER_WALL, "minecraft:block/fence_thin/paper"));
+        addDispatch(new BlockModelGenericFenceThin<>(Blocks.FENCE_STEEL, "minecraft:block/fence_thin/steel"));
+
+        addDispatch(new BlockModelGenericBasket<>(Blocks.BASKET));
+
+        addDispatch(new BlockModelGeneric<>(Blocks.PAPER_WALL, loadDataModel("minecraft:block/paperwall")));
+
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_STONE_LOWER).setAllTextures("minecraft:block/stone"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_STONE_UPPER).setAllTextures("minecraft:block/stone"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_BASALT_LOWER).setAllTextures("minecraft:block/basalt"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_BASALT_UPPER).setAllTextures("minecraft:block/basalt"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_LIMESTONE_LOWER).setAllTextures("minecraft:block/limestone"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_LIMESTONE_UPPER).setAllTextures("minecraft:block/limestone"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_GRANITE_LOWER).setAllTextures("minecraft:block/granite"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_GRANITE_UPPER).setAllTextures("minecraft:block/granite"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_MARBLE_LOWER).setAllTextures("minecraft:block/marble"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_MARBLE_UPPER).setAllTextures("minecraft:block/marble"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_PIGMAN_LOWER).setAllTextures("minecraft:block/marble"));
+        addDispatch(new BlockModelEmpty<>(Blocks.STATUE_PIGMAN_UPPER).setAllTextures("minecraft:block/marble"));
+
+        addDispatch(new BlockModelGenericMatcher<>(Blocks.MATCHER, "minecraft:block/matcher/"));
+        addDispatch(new BlockModelGenericMatcher<>(Blocks.MATCHER_ACTIVE, "minecraft:block/matcher/active"));
     }
 }
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoorGlass.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoorGlass.java
deleted file mode 100644
index 659a04668..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoorGlass.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicDoor;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-
-public class BlockModelDoorGlass<T extends BlockLogicDoor> extends BlockModelDoor<T> {
-    public BlockModelDoorGlass(Block<T> block) {
-        super(block);
-    }
-    @Override
-    protected boolean shouldFlipTexture(@NotNull Side side, int meta){
-        return false;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoorPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoorPainted.java
deleted file mode 100644
index 3bf6d7473..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDoorPainted.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicDoor;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelDoorPainted<T extends BlockLogicDoor> extends BlockModelDoor<T> {
-    public static final IconCoordinate[] doorBottomTextures = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-    public static final IconCoordinate[] doorTopTextures = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-    public static final IconCoordinate[] frameTopTextures = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-
-    static {
-        for (DyeColor c : DyeColor.blockOrderedColors()){
-            doorTopTextures[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/door/planks_" + c.colorID + "/top");
-            doorBottomTextures[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/door/planks_" + c.colorID + "/bottom");
-            frameTopTextures[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/door/planks_" + c.colorID + "/frame_top");
-        }
-    }
-    private final boolean isTop;
-    public BlockModelDoorPainted(Block<T> block, boolean isTop) {
-        super(block);
-        this.isTop = isTop;
-    }
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data)
-    {
-        int color = (data >> 4) & DyeColor.MASK_COLOR;
-        if (side.getAxis() == Axis.Y){
-            return frameTopTextures[color];
-        } else if (this.isTop){
-            return doorTopTextures[color];
-        }
-        return doorBottomTextures[color];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFarmland.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFarmland.java
deleted file mode 100644
index 3b9a2ad41..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFarmland.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicFarmland;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelFarmland<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected IconCoordinate topWet = TextureRegistry.getTexture("minecraft:block/farmland/wet_top");
-    protected IconCoordinate topWetFertilized = TextureRegistry.getTexture("minecraft:block/farmland/wet_fertilized_top");
-    protected IconCoordinate topDry = TextureRegistry.getTexture("minecraft:block/farmland/dry_top");
-    protected IconCoordinate topDryFertilized = TextureRegistry.getTexture("minecraft:block/farmland/dry_fertilized_top");
-    protected IconCoordinate mud = TextureRegistry.getTexture("minecraft:block/farmland/wet");
-
-    public BlockModelFarmland(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, final int data)
-    {
-        boolean isWet = BlockLogicFarmland.isWet(data);
-        boolean isFertilized = BlockLogicFarmland.isFertilized(data);
-
-        if (side == Side.TOP) {
-            if (isWet && isFertilized) {
-                return this.topWetFertilized;
-            } else if (isWet) {
-                return this.topWet;
-            } else if (isFertilized) {
-                return this.topDryFertilized;
-            } else {
-                return this.topDry;
-            }
-        } else {
-            if (isWet) {
-                return this.mud;
-            }
-            return super.getBlockTextureFromSideAndMetadata(side, data);
-        }
-    }
-
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceGatePainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceGatePainted.java
deleted file mode 100644
index 268fe9fa5..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFenceGatePainted.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicFenceGate;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelFenceGatePainted<T extends BlockLogicFenceGate> extends BlockModelFenceGate<T> {
-    public BlockModelFenceGatePainted(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int meta) {
-        meta = meta >> 4;
-        return BlockModelPlanksPainted.texCoords[meta & 0x0F];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFencePainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFencePainted.java
deleted file mode 100644
index ec1faba39..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFencePainted.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicFence;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelFencePainted<T extends BlockLogicFence> extends BlockModelFence<T> {
-
-
-    public BlockModelFencePainted(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int meta) {
-        return BlockModelPlanksPainted.texCoords[meta & 15];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFlowerStackable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFlowerStackable.java
deleted file mode 100644
index 297cdc899..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFlowerStackable.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicFlowerStackable;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelFlowerStackable<T extends BlockLogicFlowerStackable> extends BlockModelCrossedSquares<T> {
-    private final IconCoordinate[] ICONS;
-
-    public BlockModelFlowerStackable(Block<T> block, String baseTexture) {
-        super(block);
-
-        this.ICONS = new IconCoordinate[T.MAX_STACK_COUNT + 1];
-        for (int i = 0; i < T.MAX_STACK_COUNT + 1; i++) {
-            this.ICONS[i] = TextureRegistry.getTexture(baseTexture + i);
-        }
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        final int stackCount = T.getStackCount(data);
-        if (stackCount > T.MAX_STACK_COUNT) {
-            return this.ICONS[0];
-        }
-
-        return this.ICONS[stackCount];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFurnace.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFurnace.java
deleted file mode 100644
index 8a646460e..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFurnace.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.player.inventory.container.Container;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.util.helper.Sides;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelFurnace<T extends BlockLogic>
-    extends BlockModelHorizontalRotation<T> {
-
-    public BlockModelFurnace(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource blockAccess, @NotNull TilePosc tilePos, @NotNull Side side) {
-        int data = blockAccess.getBlockData(tilePos);
-        int index = Sides.orientationLookUpHorizontal[6 * Math.min(data, 5) + side.getId()];
-        if (index >= Sides.orientationLookUpHorizontal.length) return this.blockTextures.get(Side.BOTTOM);
-        if (index == Side.NORTH.getId()) {
-            IconCoordinate originalFront = this.blockTextures.get(Side.NORTH);
-            Container container = (Container) blockAccess.getTileEntity(tilePos);
-            if (container != null) {
-                boolean hasOutput = container.getItem(2) != null;
-                if (hasOutput) {
-                    return TextureRegistry.getTexture(originalFront.namespaceId + "_filled");
-                }
-            }
-            return originalFront;
-        }
-        return this.blockTextures.get(Side.getSideById(index));
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGeneric.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGeneric.java
deleted file mode 100644
index 01e18ae46..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGeneric.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.block.color.BlockColorDispatcher;
-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.util.helper.Side;
-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.DisplayPos;
-import org.useless.dragonfly.data.block.BlockModelData;
-import org.useless.dragonfly.models.block.StaticBlockModel;
-
-public class BlockModelGeneric<T extends BlockLogic> extends BlockModel<T> {
-    private final StaticBlockModel staticModel;
-
-    public BlockModelGeneric(@NotNull final Block<T> block, @NotNull final StaticBlockModel staticModel) {
-        super(block);
-        this.staticModel = staticModel;
-    }
-
-    public BlockModelGeneric(@NotNull final Block<T> block, @NotNull final BlockModelData staticModel) {
-        super(block);
-        this.staticModel = staticModel.asModel();
-    }
-
-    @Override
-    public boolean renderNoCulling(@NotNull final TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos) {
-        return this.staticModel.renderAttached(this,
-            tessellator,
-            worldSource,
-            tilePos.x(),
-            tilePos.y(),
-            tilePos.z(),
-            0, 0, 0, false, null);
-    }
-
-    @Override
-    public boolean render(final @NotNull TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos) {
-        return this.staticModel.renderAttached(this,
-            tessellator,
-            worldSource,
-            tilePos.x(),
-            tilePos.y(),
-            tilePos.z(),
-            0, 0, 0, true, null);
-    }
-
-    @Override
-    public boolean renderWithOverrideTexture(final @NotNull TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos, final IconCoordinate textureIndex) {
-        return this.staticModel.renderAttached(this,
-            tessellator,
-            worldSource,
-            tilePos.x(),
-            tilePos.y(),
-            tilePos.z(),
-            0, 0, 0, true, textureIndex);
-    }
-
-    @Override
-    public void renderStandalone(@NotNull final TessellatorGeneral tessellator, final int metadata, final int lightmapCoord) {
-        this.staticModel.renderStandalone(this,
-            tessellator, 0, 0, 0,
-            metadata,
-            BlockColorDispatcher.getInstance().getDispatch(this.block));
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return true;
-    }
-
-    @Override
-    public @NotNull DisplayPos getItemDisplayPos(@NotNull final String id) {
-        return this.staticModel.getItemDisplayPos(id);
-    }
-
-    @Override
-    public int renderLayer() {
-        return this.staticModel.renderLayer();
-    }
-
-    @Override
-    public @Nullable IconCoordinate getParticleTexture(@NotNull final Side side, final int meta) {
-        return this.staticModel.getParticle(side);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getOverlayTexture(final int meta) {
-        return this.staticModel.getOverlay();
-    }
-
-    @Override
-    public int particleColorIndex(@NotNull final WorldSource worldSource, final @NotNull TilePosc tilePos, @NotNull final Side side, final int meta) {
-        return this.staticModel.particleColorIndex(side);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGrass.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGrass.java
deleted file mode 100644
index 9d6158674..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGrass.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.renderer.GLRenderer;
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.material.Material;
-import net.minecraft.core.block.material.Materials;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.Side;
-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.jetbrains.annotations.Nullable;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelGrass<T extends BlockLogic> extends BlockModelStandard<T> {
-    public static boolean fancyGrass = false;
-    public static boolean useOverlay = false;
-    private static final IconCoordinate[] overlayIndices = new IconCoordinate[]{
-        null,
-        null,
-        TextureRegistry.getTexture("minecraft:block/grass/side_overlay"),
-        TextureRegistry.getTexture("minecraft:block/grass/side_overlay"),
-        TextureRegistry.getTexture("minecraft:block/grass/side_overlay"),
-        TextureRegistry.getTexture("minecraft:block/grass/side_overlay")};
-    protected IconCoordinate snowSide = TextureRegistry.getTexture("minecraft:block/grass/snowy_side");
-
-    public BlockModelGrass(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        AABBdc bounds = this.block.getBounds();
-        boolean didRender = isRetro() ? renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1) : renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-        if (fancyGrass && !(this.retroBlockTextures.hasTexture() && isRetro())) {
-            useOverlay = true;
-            didRender |= renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-            useOverlay = false;
-        }
-        return didRender;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        GLRenderer.setColor4f(1f, 1f, 1f, 1f);
-
-        AABBdc bounds = getBlockBoundsForItemRender();
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setColor1i(0xFFFFFFFF);
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.BOTTOM, metadata));
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.NORTH, metadata));
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.SOUTH, metadata));
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.WEST, metadata));
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.EAST, metadata));
-        tessellator.setColor1i(getStandaloneTintColor(metadata));
-
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.TOP, metadata));
-        if (fancyGrass && !isRetro()) {
-            useOverlay = true;
-            tessellator.setNormal(0.0F, 0.0F, -1F);
-            renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.NORTH, metadata));
-
-            tessellator.setNormal(0.0F, 0.0F, 1.0F);
-            renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.SOUTH, metadata));
-
-            tessellator.setNormal(-1F, 0.0F, 0.0F);
-            renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.WEST, metadata));
-
-            tessellator.setNormal(1.0F, 0.0F, 0.0F);
-            renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, getBlockTextureFromSideAndMetadata(Side.EAST, metadata));
-            useOverlay = false;
-        }
-        tessellator.draw();
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        Material material = source.getBlockMaterial(tilePos.up(new TilePos()));
-        if ((material == Materials.TOP_SNOW || material == Materials.SNOW) && (side.getAxis() != Axis.Y)) {
-            return this.snowSide;
-        } else return super.getBlockTexture(source, tilePos, side);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (useOverlay) {
-            return overlayIndices[side.getId()];
-        }
-        return super.getBlockTextureFromSideAndMetadata(side, data);
-    }
-
-    @Override
-    public boolean shouldSideBeColored(@NotNull WorldSource worldSource, @NotNull TilePosc tilePos, @NotNull Side side, int meta) {
-        Material material = worldSource.getBlockMaterial(tilePos.up(new TilePos()));
-        if (material == Materials.TOP_SNOW || material == Materials.SNOW) {
-            return false;
-        }
-        return useOverlay || side == Side.TOP;
-    }
-}
\ No newline at end of file
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelJar.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelJar.java
deleted file mode 100644
index b3e8b7604..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelJar.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelJar<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected IconCoordinate jarEmpty = TextureRegistry.getTexture("minecraft:block/jar");
-    protected IconCoordinate jarFull = TextureRegistry.getTexture("minecraft:block/jar_dirt");
-
-    public BlockModelJar(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        // todo: yes, i know this is horrible.
-        float brightness = 1.0f;
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        float yOffset = 0f;
-        int meta = worldSource.getBlockData(tilePos);
-
-        float extMinX = tilePos.x() + 0.5f - (3f / 16f);
-        float extMinY = tilePos.y() + yOffset;
-        float extMinZ = tilePos.z() + 0.5f - (3f / 16f);
-        float extMaxX = tilePos.x() + 0.5f + (3f / 16f);
-        float extMaxY = tilePos.y() + (0.5f + yOffset);
-        float extMaxZ = tilePos.z() + 0.5f + (3f / 16f);
-
-        float fillMaxY = tilePos.y() + (0.5f + yOffset) - (4f / 16f);
-
-        float intMinX = tilePos.x() + 0.5f - (3f / 16f);
-        float intMinY = tilePos.y() + yOffset;
-        float intMinZ = tilePos.z() + 0.5f - (3f / 16f);
-        float intMaxX = tilePos.x() + 0.5f + (3f / 16f);
-        float intMaxY = tilePos.y() + (0.5f + yOffset);
-        float intMaxZ = tilePos.z() + 0.5f + (3f / 16f);
-
-        IconCoordinate texIndex = getBlockTextureFromSideAndMetadata(Side.BOTTOM, meta);
-
-        double texU = texIndex.getIconUMin();
-        double texV = texIndex.getIconVMin();
-
-        double onePix = 1f / 16;
-
-        //exterior shell uvs
-        double extSideMinU = texU;
-        double extSideMaxU = texIndex.getSubIconU(onePix * 6);
-        double extSideMinV = texIndex.getSubIconV(onePix * 6);
-        double extSideMaxV = texIndex.getSubIconV(onePix * 14);
-
-        double extBottomMinU = texIndex.getSubIconU(onePix * 6);
-        double extBottomMaxU = texIndex.getSubIconU(onePix * 12);
-        double extBottomMinV = texV;
-        double extBottomMaxV = texIndex.getSubIconV(onePix * 6);
-
-        double extTopMinU = texU;
-        double extTopMaxU = texIndex.getSubIconU(onePix * 6);
-        double extTopMinV = texV;
-        double extTopMaxV = texIndex.getSubIconV(onePix * 6);
-
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-
-        // Render sides int
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMinY, intMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(intMinX, intMinY, intMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMinZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(intMinX, intMinY, intMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMinY, intMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMinZ, extSideMinU, extSideMinV);
-
-        // Render top ext
-        tessellator.addVertexWithUV(extMinX, fillMaxY, extMaxZ, extTopMinU, extTopMaxV);
-        tessellator.addVertexWithUV(extMaxX, fillMaxY, extMaxZ, extTopMaxU, extTopMaxV);
-        tessellator.addVertexWithUV(extMaxX, fillMaxY, extMinZ, extTopMaxU, extTopMinV);
-        tessellator.addVertexWithUV(extMinX, fillMaxY, extMinZ, extTopMinU, extTopMinV);
-
-        // Render bottom int
-        tessellator.addVertexWithUV(extMinX, extMinY + 0.01F, extMaxZ, extBottomMinU, extBottomMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY + 0.01F, extMaxZ, extBottomMaxU, extBottomMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY + 0.01F, extMinZ, extBottomMaxU, extBottomMinV);
-        tessellator.addVertexWithUV(extMinX, extMinY + 0.01F, extMinZ, extBottomMinU, extBottomMinV);
-
-        // Render sides ext
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extSideMinU, extSideMinV);
-
-        // Render bottom int
-        tessellator.addVertexWithUV(intMinX, intMinY, intMinZ, extBottomMinU, extBottomMinV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMinZ, extBottomMaxU, extBottomMinV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMaxZ, extBottomMaxU, extBottomMaxV);
-        tessellator.addVertexWithUV(intMinX, intMinY, intMaxZ, extBottomMinU, extBottomMaxV);
-
-        // Render bottom ext
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extBottomMinU, extBottomMinV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extBottomMaxU, extBottomMinV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extBottomMaxU, extBottomMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extBottomMinU, extBottomMaxV);
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int meta) {
-        if (meta == 1)
-            return this.jarFull;
-        return this.jarEmpty;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelJarButterfly.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelJarButterfly.java
deleted file mode 100644
index fe006b2cb..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelJarButterfly.java
+++ /dev/null
@@ -1,179 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.BlockLogicJarButterfly;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-
-public class BlockModelJarButterfly<T extends BlockLogic> extends BlockModelStandard<T> {
-
-    public BlockModelJarButterfly(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        int meta = worldSource.getBlockData(tilePos);
-        boolean isHanging = (meta & BlockLogicJarButterfly.MASK_HANGING) == 0;
-        boolean isAngled = (meta & BlockLogicJarButterfly.MASK_ANGLED) != 0;
-
-        float brightness = 1.0f;
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-
-        float yOffset = isHanging ? 0f : 0.375f;
-
-        float intMinX = tilePos.x() + 0.5f - (2f / 16f);
-        float intMinY = tilePos.y() + yOffset + (1f / 16f);
-        float intMinZ = tilePos.z() + 0.5f - (2f / 16f);
-        float intMaxX = tilePos.x() + 0.5f + (2f / 16f);
-        float intMaxY = tilePos.y() + (0.4375f + yOffset);
-        float intMaxZ = tilePos.z() + 0.5f + (2f / 16f);
-
-        float extMinX = tilePos.x() + 0.5f - (3f / 16f);
-        float extMinY = tilePos.y() + yOffset;
-        float extMinZ = tilePos.z() + 0.5f - (3f / 16f);
-        float extMaxX = tilePos.x() + 0.5f + (3f / 16f);
-        float extMaxY = tilePos.y() + (0.5f + yOffset);
-        float extMaxZ = tilePos.z() + 0.5f + (3f / 16f);
-
-        float hookMinX = tilePos.x() + 0.5f - (2f / 16f);
-        float hookMinZ = tilePos.z() + 0.5f - (2f / 16f);
-        float hookMaxX = tilePos.x() + 0.5f + (2f / 16f);
-        float hookMaxY = intMaxY + (4f / 16f);
-        float hookMaxZ = tilePos.z() + 0.5f + (2f / 16f);
-
-//        if (isAngled)
-//        {
-//            float angle = (float)(java.lang.Math.PI / 4);
-//            float centerX = x + 0.5f;
-//            float centerY = y;
-//            float centerZ = z + 0.5f;
-//
-//            float oldExtMaxY = extMaxY;
-//            float[] r = rotateAroundPoint(intMinX - centerX, intMinY - centerY, intMinZ - centerZ, 0, 0, angle);
-//            intMinX = r[0] + centerX;
-//            intMinY = r[1] + centerY;
-//            intMinZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(intMaxX - centerX, intMaxY - centerY, intMaxZ - centerZ, 0, 0, angle);
-//            intMaxX = r[0] + centerX;
-//            intMaxY = r[1] + centerY;
-//            intMaxZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(extMinX - centerX, extMinY - centerY, extMaxZ - centerZ, 0, 0, angle);
-//            extMinX = r[0] + centerX;
-//            extMinY = r[1] + centerY;
-//            extMinZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(extMaxX - centerX, extMaxY - centerY, extMaxZ - centerZ, 0, 0, angle);
-//            extMaxX = r[0] + centerX;
-//            extMaxY = r[1] + centerY;
-//            extMaxZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(hookMinX - centerX, oldExtMaxY - centerY, hookMinZ - centerZ, 0, 0, angle);
-//            hookMinX = r[0] + centerX;
-//            hookMinZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(hookMaxX - centerX, hookMaxY - centerY, hookMaxZ - centerZ, 0, 0, angle);
-//            hookMaxX = r[0] + centerX;
-//            hookMaxY = r[1] + centerY;
-//            hookMaxZ = r[2] + centerZ;
-//        }
-
-        IconCoordinate texIndex = getBlockTextureFromSideAndMetadata(Side.BOTTOM, meta);
-
-        double texU = texIndex.getIconUMin();
-        double texV = texIndex.getIconVMin();
-
-        double onePix = 1f / 16;
-
-        //exterior shell uvs
-        double extSideMinU = texU;
-        double extSideMaxU = texIndex.getSubIconU(onePix * 6);
-        double extSideMinV = texIndex.getSubIconV(onePix * 6);
-        double extSideMaxV = texIndex.getSubIconV(onePix * 14);
-
-        double extTopMinU = texU;
-        double extTopMaxU = texIndex.getSubIconU(onePix * 6);
-        double extTopMinV = texV;
-        double extTopMaxV = texIndex.getSubIconV(onePix * 6);
-
-        double extBottomMinU = texIndex.getSubIconU(onePix * 6);
-        double extBottomMaxU = texIndex.getSubIconU(onePix * 12);
-        double extBottomMinV = texV;
-        double extBottomMaxV = texIndex.getSubIconV(onePix * 6);
-
-        //hook uvs
-        double hookMinU = texIndex.getSubIconU(onePix * 10);
-        double hookMaxU = texIndex.getSubIconU(onePix * 16);
-        double hookMinV = texIndex.getSubIconV(onePix * 6);
-        double hookMaxV = texIndex.getSubIconV(onePix * 10);
-
-        // Render sides ext
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extSideMinU, extSideMinV);
-
-        // Render top ext
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extTopMinU, extTopMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extTopMaxU, extTopMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extTopMaxU, extTopMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extTopMinU, extTopMinV);
-
-        // Render bottom ext
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extBottomMinU, extBottomMinV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extBottomMaxU, extBottomMinV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extBottomMaxU, extBottomMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extBottomMinU, extBottomMaxV);
-
-        // Render hook
-        tessellator.addVertexWithUV(hookMinX, intMaxY, hookMinZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, hookMaxZ, hookMaxU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, hookMaxZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, hookMinZ, hookMinU, hookMinV);
-
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, hookMinZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, hookMaxZ, hookMinU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, hookMaxZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMinX, intMaxY, hookMinZ, hookMaxU, hookMaxV);
-
-        tessellator.addVertexWithUV(hookMinX, intMaxY, intMaxZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, intMinZ, hookMaxU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, intMinZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, intMaxZ, hookMinU, hookMinV);
-
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, hookMaxZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, hookMinZ, hookMinU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, hookMinZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMinX, intMaxY, hookMaxZ, hookMaxU, hookMaxV);
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLadder.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLadder.java
deleted file mode 100644
index 18a78942e..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLadder.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.BlockLogicLadder;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-
-public class BlockModelLadder<T extends BlockLogicLadder> extends BlockModelStandard<T> {
-    public BlockModelLadder(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        int data = worldSource.getBlockData(tilePos);
-        IconCoordinate tex = getBlockTextureFromSideAndMetadata(Side.BOTTOM, data);
-        if (renderBlocks.overrideBlockTexture != null) {
-            tex = renderBlocks.overrideBlockTexture;
-        }
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        double uMin = tex.getIconUMin();
-        double uMax = tex.getIconUMax();
-        double vMin = tex.getIconVMin();
-        double vMax = tex.getIconVMax();
-        float f1 = 0.0F;
-        float f2 = 0.05F;
-        switch (this.block.getLogic().getSideFromMeta(data)) {
-            case EAST -> {
-                tessellator.addVertexWithUV((float) tilePos.x() + f2, (float) (tilePos.y() + 1) + f1, (float) (tilePos.z() + 1) + f1, uMin, vMin);
-                tessellator.addVertexWithUV((float) tilePos.x() + f2, (float) (tilePos.y()) - f1, (float) (tilePos.z() + 1) + f1, uMin, vMax);
-                tessellator.addVertexWithUV((float) tilePos.x() + f2, (float) (tilePos.y()) - f1, (float) (tilePos.z()) - f1, uMax, vMax);
-                tessellator.addVertexWithUV((float) tilePos.x() + f2, (float) (tilePos.y() + 1) + f1, (float) (tilePos.z()) - f1, uMax, vMin);
-            }
-            case WEST -> {
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) - f2, (float) (tilePos.y()) - f1, (float) (tilePos.z() + 1) + f1, uMax, vMax);
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) - f2, (float) (tilePos.y() + 1) + f1, (float) (tilePos.z() + 1) + f1, uMax, vMin);
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) - f2, (float) (tilePos.y() + 1) + f1, (float) (tilePos.z()) - f1, uMin, vMin);
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) - f2, (float) (tilePos.y()) - f1, (float) (tilePos.z()) - f1, uMin, vMax);
-            }
-            case SOUTH -> {
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) + f1, (float) (tilePos.y()) - f1, (float) tilePos.z() + f2, uMax, vMax);
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) + f1, (float) (tilePos.y() + 1) + f1, (float) tilePos.z() + f2, uMax, vMin);
-                tessellator.addVertexWithUV((float) (tilePos.x()) - f1, (float) (tilePos.y() + 1) + f1, (float) tilePos.z() + f2, uMin, vMin);
-                tessellator.addVertexWithUV((float) (tilePos.x()) - f1, (float) (tilePos.y()) - f1, (float) tilePos.z() + f2, uMin, vMax);
-            }
-            case NORTH -> {
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) + f1, (float) (tilePos.y() + 1) + f1, (float) (tilePos.z() + 1) - f2, uMin, vMin);
-                tessellator.addVertexWithUV((float) (tilePos.x() + 1) + f1, (float) (tilePos.y()) - f1, (float) (tilePos.z() + 1) - f2, uMin, vMax);
-                tessellator.addVertexWithUV((float) (tilePos.x()) - f1, (float) (tilePos.y()) - f1, (float) (tilePos.z() + 1) - f2, uMax, vMax);
-                tessellator.addVertexWithUV((float) (tilePos.x()) - f1, (float) (tilePos.y() + 1) + f1, (float) (tilePos.z() + 1) - f2, uMax, vMin);
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLamp.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLamp.java
deleted file mode 100644
index 02239ccac..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLamp.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicLamp;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelLamp<T extends BlockLogicLamp> extends BlockModelStandard<T> {
-    private static final IconCoordinate[] texCoordsInactive = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-    private static final IconCoordinate[] texCoordsActive = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-
-    static {
-        for (DyeColor c : DyeColor.blockOrderedColors()) {
-            texCoordsInactive[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/lamp/" + c.colorID + "_idle");
-            texCoordsActive[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/lamp/" + c.colorID + "_active");
-        }
-    }
-
-    public BlockModelLamp(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        int data = source.getBlockData(tilePos) & DyeColor.MASK_COLOR;
-        if (this.block.getLogic().isActive) {
-            return texCoordsActive[data];
-        } else {
-            return texCoordsInactive[data];
-        }
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        return texCoordsActive[data & DyeColor.MASK_COLOR];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLantern.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLantern.java
deleted file mode 100644
index 3850901fb..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLantern.java
+++ /dev/null
@@ -1,227 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.BlockLogicLanternFirefly;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-
-public class BlockModelLantern<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelLantern(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        int meta = worldSource.getBlockData(tilePos);
-        boolean isHanging = (meta & BlockLogicLanternFirefly.MASK_HANGING) == 0;
-//        boolean isAngled = (meta & BlockLogicLanternFirefly.MASK_ANGLED) != 0;
-
-        float brightness = 1.0f;
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-
-        float yOffset = isHanging ? 0f : 0.375f;
-
-        float intMinX = tilePos.x() + 0.5f - (2f / 16f);
-        float intMinY = tilePos.y() + yOffset + (1f / 16f);
-        float intMinZ = tilePos.z() + 0.5f - (2f / 16f);
-        float intMaxX = tilePos.x() + 0.5f + (2f / 16f);
-        float intMaxY = tilePos.y() + (0.4375f + yOffset);
-        float intMaxZ = tilePos.z() + 0.5f + (2f / 16f);
-
-        float extMinX = tilePos.x() + 0.5f - (3f / 16f);
-        float extMinY = tilePos.y() + yOffset;
-        float extMinZ = tilePos.z() + 0.5f - (3f / 16f);
-        float extMaxX = tilePos.x() + 0.5f + (3f / 16f);
-        float extMaxY = tilePos.y() + (0.5f + yOffset);
-        float extMaxZ = tilePos.z() + 0.5f + (3f / 16f);
-
-        float hookMinX = tilePos.x() + 0.5f - (2f / 16f);
-        float hookMinZ = tilePos.z() + 0.5f - (2f / 16f);
-        float hookMaxX = tilePos.x() + 0.5f + (2f / 16f);
-        float hookMaxY = intMaxY + (4f / 16f);
-        float hookMaxZ = tilePos.z() + 0.5f + (2f / 16f);
-
-//        if (isAngled)
-//        {
-//            float angle = (float)(java.lang.Math.PI / 4);
-//            float centerX = x + 0.5f;
-//            float centerY = y;
-//            float centerZ = z + 0.5f;
-//
-//            float oldExtMaxY = extMaxY;
-//            float[] r = rotateAroundPoint(intMinX - centerX, intMinY - centerY, intMinZ - centerZ, 0, 0, angle);
-//            intMinX = r[0] + centerX;
-//            intMinY = r[1] + centerY;
-//            intMinZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(intMaxX - centerX, intMaxY - centerY, intMaxZ - centerZ, 0, 0, angle);
-//            intMaxX = r[0] + centerX;
-//            intMaxY = r[1] + centerY;
-//            intMaxZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(extMinX - centerX, extMinY - centerY, extMaxZ - centerZ, 0, 0, angle);
-//            extMinX = r[0] + centerX;
-//            extMinY = r[1] + centerY;
-//            extMinZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(extMaxX - centerX, extMaxY - centerY, extMaxZ - centerZ, 0, 0, angle);
-//            extMaxX = r[0] + centerX;
-//            extMaxY = r[1] + centerY;
-//            extMaxZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(hookMinX - centerX, oldExtMaxY - centerY, hookMinZ - centerZ, 0, 0, angle);
-//            hookMinX = r[0] + centerX;
-//            hookMinZ = r[2] + centerZ;
-//
-//            r = rotateAroundPoint(hookMaxX - centerX, hookMaxY - centerY, hookMaxZ - centerZ, 0, 0, angle);
-//            hookMaxX = r[0] + centerX;
-//            hookMaxY = r[1] + centerY;
-//            hookMaxZ = r[2] + centerZ;
-//        }
-
-        IconCoordinate texIndex = getBlockTextureFromSideAndMetadata(Side.BOTTOM, meta);
-
-        double texU = texIndex.getIconUMin();
-        double texV = texIndex.getIconVMin();
-
-        double onePix = 1f / 16;
-
-        //exterior shell uvs
-        double extSideMinU = texU;
-        double extSideMaxU = texIndex.getSubIconU(onePix * 6);
-        double extSideMinV = texIndex.getSubIconV(onePix * 6);
-        double extSideMaxV = texIndex.getSubIconV(onePix * 14);
-
-        double extTopMinU = texU;
-        double extTopMaxU = texIndex.getSubIconU(onePix * 6);
-        double extTopMinV = texV;
-        double extTopMaxV = texIndex.getSubIconV(onePix * 6);
-
-        double extBottomMinU = texIndex.getSubIconU(onePix * 6);
-        double extBottomMaxU = texIndex.getSubIconU(onePix * 12);
-        double extBottomMinV = texV;
-        double extBottomMaxV = texIndex.getSubIconV(onePix * 6);
-
-        //interior uvs
-        double sideMinU = texIndex.getSubIconU(onePix * 6);
-        double sideMaxU = texIndex.getSubIconU(onePix * 10);
-        double sideMinV = texIndex.getSubIconV(onePix * 10);
-        double sideMaxV = texIndex.getSubIconV(onePix * 16);
-
-        double topMinU = texIndex.getSubIconU(onePix * 6);
-        double topMaxU = texIndex.getSubIconU(onePix * 10);
-        double topMinV = texIndex.getSubIconV(onePix * 6);
-        double topMaxV = texIndex.getSubIconV(onePix * 10);
-
-        double bottomMinU = texIndex.getSubIconU(onePix * 6);
-        double bottomMaxU = texIndex.getSubIconU(onePix * 10);
-        double bottomMinV = texIndex.getSubIconV(onePix * 6);
-        double bottomMaxV = texIndex.getSubIconV(onePix * 10);
-
-        //hook uvs
-        double hookMinU = texIndex.getSubIconU(onePix * 10);
-        double hookMaxU = texIndex.getSubIconU(onePix * 16);
-        double hookMinV = texIndex.getSubIconV(onePix * 6);
-        double hookMaxV = texIndex.getSubIconV(onePix * 10);
-
-        // Render sides int
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMinZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMinY, intMinZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMinZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMinZ, sideMinU, sideMinV);
-
-        tessellator.addVertexWithUV(intMinX, intMinY, intMaxZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMaxZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMaxZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMaxZ, sideMinU, sideMinV);
-
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMaxZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMinZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMinZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMaxZ, sideMinU, sideMinV);
-
-        tessellator.addVertexWithUV(intMinX, intMinY, intMinZ, sideMinU, sideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMinY, intMaxZ, sideMaxU, sideMaxV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMaxZ, sideMaxU, sideMinV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMinZ, sideMinU, sideMinV);
-
-        // Render top int
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMaxZ, topMinU, topMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMaxZ, topMaxU, topMaxV);
-        tessellator.addVertexWithUV(intMaxX, intMaxY, intMinZ, topMaxU, topMinV);
-        tessellator.addVertexWithUV(intMinX, intMaxY, intMinZ, topMinU, topMinV);
-
-        // Render bottom int
-        tessellator.addVertexWithUV(intMinX, intMinY, intMinZ, bottomMinU, bottomMinV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMinZ, bottomMaxU, bottomMinV);
-        tessellator.addVertexWithUV(intMaxX, intMinY, intMaxZ, bottomMaxU, bottomMaxV);
-        tessellator.addVertexWithUV(intMinX, intMinY, intMaxZ, bottomMinU, bottomMaxV);
-
-        // Render sides ext
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extSideMinU, extSideMinV);
-
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extSideMinU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extSideMaxU, extSideMaxV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extSideMaxU, extSideMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extSideMinU, extSideMinV);
-
-        // Render top ext
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMaxZ, extTopMinU, extTopMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMaxZ, extTopMaxU, extTopMaxV);
-        tessellator.addVertexWithUV(extMaxX, extMaxY, extMinZ, extTopMaxU, extTopMinV);
-        tessellator.addVertexWithUV(extMinX, extMaxY, extMinZ, extTopMinU, extTopMinV);
-
-        // Render bottom ext
-        tessellator.addVertexWithUV(extMinX, extMinY, extMinZ, extBottomMinU, extBottomMinV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMinZ, extBottomMaxU, extBottomMinV);
-        tessellator.addVertexWithUV(extMaxX, extMinY, extMaxZ, extBottomMaxU, extBottomMaxV);
-        tessellator.addVertexWithUV(extMinX, extMinY, extMaxZ, extBottomMinU, extBottomMaxV);
-
-        // Render hook
-        tessellator.addVertexWithUV(hookMinX, intMaxY, hookMinZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, hookMaxZ, hookMaxU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, hookMaxZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, hookMinZ, hookMinU, hookMinV);
-
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, hookMinZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, hookMaxZ, hookMinU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, hookMaxZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMinX, intMaxY, hookMinZ, hookMaxU, hookMaxV);
-
-        tessellator.addVertexWithUV(hookMinX, intMaxY, intMaxZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, intMinZ, hookMaxU, hookMaxV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, intMinZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, intMaxZ, hookMinU, hookMinV);
-
-        tessellator.addVertexWithUV(hookMinX, hookMaxY, hookMaxZ, hookMaxU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, hookMaxY, hookMinZ, hookMinU, hookMinV);
-        tessellator.addVertexWithUV(hookMaxX, intMaxY, hookMinZ, hookMinU, hookMaxV);
-        tessellator.addVertexWithUV(hookMinX, intMaxY, hookMaxZ, hookMaxU, hookMaxV);
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-}
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 e6eef4658..c82f91d7c 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
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.block.model;
 
+import net.minecraft.client.render.block.model.generic.BlockModelGenericLeaves;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -13,7 +14,6 @@ import org.jetbrains.annotations.Nullable;
 import org.joml.primitives.AABBdc;
 
 public class BlockModelLeaves<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected static boolean fancyGraphics;
     protected final IconCoordinate fancyLeavesTexture;
     protected final boolean canBeRetro;
 
@@ -26,15 +26,11 @@ public class BlockModelLeaves<T extends BlockLogic> extends BlockModelStandard<T
 
     public BlockModelLeaves(Block<T> block, String leavesTex, boolean canBeRetro) {
         super(block);
-        setAllTextures(BLOCK_TEXTURES, leavesTex);
+        setAllTextures(leavesTex);
         this.fancyLeavesTexture = TextureRegistry.getTexture(leavesTex + "_fancy");
         this.canBeRetro = canBeRetro;
     }
 
-    public static void setGraphicsLevel(boolean graphicsLevel) {
-        fancyGraphics = graphicsLevel;
-    }
-
     @Override
     public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
         boolean invTint = renderBlocks.useInventoryTint;
@@ -54,14 +50,14 @@ public class BlockModelLeaves<T extends BlockLogic> extends BlockModelStandard<T
     @Override
     public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
         if (this.canBeRetro && isRetro()) {
-            return fancyGraphics ? this.retroLeavesFancy : this.retroLeaves;
+            return BlockModelGenericLeaves.fancyGraphics ? this.retroLeavesFancy : this.retroLeaves;
         }
-        return fancyGraphics ? this.fancyLeavesTexture : super.getBlockTextureFromSideAndMetadata(side, data);
+        return BlockModelGenericLeaves.fancyGraphics ? this.fancyLeavesTexture : super.getBlockTextureFromSideAndMetadata(side, data);
     }
 
     @Override
     public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        if (!fancyGraphics && source.getBlockId(tilePos) == this.block.id()) {
+        if (!BlockModelGenericLeaves.fancyGraphics && source.getBlockId(tilePos) == this.block.id()) {
             return false;
         } else {
             return super.shouldSideBeRendered(source, bounds, tilePos, side);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesCacao.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesCacao.java
deleted file mode 100644
index 34087f503..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesCacao.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.LightmapHelper;
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicLeavesCacao;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelLeavesCacao<T extends BlockLogic> extends BlockModelLeaves<T> {
-    protected IconCoordinate[] growthStages = new IconCoordinate[]{
-        TextureRegistry.getTexture("minecraft:block/leaves/cacao_bean_stage0"),
-        TextureRegistry.getTexture("minecraft:block/leaves/cacao_bean_stage1"),
-        TextureRegistry.getTexture("minecraft:block/leaves/cacao_bean_stage2"),
-        TextureRegistry.getTexture("minecraft:block/leaves/cacao_bean_stage3")};
-
-    public BlockModelLeavesCacao(Block<T> block) {
-        super(block, "minecraft:block/leaves/cacao");
-        assert this.growthStages.length == BlockLogicLeavesCacao.MAX_GROWTH_STATE : "There must be a texture associated with every cacao bean stage!";
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        super.render(tessellator, worldSource, tilePos);
-
-        AABBdc bounds = this.block.getBounds();
-
-        final int growthRate = BlockLogicLeavesCacao.getGrowthRate(worldSource.getBlockData(tilePos));
-        float brightness = 1.0f;
-        int lmc = this.block.getLightmapCoord(worldSource, tilePos);
-        if (this.block.emission > 0) {
-            lmc = LightmapHelper.setBlocklightValue(lmc, 15);
-        }
-        tessellator.setLightmapCoord1i(lmc);
-
-        final float cNorthSouth = 0.8F;
-        final float cEastWest = 0.6F;
-        if (growthRate > 0) {
-            renderBlocks.overrideBlockTexture = this.growthStages[Math.min(growthRate - 1, BlockLogicLeavesCacao.MAX_GROWTH_STATE - 1)];
-            tessellator.setColorOpaque3f(cNorthSouth * brightness, cNorthSouth * brightness, cNorthSouth * brightness);
-            renderBlocks.renderNorthFace(tessellator, bounds, tilePos, renderBlocks.overrideBlockTexture);
-            renderBlocks.renderSouthFace(tessellator, bounds, tilePos, renderBlocks.overrideBlockTexture);
-            tessellator.setColorOpaque3f(cEastWest * brightness, cEastWest * brightness, cEastWest * brightness);
-            renderBlocks.renderEastFace(tessellator, bounds, tilePos, renderBlocks.overrideBlockTexture);
-            renderBlocks.renderWestFace(tessellator, bounds, tilePos, renderBlocks.overrideBlockTexture);
-            renderBlocks.overrideBlockTexture = null;
-        }
-
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        super.renderStandalone(tessellator, metadata, lightmapCoord);
-        AABBdc bounds = this.block.getBounds();
-
-        final IconCoordinate cacaoCoord = this.growthStages[BlockLogicLeavesCacao.MAX_GROWTH_STATE - 1];
-
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cacaoCoord);
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cacaoCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cacaoCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cacaoCoord);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cacaoCoord);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cacaoCoord);
-        tessellator.draw();
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesCherryFlowering.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesCherryFlowering.java
deleted file mode 100644
index 4b35c283a..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeavesCherryFlowering.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicLeavesCherryFlowering;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelLeavesCherryFlowering<T extends BlockLogic> extends BlockModelLeaves<T> {
-    private final IconCoordinate grownCherryOverlay = TextureRegistry.getTexture("minecraft:block/leaves/cherry_overlay");
-    private final IconCoordinate floweringCherryOverlay = TextureRegistry.getTexture("minecraft:block/leaves/cherry_flowering_overlay");
-
-    public BlockModelLeavesCherryFlowering(Block<T> block) {
-        super(block, "minecraft:block/leaves/cherry");
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        super.render(tessellator, worldSource, tilePos);
-
-        int growthRate = BlockLogicLeavesCherryFlowering.getGrowthRate(worldSource.getBlockData(tilePos));
-        if (growthRate > 0) {
-            renderBlocks.overrideBlockTexture = this.grownCherryOverlay;
-        } else {
-            renderBlocks.overrideBlockTexture = this.floweringCherryOverlay;
-        }
-
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, this.block.getBoundsRaw(), tilePos, 1.0f, 1.0f, 1.0f);
-        renderBlocks.overrideBlockTexture = null;
-
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        super.renderStandalone(tessellator, metadata, lightmapCoord);
-
-        AABBdc bounds = this.block.getBoundsRaw();
-        IconCoordinate cherryCoord = this.grownCherryOverlay;
-
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cherryCoord);
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cherryCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cherryCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cherryCoord);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cherryCoord);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, cherryCoord);
-        tessellator.draw();
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLever.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLever.java
deleted file mode 100644
index 35ec6d67f..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLever.java
+++ /dev/null
@@ -1,188 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicLever;
-import net.minecraft.core.util.helper.MathHelper;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.Vector3d;
-import org.joml.primitives.AABBd;
-
-public class BlockModelLever<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelLever(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        int data = worldSource.getBlockData(tilePos);
-        int rotation = data & BlockLogicLever.MASK_ROTATION;
-        boolean powered = (data & BlockLogicLever.MASK_POWERED) != 0;
-        boolean overrideTexture = renderBlocks.overrideBlockTexture != null;
-        if (!overrideTexture) {
-            renderBlocks.overrideBlockTexture = TextureRegistry.getTexture("minecraft:block/cobbled_stone");
-        }
-        float f = 0.25F;
-        float f1 = 0.1875F;
-        float f2 = 0.1875F;
-        AABBd bounds = new AABBd(this.block.getBounds());
-        switch (rotation) {
-            case BlockLogicLever.ROTATION_BOTTOM_NS:
-                bounds.setMin(0.5F - f1, 1f - f2, 0.5F - f).setMax(0.5F + f1, 1f, 0.5F + f);
-                break;
-            case BlockLogicLever.ROTATION_BOTTOM_WE:
-                bounds.setMin(0.5F - f, 1f - f2, 0.5F - f1).setMax(0.5F + f, 1f, 0.5F + f1);
-                break;
-            case BlockLogicLever.ROTATION_TOP_NS:
-                bounds.setMin(0.5F - f1, 0.0F, 0.5F - f).setMax(0.5F + f1, f2, 0.5F + f);
-                break;
-            case BlockLogicLever.ROTATION_TOP_WE:
-                bounds.setMin(0.5F - f, 0.0F, 0.5F - f1).setMax(0.5F + f, f2, 0.5F + f1);
-                break;
-            case BlockLogicLever.ROTATION_NORTH:
-                bounds.setMin(0.5F - f1, 0.5F - f, 1.0F - f2).setMax(0.5F + f1, 0.5F + f, 1.0F);
-                break;
-            case BlockLogicLever.ROTATION_SOUTH:
-                bounds.setMin(0.5F - f1, 0.5F - f, 0.0F).setMax(0.5F + f1, 0.5F + f, f2);
-                break;
-            case BlockLogicLever.ROTATION_WEST:
-                bounds.setMin(1.0F - f2, 0.5F - f, 0.5F - f1).setMax(1.0F, 0.5F + f, 0.5F + f1);
-                break;
-            case BlockLogicLever.ROTATION_EAST:
-                bounds.setMin(0.0F, 0.5F - f, 0.5F - f1).setMax(f2, 0.5F + f, 0.5F + f1);
-                break;
-        }
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-        if (!overrideTexture) {
-            renderBlocks.overrideBlockTexture = null;
-        }
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.BOTTOM, data);
-        if (renderBlocks.overrideBlockTexture != null) {
-            texture = renderBlocks.overrideBlockTexture;
-        }
-        double f4 = texture.getIconUMin();
-        double f5 = texture.getIconUMax();
-        double f6 = texture.getIconVMin();
-        double f7 = texture.getIconVMax();
-        Vector3d[] renderVecs = new Vector3d[8];
-        float f8 = 0.0625F;
-        float f9 = 0.0625F;
-        float f10 = 0.625F;
-        renderVecs[0] = new Vector3d(-f8, 0.0D, -f9);
-        renderVecs[1] = new Vector3d(f8, 0.0D, -f9);
-        renderVecs[2] = new Vector3d(f8, 0.0D, f9);
-        renderVecs[3] = new Vector3d(-f8, 0.0D, f9);
-        renderVecs[4] = new Vector3d(-f8, f10, -f9);
-        renderVecs[5] = new Vector3d(f8, f10, -f9);
-        renderVecs[6] = new Vector3d(f8, f10, f9);
-        renderVecs[7] = new Vector3d(-f8, f10, f9);
-        for (int i2 = 0; i2 < 8; i2++) {
-            if (powered) {
-                renderVecs[i2].z -= 0.0625D;
-                renderVecs[i2].rotateX(-0.6981317F);
-            } else {
-                renderVecs[i2].z += 0.0625D;
-                renderVecs[i2].rotateX(0.6981317F);
-            }
-            if (rotation == 6 || rotation == 8) {
-                renderVecs[i2].rotateY(-MathHelper.PI / 2f);
-            }
-            if (rotation < 5) {
-                renderVecs[i2].y -= 0.375D;
-                renderVecs[i2].rotateX(-MathHelper.PI / 2f);
-                if (rotation == 4) {
-                    renderVecs[i2].rotateY(0.0F);
-                }
-                if (rotation == 3) {
-                    renderVecs[i2].rotateY(-MathHelper.PI);
-                }
-                if (rotation == 2) {
-                    renderVecs[i2].rotateY(MathHelper.PI / 2f);
-                }
-                if (rotation == 1) {
-                    renderVecs[i2].rotateY(-MathHelper.PI / 2f);
-                }
-                renderVecs[i2].x += (double) tilePos.x() + 0.5D;
-                renderVecs[i2].y += (float) tilePos.y() + 0.5F;
-                renderVecs[i2].z += (double) tilePos.z() + 0.5D;
-            } else if (rotation == 5 || rotation == 6) {
-                renderVecs[i2].x += (double) tilePos.x() + 0.5D;
-                renderVecs[i2].y += (float) tilePos.y() + 0.125F;
-                renderVecs[i2].z += (double) tilePos.z() + 0.5D;
-            } else {
-                renderVecs[i2].rotateX(MathHelper.PI);
-                renderVecs[i2].x += (double) tilePos.x() + 0.5D;
-                renderVecs[i2].y += (float) (tilePos.y() + 1) - 0.125D;
-                renderVecs[i2].z += (double) tilePos.z() + 0.5D;
-            }
-        }
-
-        Vector3d vec3;
-        Vector3d vec31;
-        Vector3d vec32;
-        Vector3d vec3d3;
-        for (int j2 = 0; j2 < 6; j2++) {
-            if (j2 == 0) {
-                f4 = texture.getSubIconU(0.4375);
-                f5 = texture.getSubIconU(0.5625);
-                f6 = texture.getSubIconV(0.375);
-                f7 = texture.getSubIconV(0.5);
-            } else if (j2 == 2) {
-                f4 = texture.getSubIconU(0.4375);
-                f5 = texture.getSubIconU(0.5625);
-                f6 = texture.getSubIconV(0.375);
-                f7 = texture.getIconVMax();
-            }
-            if (j2 == 0) {
-                vec3 = renderVecs[0];
-                vec31 = renderVecs[1];
-                vec32 = renderVecs[2];
-                vec3d3 = renderVecs[3];
-            } else if (j2 == 1) {
-                vec3 = renderVecs[7];
-                vec31 = renderVecs[6];
-                vec32 = renderVecs[5];
-                vec3d3 = renderVecs[4];
-            } else if (j2 == 2) {
-                vec3 = renderVecs[1];
-                vec31 = renderVecs[0];
-                vec32 = renderVecs[4];
-                vec3d3 = renderVecs[5];
-            } else if (j2 == 3) {
-                vec3 = renderVecs[2];
-                vec31 = renderVecs[1];
-                vec32 = renderVecs[5];
-                vec3d3 = renderVecs[6];
-            } else if (j2 == 4) {
-                vec3 = renderVecs[3];
-                vec31 = renderVecs[2];
-                vec32 = renderVecs[6];
-                vec3d3 = renderVecs[7];
-            } else {
-                vec3 = renderVecs[0];
-                vec31 = renderVecs[3];
-                vec32 = renderVecs[7];
-                vec3d3 = renderVecs[4];
-            }
-            tessellator.addVertexWithUV(vec3.x, vec3.y, vec3.z, f4, f7);
-            tessellator.addVertexWithUV(vec31.x, vec31.y, vec31.z, f5, f7);
-            tessellator.addVertexWithUV(vec32.x, vec32.y, vec32.z, f5, f6);
-            tessellator.addVertexWithUV(vec3d3.x, vec3d3.y, vec3d3.z, f4, f6);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelMatcher.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelMatcher.java
deleted file mode 100644
index d26ffeb3c..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelMatcher.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.Side;
-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.DisplayPos;
-
-import java.util.Map;
-import java.util.Random;
-
-public class BlockModelMatcher<T extends BlockLogic> extends BlockModelAxisAligned<T> {
-    public IconCoordinate[] frontVariants;
-    public IconCoordinate[] frontOverlayVariants;
-    public final Random random = new Random();
-
-    public BlockModelMatcher(Block<T> block, boolean isPowered) {
-        super(block);
-        this.frontVariants = new IconCoordinate[4];
-        this.frontOverlayVariants = new IconCoordinate[this.frontVariants.length];
-        for (int i = 0; i < this.frontVariants.length; i++) {
-            this.frontVariants[i] = TextureRegistry.getTexture("minecraft:block/matcher/front" + (isPowered ? "_active" : "") + i);
-            this.frontOverlayVariants[i] = TextureRegistry.getTexture("minecraft:block/matcher/front" + (isPowered ? "_active" : "") + "_overlay" + i);
-        }
-
-        for (Map.Entry<String, DisplayPos> e : this.displayPosMap.entrySet()) {
-            DisplayPos p = this.displayPosMap.get(e.getKey());
-            boolean flip = e.getKey().equals(DisplayPos.FIRST_PERSON_RIGHT_HAND) || e.getKey().equals(DisplayPos.THIRD_PERSON_RIGHT_HAND) || e.getKey().equals(DisplayPos.THIRD_PERSON_LEFT_HAND);
-            this.displayPosMap.put(e.getKey(), new DisplayPos(p.tx, p.ty, p.tz, p.rx, p.ry + (flip ? -90 : 90), p.rz, p.sx, p.sy, p.sz));
-        }
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        Side rotated = getRotatedSide(side, source.getBlockData(tilePos));
-        if (rotated.getAxis() == Axis.Y) {
-            this.random.setSeed(getPositionalSeed(tilePos));
-            return this.frontVariants[this.random.nextInt(this.frontVariants.length)];
-        }
-        return super.getBlockTexture(source, tilePos, side);
-    }
-
-    public long getPositionalSeed(@NotNull TilePosc tilePos) {
-        return tilePos.x() * 374761393L + tilePos.y() * 668265263L + tilePos.z() * 968290493L;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelOverlayLeaves.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelOverlayLeaves.java
deleted file mode 100644
index a33143806..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelOverlayLeaves.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelOverlayLeaves<T extends BlockLogic> extends BlockModelLeaves<T> {
-    protected final IconCoordinate overlayTexture;
-
-    public BlockModelOverlayLeaves(Block<T> block, String leavesTex, String overlayTex) {
-        super(block, leavesTex);
-        this.overlayTexture = TextureRegistry.getTexture(overlayTex);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        super.render(tessellator, worldSource, tilePos);
-
-        renderBlocks.overrideBlockTexture = this.overlayTexture;
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, this.block.getBoundsRaw(), tilePos, 1.0f, 1.0f, 1.0f);
-        renderBlocks.overrideBlockTexture = null;
-
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        super.renderStandalone(tessellator, metadata, lightmapCoord);
-
-        AABBdc bounds = this.block.getBounds();
-        IconCoordinate overlayCoord = this.overlayTexture;
-
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, overlayCoord);
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, overlayCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, overlayCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, overlayCoord);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, overlayCoord);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, overlayCoord);
-        tessellator.draw();
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPebbles.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPebbles.java
deleted file mode 100644
index ca87b5434..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPebbles.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.LightmapHelper;
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.MathHelper;
-import net.minecraft.core.util.helper.Side;
-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.jetbrains.annotations.Nullable;
-
-public class BlockModelPebbles<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected IconCoordinate[] pebbles = {
-        TextureRegistry.getTexture("minecraft:block/pebbles/0"),
-        TextureRegistry.getTexture("minecraft:block/pebbles/1"),
-        TextureRegistry.getTexture("minecraft:block/pebbles/2")
-    };
-
-    public BlockModelPebbles(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        tessellator.setLightmapCoord1i(LightmapHelper.max(this.block.getLightmapCoord(worldSource, tilePos), this.block.getLightmapCoord(worldSource, tilePos.down(new TilePos()))));
-        renderBlocks.renderTopFace(tessellator,
-            this.block.getBoundsFromState(worldSource, tilePos),
-            tilePos,
-            getBlockTextureFromSideAndMetadata(Side.TOP, worldSource.getBlockData(tilePos)));
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        return this.pebbles[MathHelper.clamp(data, 0, 2)];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPiePumpkin.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPiePumpkin.java
deleted file mode 100644
index 7a36c1035..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPiePumpkin.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.BlockLogicEdible;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBd;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelPiePumpkin<T extends BlockLogicEdible> extends BlockModelStandard<T> {
-    protected IconCoordinate sideTexture = TextureRegistry.getTexture("minecraft:block/pumpkin_pie/side");
-    protected IconCoordinate insideTexture = TextureRegistry.getTexture("minecraft:block/pumpkin_pie/inner");
-    protected IconCoordinate topTexture = TextureRegistry.getTexture("minecraft:block/pumpkin_pie/top");
-
-    public BlockModelPiePumpkin(final Block<T> block) {
-        super(block);
-        final float f = 0.0625F;
-        final float f1 = 0.375F;
-        withCustomItemBounds(f, 0.0F, f, 1.0F - f, f1, 1.0F - f);
-    }
-
-    public void renderSliceSide(final @NotNull TessellatorGeneral tessellator, final @NotNull WorldSource worldSource, final @NotNull AABBdc bounds, @NotNull TilePosc tilePos, final @NotNull Side side, final boolean overrideTex) {
-        if (overrideTex)
-            renderBlocks.overrideBlockTexture = this.insideTexture;
-        renderBlocks.renderSide(tessellator, worldSource, this, bounds, tilePos, 1, 1, 1, side, 0);
-        if (overrideTex)
-            renderBlocks.overrideBlockTexture = null;
-    }
-
-    private void renderSlice(final @NotNull TessellatorGeneral tessellator, final @NotNull WorldSource worldSource, final @NotNull AABBdc bounds, @NotNull TilePosc tilePos, final int sliceX, final int sliceZ) {
-
-        final double onePix = 0.0625;
-        final double sliceWidth = onePix * 8;
-
-        final double xMin = 0.0F + (sliceWidth * sliceX);
-        final double xMax = xMin + sliceWidth;
-
-        final double zMin = 0.0F + (sliceWidth * sliceZ);
-        final double zMax = zMin + sliceWidth;
-        final double offsetXMin = sliceX == 0 ? onePix : 0;
-        final double offsetXMax = sliceX == 1 ? onePix : 0;
-        final double offsetZMin = sliceZ == 0 ? onePix : 0;
-        final double offsetZMax = sliceZ == 1 ? onePix : 0;
-
-        final boolean insideSouth = sliceZ == 0;
-        final boolean insideNorth = sliceZ == 1;
-        final boolean insideEast = sliceX == 0;
-        final boolean insideWest = sliceX == 1;
-
-        AABBdc newBounds = new AABBd(xMin + offsetXMin, 0.0F, zMin + offsetZMin, xMax - offsetXMax, 0.375F, zMax - offsetZMax);
-        renderBlocks.renderSide(tessellator, worldSource, this, newBounds, tilePos, 1, 1, 1, Side.TOP, 0);
-        renderBlocks.renderSide(tessellator, worldSource, this, newBounds, tilePos, 1, 1, 1, Side.BOTTOM, 0);
-        renderSliceSide(tessellator, worldSource, newBounds, tilePos, Side.SOUTH, insideSouth);
-        renderSliceSide(tessellator, worldSource, newBounds, tilePos, Side.WEST, insideWest);
-        renderBlocks.flipTexture = true;
-        renderSliceSide(tessellator, worldSource, newBounds, tilePos, Side.NORTH, insideNorth);
-        renderSliceSide(tessellator, worldSource, newBounds, tilePos, Side.EAST, insideEast);
-        renderBlocks.flipTexture = false;
-    }
-
-    @Override
-    public boolean render(final @NotNull TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos) {
-        final AABBdc bounds = this.block.getBoundsFromState(worldSource, tilePos);
-
-        final int meta = worldSource.getBlockData(tilePos);
-        renderBlocks.enableAO = true;
-        renderBlocks.cache.setupCache(this.block, worldSource, tilePos);
-        int slices = 0;
-        for (int xSlice = 0; xSlice < 2; xSlice++) {
-            for (int zSlice = 0; zSlice < 2; zSlice++) {
-                slices++;
-                if (meta >= slices)
-                    continue;
-                renderSlice(tessellator, worldSource, bounds, tilePos, xSlice, zSlice);
-            }
-        }
-
-        renderBlocks.enableAO = false;
-        return true;
-    }
-
-
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPiston.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPiston.java
deleted file mode 100644
index dcdcbf928..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPiston.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.piston.BlockLogicPistonBase;
-import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.helper.Side;
-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.jetbrains.annotations.Nullable;
-import org.joml.primitives.AABBd;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelPiston<T extends BlockLogicPistonBase> extends BlockModelStandard<T> {
-    private final @NotNull IconCoordinate faceTexture;
-    protected @NotNull IconCoordinate sideTexture = TextureRegistry.getTexture("minecraft:block/piston/side");
-    protected @NotNull IconCoordinate topTexture = TextureRegistry.getTexture("minecraft:block/piston/top");
-    protected @NotNull IconCoordinate bottomTexture = TextureRegistry.getTexture("minecraft:block/piston/bottom");
-
-    protected final double headThickness;
-
-    public BlockModelPiston(Block<T> block, @NotNull IconCoordinate faceTexture) {
-        this(block, faceTexture, 4 / 16d);
-    }
-
-    public BlockModelPiston(Block<T> block, @NotNull IconCoordinate faceTexture, double headThickness) {
-        super(block);
-        this.headThickness = headThickness;
-        this.faceTexture = faceTexture;
-    }
-
-    public BlockModelPiston<T> setPistonTextures(@NotNull IconCoordinate sideTexture, @NotNull IconCoordinate topTexture, @NotNull IconCoordinate bottomTexture) {
-        this.sideTexture = sideTexture;
-        this.topTexture = topTexture;
-        this.bottomTexture = bottomTexture;
-        return this;
-    }
-
-    public BlockModelPiston<T> setPistonTextures(@NotNull String sideTexture, @NotNull String topTexture, @NotNull String bottomTexture) {
-        return setPistonTextures(TextureRegistry.getTexture(sideTexture), TextureRegistry.getTexture(topTexture), TextureRegistry.getTexture(bottomTexture));
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        return renderPistonBase(tessellator, worldSource, tilePos, false);
-    }
-
-    private boolean headless = false;
-
-    public boolean renderHeadless(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePos tilePos) {
-        renderBlocks.renderAllFaces = true;
-        this.headless = true;
-        boolean result = renderPistonBase(tessellator, worldSource, tilePos, true);
-        this.headless = false;
-        renderBlocks.renderAllFaces = false;
-        return result;
-    }
-
-    protected boolean renderPistonBase(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean noCulling) {
-        int meta = worldSource.getBlockData(tilePos);
-        boolean extended = noCulling || (meta & 8) != 0;
-        Direction direction = BlockLogicPistonBase.getDirection(meta);
-        AABBdc bounds;
-        if (extended) {
-            switch (direction) {
-                case DOWN: // '\0'
-                    renderBlocks.uvRotateEast = 3;
-                    renderBlocks.uvRotateWest = 3;
-                    renderBlocks.uvRotateSouth = 3;
-                    renderBlocks.uvRotateNorth = 3;
-                    bounds = new AABBd(0.0F, this.headThickness, 0.0F, 1.0F, 1.0F, 1.0F);
-                    break;
-
-                case UP: // '\001'
-                    bounds = new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1 - this.headThickness, 1.0F);
-                    break;
-
-                case NORTH: // '\002'
-                    renderBlocks.uvRotateSouth = 1;
-                    renderBlocks.uvRotateNorth = 2;
-                    bounds = new AABBd(0.0F, 0.0F, this.headThickness, 1.0F, 1.0F, 1.0F);
-                    break;
-
-                case SOUTH: // '\003'
-                    renderBlocks.uvRotateSouth = 2;
-                    renderBlocks.uvRotateNorth = 1;
-                    renderBlocks.uvRotateTop = 3;
-                    renderBlocks.uvRotateBottom = 3;
-                    bounds = new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1 - this.headThickness);
-                    break;
-
-                case WEST: // '\004'
-                    renderBlocks.uvRotateEast = 1;
-                    renderBlocks.uvRotateWest = 2;
-                    renderBlocks.uvRotateTop = 2;
-                    renderBlocks.uvRotateBottom = 1;
-                    bounds = new AABBd(this.headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
-                    break;
-
-                case EAST: // '\005'
-                    renderBlocks.uvRotateEast = 2;
-                    renderBlocks.uvRotateWest = 1;
-                    renderBlocks.uvRotateTop = 1;
-                    renderBlocks.uvRotateBottom = 2;
-                    bounds = new AABBd(0.0F, 0.0F, 0.0F, 1 - this.headThickness, 1.0F, 1.0F);
-                    break;
-
-                default:
-                    bounds = new AABBd(0, 0, 0, 1, 1, 1);
-            }
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-            renderBlocks.resetRenderBlocks();
-        } else {
-            switch (direction) {
-                case DOWN: // '\0'
-                    renderBlocks.uvRotateEast = 3;
-                    renderBlocks.uvRotateWest = 3;
-                    renderBlocks.uvRotateSouth = 3;
-                    renderBlocks.uvRotateNorth = 3;
-                    break;
-
-                case NORTH: // '\002'
-                    renderBlocks.uvRotateSouth = 1;
-                    renderBlocks.uvRotateNorth = 2;
-                    break;
-
-                case SOUTH: // '\003'
-                    renderBlocks.uvRotateSouth = 2;
-                    renderBlocks.uvRotateNorth = 1;
-                    renderBlocks.uvRotateTop = 3;
-                    renderBlocks.uvRotateBottom = 3;
-                    break;
-
-                case WEST: // '\004'
-                    renderBlocks.uvRotateEast = 1;
-                    renderBlocks.uvRotateWest = 2;
-                    renderBlocks.uvRotateTop = 2;
-                    renderBlocks.uvRotateBottom = 1;
-                    break;
-
-                case EAST: // '\005'
-                    renderBlocks.uvRotateEast = 2;
-                    renderBlocks.uvRotateWest = 1;
-                    renderBlocks.uvRotateTop = 1;
-                    renderBlocks.uvRotateBottom = 2;
-                    break;
-            }
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, this.block.getBounds(), tilePos);
-            renderBlocks.resetRenderBlocks();
-        }
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        super.renderStandalone(tessellator, 1, lightmapCoord);
-    }
-
-    public @NotNull IconCoordinate getFaceTexture() {
-        return this.faceTexture;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        Direction direction = BlockLogicPistonBase.getDirection(data);
-        if (direction == Direction.NONE) {
-            return this.blockTextures.get(Side.BOTTOM);
-        }
-        if (side.getDirection() == direction) {
-            if (BlockLogicPistonBase.isPowered(data) || this.headless) {
-                return this.topTexture;
-            } else {
-                return this.blockTextures.get(Side.BOTTOM);
-            }
-        }
-        return side.getDirection() != direction.getOpposite() ? this.sideTexture : this.bottomTexture;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPistonHead.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPistonHead.java
deleted file mode 100644
index 06848fd3b..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPistonHead.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Block;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.block.piston.BlockLogicPistonHead;
-import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.helper.Side;
-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.jetbrains.annotations.Nullable;
-import org.joml.primitives.AABBd;
-
-public class BlockModelPistonHead extends BlockModelStandard<BlockLogicPistonHead> {
-    protected IconCoordinate pistonHead;
-    protected IconCoordinate pistonShaft;
-    protected IconCoordinate pistonDry = TextureRegistry.getTexture("minecraft:block/piston/face");
-    protected IconCoordinate pistonSticky = TextureRegistry.getTexture("minecraft:block/piston_sticky/face");
-    protected IconCoordinate pistonSteel = TextureRegistry.getTexture("minecraft:block/piston_steel/face");
-    @Nullable
-    public IconCoordinate faceTextureOverride;
-
-    protected final double headThickness;
-    protected final double shaftThickness;
-
-    public BlockModelPistonHead(final Block<BlockLogicPistonHead> block, final IconCoordinate pistonHead, final IconCoordinate pistonShaft) {
-        this(block, pistonHead, pistonShaft, 4 / 16d, 4 / 16d);
-    }
-
-    public BlockModelPistonHead(final Block<BlockLogicPistonHead> block, final IconCoordinate pistonHead, final IconCoordinate pistonShaft, final double headThickness, final double shaftThickness) {
-        super(block);
-        this.pistonHead = pistonHead;
-        this.pistonShaft = pistonShaft;
-        this.headThickness = headThickness;
-        this.shaftThickness = shaftThickness;
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        return renderPistonHead(tessellator, worldSource, this.block, tilePos, true);
-    }
-
-    public void renderPistonHeadNoCulling(@NotNull TessellatorGeneral tessellator, WorldSource worldSource, Block<BlockLogicPistonHead> block, @NotNull TilePos tilePos, boolean flag) {
-        renderBlocks.renderAllFaces = true;
-        renderPistonHead(tessellator, worldSource, block, tilePos, flag);
-        renderBlocks.renderAllFaces = false;
-    }
-
-    public void setFaceTextureOverride(@Nullable final IconCoordinate faceTexture) {
-        this.faceTextureOverride = faceTexture;
-    }
-
-    protected boolean renderPistonHead(@NotNull TessellatorGeneral tessellator, WorldSource worldSource, Block<BlockLogicPistonHead> block, @NotNull TilePosc tilePos, boolean flag) {
-        int metadata = worldSource.getBlockData(tilePos);
-        Direction direction = BlockLogicPistonHead.getDirectionFromMeta(metadata);
-        float brightness = 1.0f;
-        tessellator.setLightmapCoord1i(block.getLightmapCoord(worldSource, tilePos));
-        final float f1 = flag ? 1.0F : 0.5F;
-        final double width = flag ? 1 : 1 / 2d;
-
-        final int x = tilePos.x();
-        final int y = tilePos.y();
-        final int z = tilePos.z();
-
-        switch (direction) {
-            case DOWN: // BOTTOM
-                renderBlocks.uvRotateEast = 3;
-                renderBlocks.uvRotateWest = 3;
-                renderBlocks.uvRotateSouth = 3;
-                renderBlocks.uvRotateNorth = 3;
-                renderBlocks.renderStandardBlock(tessellator, worldSource, this, new AABBd(0.0F, 0.0F, 0.0F, 1.0F, this.headThickness, 1.0F), tilePos);
-                renderHeadTopBottom(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, y + this.headThickness, y + this.headThickness + f1, z + 0.5 + this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, y + this.headThickness, y + this.headThickness + f1, z + 0.5 - this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, y + this.headThickness, y + this.headThickness + f1, z + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness * 0.6F, width);
-                renderHeadTopBottom(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, y + this.headThickness, y + this.headThickness + f1, z + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.6F, width);
-                break;
-
-            case UP: // TOP
-                renderBlocks.renderStandardBlock(tessellator, worldSource, this, new AABBd(0.0F, 1 - this.headThickness, 0.0F, 1.0F, 1.0F, 1.0F), tilePos);
-                renderHeadTopBottom(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, ((y - this.headThickness) + 1.0F) - f1, (y - this.headThickness) + 1.0F, z + 0.5 + this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, ((y - this.headThickness) + 1.0F) - f1, (y - this.headThickness) + 1.0F, z + 0.5 - this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.8F, width);
-                renderHeadTopBottom(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, ((y - this.headThickness) + 1.0F) - f1, (y - this.headThickness) + 1.0F, z + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness * 0.6F, width);
-                renderHeadTopBottom(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, ((y - this.headThickness) + 1.0F) - f1, (y - this.headThickness) + 1.0F, z + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.6F, width);
-                break;
-
-            case NORTH: // NORTH
-                renderBlocks.uvRotateSouth = 1;
-                renderBlocks.uvRotateNorth = 2;
-                renderBlocks.renderStandardBlock(tessellator, worldSource, this, new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, this.headThickness), tilePos);
-                renderHeadNorthSouth(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, z + this.headThickness, z + this.headThickness + f1, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, z + this.headThickness, z + this.headThickness + f1, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, z + this.headThickness, z + this.headThickness + f1, brightness * 0.5F, width);
-                renderHeadNorthSouth(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, z + this.headThickness, z + this.headThickness + f1, brightness, width);
-                break;
-
-            case SOUTH: // SOUTH
-                renderBlocks.uvRotateSouth = 2;
-                renderBlocks.uvRotateNorth = 1;
-                renderBlocks.uvRotateTop = 3;
-                renderBlocks.uvRotateBottom = 3;
-                renderBlocks.renderStandardBlock(tessellator, worldSource, this, new AABBd(0.0F, 0.0F, 1 - this.headThickness, 1.0F, 1.0F, 1.0F), tilePos);
-                renderHeadNorthSouth(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, ((z - this.headThickness) + 1.0F) - f1, (z - this.headThickness) + 1.0F, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, ((z - this.headThickness) + 1.0F) - f1, (z - this.headThickness) + 1.0F, brightness * 0.6F, width);
-                renderHeadNorthSouth(tessellator, x + 0.5 - this.shaftThickness / 2, x + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, ((z - this.headThickness) + 1.0F) - f1, (z - this.headThickness) + 1.0F, brightness * 0.5F, width);
-                renderHeadNorthSouth(tessellator, x + 0.5 + this.shaftThickness / 2, x + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, ((z - this.headThickness) + 1.0F) - f1, (z - this.headThickness) + 1.0F, brightness, width);
-                break;
-
-            case WEST: // WEST
-                renderBlocks.uvRotateEast = 1;
-                renderBlocks.uvRotateWest = 2;
-                renderBlocks.uvRotateTop = 2;
-                renderBlocks.uvRotateBottom = 1;
-                renderBlocks.renderStandardBlock(tessellator, worldSource, this, new AABBd(0.0F, 0.0F, 0.0F, this.headThickness, 1.0F, 1.0F), tilePos);
-                renderHeadEastWest(tessellator, x + this.headThickness, x + this.headThickness + f1, y + 0.5 - this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.5F, width);
-                renderHeadEastWest(tessellator, x + this.headThickness, x + this.headThickness + f1, y + 0.5 + this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness, width);
-                renderHeadEastWest(tessellator, x + this.headThickness, x + this.headThickness + f1, y + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.6F, width);
-                renderHeadEastWest(tessellator, x + this.headThickness, x + this.headThickness + f1, y + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness * 0.6F, width);
-                break;
-
-            case EAST: // EAST
-                renderBlocks.uvRotateEast = 2;
-                renderBlocks.uvRotateWest = 1;
-                renderBlocks.uvRotateTop = 1;
-                renderBlocks.uvRotateBottom = 2;
-                renderBlocks.renderStandardBlock(tessellator, worldSource, this, new AABBd(1 - this.headThickness, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F), tilePos);
-                renderHeadEastWest(tessellator, ((x - this.headThickness) + 1.0F) - f1, (x - this.headThickness) + 1.0F, y + 0.5 - this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.5F, width);
-                renderHeadEastWest(tessellator, ((x - this.headThickness) + 1.0F) - f1, (x - this.headThickness) + 1.0F, y + 0.5 + this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness, width);
-                renderHeadEastWest(tessellator, ((x - this.headThickness) + 1.0F) - f1, (x - this.headThickness) + 1.0F, y + 0.5 - this.shaftThickness / 2, y + 0.5 + this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, z + 0.5 - this.shaftThickness / 2, brightness * 0.6F, width);
-                renderHeadEastWest(tessellator, ((x - this.headThickness) + 1.0F) - f1, (x - this.headThickness) + 1.0F, y + 0.5 + this.shaftThickness / 2, y + 0.5 - this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, z + 0.5 + this.shaftThickness / 2, brightness * 0.6F, width);
-                break;
-        }
-        renderBlocks.resetRenderBlocks();
-        return true;
-    }
-
-    private void renderHeadTopBottom(final @NotNull TessellatorGeneral tessellator, final double xMin, final double xMax, final double yMin, final double yMax, final double zMin, final double zMax, final float brightness, final double width) {
-        final IconCoordinate i = renderBlocks.overrideBlockTexture != null ? renderBlocks.overrideBlockTexture : this.pistonShaft;
-        final double uMin = i.getSubIconU(0.5 - this.shaftThickness / 2);
-        final double vMin = i.getIconVMin();
-        final double uMax = i.getSubIconU(0.5 + this.shaftThickness / 2);
-        final double vMax = i.getSubIconV(width);
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-        tessellator.addVertexWithUV(xMin, yMax, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMin, yMin, zMin, uMax, vMin);
-        tessellator.addVertexWithUV(xMax, yMin, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yMax, zMax, uMin, vMax);
-    }
-
-    private void renderHeadNorthSouth(final @NotNull TessellatorGeneral tessellator, final double xMin, final double xMax, final double yMin, final double yMax, final double zMin, final double zMax, final float brightness, final double width) {
-        final IconCoordinate i = renderBlocks.overrideBlockTexture != null ? renderBlocks.overrideBlockTexture : this.pistonShaft;
-        final double uMin = i.getSubIconU(0.5 - this.shaftThickness / 2);
-        final double vMin = i.getIconVMin();
-        final double uMax = i.getSubIconU(0.5 + this.shaftThickness / 2);
-        final double vMax = i.getSubIconV(width);
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-        tessellator.addVertexWithUV(xMin, yMin, zMax, uMax, vMax);
-        tessellator.addVertexWithUV(xMin, yMin, zMin, uMax, vMin);
-        tessellator.addVertexWithUV(xMax, yMax, zMin, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yMax, zMax, uMin, vMax);
-    }
-
-    private void renderHeadEastWest(final @NotNull TessellatorGeneral tessellator, final double xMin, final double xMax, final double yMin, final double yMax, final double zMin, final double zMax, final float brightness, final double width) {
-        final IconCoordinate i = renderBlocks.overrideBlockTexture != null ? renderBlocks.overrideBlockTexture : this.pistonShaft;
-        final double uMin = i.getSubIconU(0.5 - this.shaftThickness / 2);
-        final double vMin = i.getIconVMin();
-        final double uMax = i.getSubIconU(0.5 + this.shaftThickness / 2);
-        final double vMax = i.getSubIconV(width);
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-        tessellator.addVertexWithUV(xMax, yMin, zMin, uMax, vMax);
-        tessellator.addVertexWithUV(xMin, yMin, zMin, uMax, vMin);
-        tessellator.addVertexWithUV(xMin, yMax, zMax, uMin, vMin);
-        tessellator.addVertexWithUV(xMax, yMax, zMax, uMin, vMax);
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        final Direction direction = BlockLogicPistonHead.getDirectionFromMeta(data);
-        if (side.getDirection() == direction) {
-            if (this.faceTextureOverride != null) {
-                return this.faceTextureOverride;
-            }
-            switch (BlockLogicPistonHead.getPistonType(data)) {
-                case BlockLogicPistonHead.TYPE_NORMAL:
-                    return this.pistonDry;
-                case BlockLogicPistonHead.TYPE_STICKY:
-                    return this.pistonSticky;
-                case BlockLogicPistonHead.TYPE_STEEL:
-                    return this.pistonSteel;
-            }
-        }
-        final boolean isSteel = this.block == Blocks.PISTON_HEAD_STEEL; // Todo this is just awful
-        return side.getDirection() != direction.getOpposite() ? this.pistonHead : ((isSteel) ? this.pistonSteel : this.pistonDry); // TODO remove this horrid ternary
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPlanksPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPlanksPainted.java
deleted file mode 100644
index 98d876720..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPlanksPainted.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelPlanksPainted<T extends BlockLogic> extends BlockModelStandard<T> {
-    public static final IconCoordinate[] texCoords = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-
-    static {
-        for (DyeColor c : DyeColor.blockOrderedColors()) {
-            texCoords[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/planks/" + c.colorID);
-        }
-    }
-
-    public BlockModelPlanksPainted(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int meta) {
-        return texCoords[meta & DyeColor.MASK_COLOR];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPortal.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPortal.java
deleted file mode 100644
index 2685af80c..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPortal.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicPortal;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-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.primitives.AABBdc;
-
-public class BlockModelPortal<T extends BlockLogicPortal> extends BlockModelTransparent<T> {
-    protected IconCoordinate[] colors = new IconCoordinate[16];
-
-    public BlockModelPortal(Block<T> block, String rootTexKey) {
-        super(block, false);
-        for (DyeColor color : DyeColor.values()) {
-            this.colors[color.blockMeta] = TextureRegistry.getTexture(rootTexKey + color.colorID);
-        }
-        onRenderLayer(1);
-    }
-
-    @Override
-    public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        if (source.getBlockId(tilePos) == this.block.id()) {
-            return false;
-        }
-        return super.shouldSideBeRendered(source, bounds, tilePos, side);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        return this.colors[this.block.getLogic().fromMetadata(data).blockMeta];
-    }
-
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPressurePlatePainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPressurePlatePainted.java
deleted file mode 100644
index d58283d25..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPressurePlatePainted.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelPressurePlatePainted<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected final IconCoordinate[] texCoords = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-
-    public BlockModelPressurePlatePainted(final Block<T> block) {
-        super(block);
-        for (final DyeColor c : DyeColor.blockOrderedColors()) {
-            this.texCoords[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/planks/" + c.colorID);
-        }
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(final @NotNull Side side, final int meta) {
-        return this.texCoords[(meta >> 4) & DyeColor.MASK_COLOR];
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPumice.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPumice.java
deleted file mode 100644
index 0bb7319b8..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelPumice.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.LightmapHelper;
-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.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.Side;
-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.primitives.AABBd;
-
-public class BlockModelPumice<T extends BlockLogic> extends BlockModelStandard<T> {
-    private boolean lavaFlag = false;
-
-    public BlockModelPumice(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        this.lavaFlag = true;
-        boolean rendered = super.render(tessellator, worldSource, tilePos);
-
-        this.lavaFlag = false;
-        rendered |= super.render(tessellator, worldSource, tilePos);
-        return rendered;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-
-        int color = getStandaloneTintColor(metadata);
-        this.lavaFlag = true;
-        final double depthFixOffset = 0.001d;
-        AABBd bounds = new AABBd(depthFixOffset, depthFixOffset, depthFixOffset, 1 - depthFixOffset, 1 - depthFixOffset, 1 - depthFixOffset);
-        renderBlockWithBounds(tessellator, bounds, metadata, LightmapHelper.getLightmapCoord(15, 15), color);
-
-        this.lavaFlag = false;
-        bounds.setMin(0, 0, 0).setMax(1, 1, 1);
-        renderBlockWithBounds(tessellator, bounds, metadata, lightmapCoord, color);
-
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (this.lavaFlag) return TextureRegistry.getTexture("minecraft:block/lava_still");
-        return super.getBlockTextureFromSideAndMetadata(side, data);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRepeater.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRepeater.java
deleted file mode 100644
index abb449b02..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRepeater.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.LightmapHelper;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicRepeater;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelRepeater extends BlockModelStandard<BlockLogicRepeater> {
-    private static final @NotNull BlockModelTorch<?> modelTorchActive = (BlockModelTorch<?>) BlockModelDispatcher.getInstance().getDispatch(Blocks.TORCH_REDSTONE_ACTIVE);
-    private static final @NotNull BlockModelTorch<?> modelTorchIdle = (BlockModelTorch<?>) BlockModelDispatcher.getInstance().getDispatch(Blocks.TORCH_REDSTONE_IDLE);
-
-    public BlockModelRepeater(Block<BlockLogicRepeater> block) {
-        super(block);
-    }
-
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        int meta = worldSource.getBlockData(tilePos);
-        int direction = meta & BlockLogicRepeater.MASK_DIRECTION;
-
-        switch (direction) {
-            case BlockLogicRepeater.DIRECTION_SOUTH:
-                renderBlocks.uvRotateTop = 0;
-                break;
-
-            case BlockLogicRepeater.DIRECTION_NORTH:
-                renderBlocks.uvRotateTop = 3;
-                break;
-
-            case BlockLogicRepeater.DIRECTION_EAST:
-                renderBlocks.uvRotateTop = 2;
-                break;
-
-            case BlockLogicRepeater.DIRECTION_WEST:
-                renderBlocks.uvRotateTop = 1;
-                break;
-        }
-
-        int j1 = (meta & 0xc) >> 2;
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, this.block.getBoundsFromState(worldSource, tilePos), tilePos);
-        renderBlocks.resetRenderBlocks();
-        float brightness = 1.0f;
-        int lmc = this.block.getLightmapCoord(worldSource, tilePos);
-        if (this.block.emission > 0) {
-            lmc = LightmapHelper.setBlocklightValue(lmc, 15);
-        }
-        tessellator.setLightmapCoord1i(lmc);
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-        double d = -0.1875D;
-        double d1 = 0.0D;
-        double d2 = 0.0D;
-        double d3 = 0.0D;
-        double d4 = 0.0D;
-        switch (direction) {
-            case BlockLogicRepeater.DIRECTION_SOUTH:
-                d4 = -0.3125D;
-                d2 = BlockLogicRepeater.torchPosOffset[j1];
-                break;
-
-            case BlockLogicRepeater.DIRECTION_NORTH:
-                d4 = 0.3125D;
-                d2 = -BlockLogicRepeater.torchPosOffset[j1];
-                break;
-
-            case BlockLogicRepeater.DIRECTION_EAST:
-                d3 = -0.3125D;
-                d1 = BlockLogicRepeater.torchPosOffset[j1];
-                break;
-
-            case BlockLogicRepeater.DIRECTION_WEST:
-                d3 = 0.3125D;
-                d1 = -BlockLogicRepeater.torchPosOffset[j1];
-                break;
-        }
-        BlockModelTorch<?> modelTorch = this.block.getLogic().isRepeaterPowered ? modelTorchActive : modelTorchIdle;
-        modelTorch.renderTorchAtAngle(tessellator, (double) tilePos.x() + d1, (double) tilePos.y() + d, (double) tilePos.z() + d2, 0.0D, 0.0D);
-        modelTorch.renderTorchAtAngle(tessellator, (double) tilePos.x() + d3, (double) tilePos.y() + d, (double) tilePos.z() + d4, 0.0D, 0.0D);
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-    @Override
-    public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        return true;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSeat.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSeat.java
deleted file mode 100644
index 3e12d0fe1..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSeat.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBd;
-
-public class BlockModelSeat<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelSeat(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        AABBd bounds = new AABBd(this.block.getBoundsFromState(worldSource, tilePos));
-
-        renderBlocks.setRenderSide(Side.BOTTOM, false); // Set bottom face to not render
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos); // Render seat
-
-        // Set only the bottom face to render
-        renderBlocks.renderBitMask = 0b111111;
-        renderBlocks.setRenderSide(Side.BOTTOM, true);
-        bounds.minY += 0.1875D; // Shift the bottom face up
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos); // Render Seat
-
-        // Reset block values
-        renderBlocks.renderBitMask = 0;
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSignPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSignPainted.java
index a6687f240..8b9164852 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSignPainted.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSignPainted.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.block.model;
 
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPlanksPainted;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicSignPainted;
@@ -14,6 +15,6 @@ public class BlockModelSignPainted<T extends BlockLogicSignPainted> extends Bloc
 
     @Override
     public @Nullable IconCoordinate getParticleTexture(@NotNull final Side side, final int meta) {
-        return BlockModelPlanksPainted.texCoords[this.block.getLogic().fromMetadata(meta).blockMeta];
+        return BlockModelGenericPlanksPainted.texCoords[this.block.getLogic().fromMetadata(meta).blockMeta];
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlab.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlab.java
index e78c9b378..191cea573 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlab.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlab.java
@@ -10,24 +10,22 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class BlockModelSlab<T extends BlockLogicSlab> extends BlockModelStandard<T> {
-    protected BlockModelStandard<T> parentModel;
+    protected BlockModel<?> parentModel;
 
     public BlockModelSlab(Block<T> block) {
         super(block);
-        this.parentModel = (BlockModelStandard<T>) BlockModelDispatcher.getInstance().getDispatch(this.block.getLogic().modelBlock);
-        this.blockTextures.copy(this.parentModel.blockTextures);
-        this.retroBlockTextures.copy(this.parentModel.retroBlockTextures);
+        this.parentModel = BlockModelDispatcher.getInstance().getDispatch(this.block.getLogic().modelBlock);
         withCustomItemBounds(0, 0, 0, 1, 0.5d, 1);
     }
 
     @Override
     public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        return this.parentModel.getBlockTextureFromSideAndMetadata(side, this.block.getLogic().modelBlockMetadata);
+        return this.parentModel.getParticleTexture(side, this.block.getLogic().modelBlockMetadata);
     }
 
     @Override
     public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        return this.parentModel.getBlockTextureFromSideAndMetadata(side, this.block.getLogic().modelBlockMetadata);
+        return this.parentModel.getParticleTexture(side, this.block.getLogic().modelBlockMetadata);
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlabMarble.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlabMarble.java
deleted file mode 100644
index 031d08560..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlabMarble.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicSlab;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelSlabMarble<T extends BlockLogicSlab> extends BlockModelSlab<T> {
-    protected IconCoordinate slabSide = TextureRegistry.getTexture("minecraft:block/carved_marble");
-
-    public BlockModelSlabMarble(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        return getBlockTextureFromSideAndMetadata(side, source.getBlockData(tilePos));
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (data != 1 && (side.getAxis() != Axis.Y)) {
-            return this.slabSide;
-        }
-        return super.getBlockTextureFromSideAndMetadata(side, data);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlabPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlabPainted.java
deleted file mode 100644
index 4a80401dd..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSlabPainted.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicSlab;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelSlabPainted<T extends BlockLogicSlab> extends BlockModelSlab<T> {
-    public BlockModelSlabPainted(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int meta) {
-        meta = meta >> 4;
-        return BlockModelPlanksPainted.texCoords[meta & 0x0F];
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        return getBlockTextureFromSideAndMetadata(side, source.getBlockData(tilePos));
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSpikes.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSpikes.java
deleted file mode 100644
index 6071b8925..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelSpikes.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.BlockLogicSpikes;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBd;
-
-public class BlockModelSpikes<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelSpikes(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        int metaData = worldSource.getBlockData(tilePos);
-        IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.EAST, metaData);
-        if (renderBlocks.overrideBlockTexture != null) {
-            texture = renderBlocks.overrideBlockTexture;
-        }
-
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, new AABBd(0.0F, 0.0F, 0.0F, 1.0F, 0.1875F, 1.0F), tilePos);
-
-        if (BlockLogicSpikes.isSpikesUp(metaData)) {
-            tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-            double uMin = texture.getIconUMin();
-            double uMax = texture.getIconUMax();
-            double vMin = texture.getIconVMin();
-            double vMax = texture.getIconVMax();
-
-            final int x = tilePos.x();
-            final int y = tilePos.y();
-            final int z = tilePos.z();
-
-            double d7 = (x + 0.5D) - 0.25D;
-            double d8 = x + 0.5D + 0.25D;
-            double d9 = (z + 0.5D) - 0.5D;
-            double d10 = z + 0.5D + 0.5D;
-            double mid = 0.25f;
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 1.0D, d9, uMin, vMin);
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 0.0D, d9, uMin, vMax);
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 0.0D, d10, uMax, vMax);
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 1.0D, d10, uMax, vMin);
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 1.0D, d10, uMin, vMin);
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 0.0D, d10, uMin, vMax);
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 0.0D, d9, uMax, vMax);
-            tessellator.addVertexWithUV(d7 - 0.0625, y + 1.0D, d9, uMax, vMin);
-
-            tessellator.addVertexWithUV(d7 + mid, y + 1.0D, d9, uMin, vMin);
-            tessellator.addVertexWithUV(d7 + mid, y + 0.0D, d9, uMin, vMax);
-            tessellator.addVertexWithUV(d7 + mid, y + 0.0D, d10, uMax, vMax);
-            tessellator.addVertexWithUV(d7 + mid, y + 1.0D, d10, uMax, vMin);
-            tessellator.addVertexWithUV(d7 + mid, y + 1.0D, d10, uMin, vMin);
-            tessellator.addVertexWithUV(d7 + mid, y + 0.0D, d10, uMin, vMax);
-            tessellator.addVertexWithUV(d7 + mid, y + 0.0D, d9, uMax, vMax);
-            tessellator.addVertexWithUV(d7 + mid, y + 1.0D, d9, uMax, vMin);
-
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 1.0D, d10, uMin, vMin);
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 0.0D, d10, uMin, vMax);
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 0.0D, d9, uMax, vMax);
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 1.0D, d9, uMax, vMin);
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 1.0D, d9, uMin, vMin);
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 0.0D, d9, uMin, vMax);
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 0.0D, d10, uMax, vMax);
-            tessellator.addVertexWithUV(d8 + 0.0625, y + 1.0D, d10, uMax, vMin);
-
-            d7 = (x + 0.5D) - 0.5D;
-            d8 = x + 0.5D + 0.5D;
-            d9 = (z + 0.5D) - 0.25D;
-            d10 = z + 0.5D + 0.25D;
-            tessellator.addVertexWithUV(d7, y + 1.0D, d9 - 0.0625, uMin, vMin);
-            tessellator.addVertexWithUV(d7, y + 0.0D, d9 - 0.0625, uMin, vMax);
-            tessellator.addVertexWithUV(d8, y + 0.0D, d9 - 0.0625, uMax, vMax);
-            tessellator.addVertexWithUV(d8, y + 1.0D, d9 - 0.0625, uMax, vMin);
-            tessellator.addVertexWithUV(d8, y + 1.0D, d9 - 0.0625, uMin, vMin);
-            tessellator.addVertexWithUV(d8, y + 0.0D, d9 - 0.0625, uMin, vMax);
-            tessellator.addVertexWithUV(d7, y + 0.0D, d9 - 0.0625, uMax, vMax);
-            tessellator.addVertexWithUV(d7, y + 1.0D, d9 - 0.0625, uMax, vMin);
-
-            tessellator.addVertexWithUV(d7, y + 1.0D, d9 + mid, uMin, vMin);
-            tessellator.addVertexWithUV(d7, y + 0.0D, d9 + mid, uMin, vMax);
-            tessellator.addVertexWithUV(d8, y + 0.0D, d9 + mid, uMax, vMax);
-            tessellator.addVertexWithUV(d8, y + 1.0D, d9 + mid, uMax, vMin);
-            tessellator.addVertexWithUV(d8, y + 1.0D, d9 + mid, uMin, vMin);
-            tessellator.addVertexWithUV(d8, y + 0.0D, d9 + mid, uMin, vMax);
-            tessellator.addVertexWithUV(d7, y + 0.0D, d9 + mid, uMax, vMax);
-            tessellator.addVertexWithUV(d7, y + 1.0D, d9 + mid, uMax, vMin);
-
-            tessellator.addVertexWithUV(d8, y + 1.0D, d10 + 0.0625, uMin, vMin);
-            tessellator.addVertexWithUV(d8, y + 0.0D, d10 + 0.0625, uMin, vMax);
-            tessellator.addVertexWithUV(d7, y + 0.0D, d10 + 0.0625, uMax, vMax);
-            tessellator.addVertexWithUV(d7, y + 1.0D, d10 + 0.0625, uMax, vMin);
-            tessellator.addVertexWithUV(d7, y + 1.0D, d10 + 0.0625, uMin, vMin);
-            tessellator.addVertexWithUV(d7, y + 0.0D, d10 + 0.0625, uMin, vMax);
-            tessellator.addVertexWithUV(d8, y + 0.0D, d10 + 0.0625, uMax, vMax);
-            tessellator.addVertexWithUV(d8, y + 1.0D, d10 + 0.0625, uMax, vMin);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java
index 4ac11a6d5..cbee89718 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStairs.java
@@ -17,13 +17,11 @@ public class BlockModelStairs<T extends BlockLogicStairs> extends BlockModelStan
     protected static final DisplayPos STAIRS_GUI = new DisplayPos(0, 0, 0, 30, 135, 0, 0.625f, 0.625f, 0.625f);
     protected static final DisplayPos STAIRS_HEAD = new DisplayPos(0, 0, 0, 0, -90, 0, 1f, 1f, 1f);
     protected static final DisplayPos STAIRS_THIRD_PERSON_LEFT_HAND = new DisplayPos(0, 2.5f / 16f, 0, 75, -135, 0, 0.375f, 0.375f, 0.375f);
-    protected BlockModelStandard<T> parentModel;
+    protected BlockModel<?> parentModel;
 
     public BlockModelStairs(Block<T> block) {
         super(block);
-        this.parentModel = (BlockModelStandard<T>) BlockModelDispatcher.getInstance().getDispatch(this.block.getLogic().modelBlock);
-        this.blockTextures.copy(this.parentModel.blockTextures);
-        this.retroBlockTextures.copy(this.parentModel.retroBlockTextures);
+        this.parentModel = BlockModelDispatcher.getInstance().getDispatch(this.block.getLogic().modelBlock);
 
         setDisplayPos(DisplayPos.GUI, STAIRS_GUI);
         setDisplayPos(DisplayPos.HEAD, STAIRS_HEAD);
@@ -101,12 +99,12 @@ public class BlockModelStairs<T extends BlockLogicStairs> extends BlockModelStan
 
     @Override
     public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        return this.parentModel.getBlockTextureFromSideAndMetadata(side, data);
+        return this.parentModel.getParticleTexture(side, data);
     }
 
     @Override
     public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        return this.parentModel.getBlockTexture(source, tilePos, side);
+        return this.parentModel.getParticleTexture(side, source.getBlockData(tilePos));
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStairsPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStairsPainted.java
deleted file mode 100644
index 5127fb1a2..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStairsPainted.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicStairs;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelStairsPainted<T extends BlockLogicStairs> extends BlockModelStairs<T> {
-    public BlockModelStairsPainted(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int meta) {
-        meta = meta >> 4;
-        return BlockModelPlanksPainted.texCoords[meta & 0x0F];
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTexture(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
-        return getBlockTextureFromSideAndMetadata(side, source.getBlockData(tilePos));
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java
index 6bccc7236..adae8ffdd 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStandard.java
@@ -36,11 +36,7 @@ public class BlockModelStandard<T extends BlockLogic> extends BlockModel<T> {
     public @Nullable AABBdc itemRenderBounds = null;
     public int renderLayer = 0;
 
-    public static final int BLOCK_TEXTURES = 0;
-    public static final int RETRO_BLOCK_TEXTURES = 2;
-
     protected final TextureLayer blockTextures = new TextureLayer().setAll(BLOCK_TEXTURE_UNASSIGNED);
-    protected final TextureLayer retroBlockTextures = new TextureLayer();
 
     protected @NotNull Map<@NotNull String, @NotNull DisplayPos> displayPosMap = new HashMap<>();
 
@@ -64,8 +60,8 @@ public class BlockModelStandard<T extends BlockLogic> extends BlockModel<T> {
     }
 
     @Override
-    public boolean renderWithOverrideTexture(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, IconCoordinate textureIndex) {
-        renderBlocks.overrideBlockTexture = textureIndex;
+    public boolean renderWithOverrideTexture(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, IconCoordinate overrideTexture) {
+        renderBlocks.overrideBlockTexture = overrideTexture;
         boolean result = render(tessellator, worldSource, tilePos);
         renderBlocks.overrideBlockTexture = null;
         return result;
@@ -142,9 +138,6 @@ public class BlockModelStandard<T extends BlockLogic> extends BlockModel<T> {
     }
 
     public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (this.retroBlockTextures.hasTexture && isRetro()) {
-            return this.retroBlockTextures.get(side);
-        }
         return this.blockTextures.get(side);
     }
 
@@ -221,51 +214,23 @@ public class BlockModelStandard<T extends BlockLogic> extends BlockModel<T> {
         return this;
     }
 
-    public BlockModelStandard<T> setTex(int layer, @Nullable IconCoordinate coordinate, Side... sides) {
-        switch (layer) {
-            case BLOCK_TEXTURES:
-                this.blockTextures.set(coordinate, sides);
-                break;
-            case RETRO_BLOCK_TEXTURES:
-                this.retroBlockTextures.set(coordinate, sides);
-                break;
-        }
+    public BlockModelStandard<T> setTex(@Nullable IconCoordinate coordinate, Side... sides) {
+        this.blockTextures.set(coordinate, sides);
         return this;
     }
 
-    public BlockModelStandard<T> setTex(int layer, @Nullable String texture, Side... sides) {
-        switch (layer) {
-            case BLOCK_TEXTURES:
-                this.blockTextures.set(texture, sides);
-                break;
-            case RETRO_BLOCK_TEXTURES:
-                this.retroBlockTextures.set(texture, sides);
-                break;
-        }
+    public BlockModelStandard<T> setTex(@Nullable String texture, Side... sides) {
+        this.blockTextures.set(texture, sides);
         return this;
     }
 
-    public BlockModelStandard<T> setAllTextures(int layer, @Nullable IconCoordinate coordinate) {
-        switch (layer) {
-            case BLOCK_TEXTURES:
-                this.blockTextures.setAll(coordinate);
-                break;
-            case RETRO_BLOCK_TEXTURES:
-                this.retroBlockTextures.setAll(coordinate);
-                break;
-        }
+    public BlockModelStandard<T> setAllTextures(@Nullable IconCoordinate coordinate) {
+        this.blockTextures.setAll(coordinate);
         return this;
     }
 
-    public BlockModelStandard<T> setAllTextures(int layer, @Nullable String texture) {
-        switch (layer) {
-            case BLOCK_TEXTURES:
-                this.blockTextures.setAll(texture);
-                break;
-            case RETRO_BLOCK_TEXTURES:
-                this.retroBlockTextures.setAll(texture);
-                break;
-        }
+    public BlockModelStandard<T> setAllTextures(@Nullable String texture) {
+        this.blockTextures.setAll(texture);
         return this;
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStoneMossy.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStoneMossy.java
deleted file mode 100644
index 593d0c117..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelStoneMossy.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.client.render.block.color.BlockColorDispatcher;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.joml.primitives.AABBdc;
-
-public class BlockModelStoneMossy<T extends BlockLogic> extends BlockModelStandard<T> {
-    protected IconCoordinate mossOverlay;
-
-    public BlockModelStoneMossy(Block<T> block) {
-        super(block);
-        this.mossOverlay = TextureRegistry.getTexture("minecraft:block/moss_overlay");
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        AABBdc bounds = this.block.getBoundsFromState(worldSource, tilePos);
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos, 1.0f, 1.0f, 1.0f);
-        renderBlocks.overrideBlockTexture = this.mossOverlay;
-        renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-        renderBlocks.overrideBlockTexture = null;
-        return true;
-    }
-
-    @Override
-    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
-        renderBlocks.useInventoryTint = false;
-        super.renderStandalone(tessellator, metadata, lightmapCoord);
-        renderBlocks.useInventoryTint = true;
-
-        int color = BlockColorDispatcher.getInstance().getDispatch(this.block).getFallbackColor(metadata, 0);
-
-        AABBdc bounds = this.block.getBounds();
-        IconCoordinate mossCoord = this.mossOverlay;
-
-        tessellator.offsetTranslation(-0.5, -0.5, -0.5);
-        tessellator.startDrawingQuads();
-        tessellator.setColor1i(color);
-        tessellator.setNormal(0.0F, -1F, 0.0F);
-        renderBlocks.renderBottomFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, mossCoord);
-
-        tessellator.setNormal(0.0F, 1.0F, 0.0F);
-        renderBlocks.renderTopFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, mossCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, -1F);
-        renderBlocks.renderNorthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, mossCoord);
-
-        tessellator.setNormal(0.0F, 0.0F, 1.0F);
-        renderBlocks.renderSouthFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, mossCoord);
-
-        tessellator.setNormal(-1F, 0.0F, 0.0F);
-        renderBlocks.renderWestFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, mossCoord);
-
-        tessellator.setNormal(1.0F, 0.0F, 0.0F);
-        renderBlocks.renderEastFace(tessellator, bounds, 0.0D, 0.0D, 0.0D, mossCoord);
-        tessellator.draw();
-        tessellator.offsetTranslation(0.5, 0.5, 0.5);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTorch.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTorch.java
deleted file mode 100644
index c4d0d5302..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTorch.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.BlockLogicTorch;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-
-public class BlockModelTorch<T extends BlockLogic> extends BlockModelStandard<T> {
-    public BlockModelTorch(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        float brightness = 1.0f;
-        tessellator.setLightmapCoord1i(this.block.getLightmapCoord(worldSource, tilePos));
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
-        double d = 0.4;
-        double d1 = 0.5D - d;
-        double d2 = 0.2;
-        int direction = worldSource.getBlockData(tilePos) & BlockLogicTorch.MASK_DIRECTION;
-        switch (direction) {
-            case BlockLogicTorch.SIDE_WEST:
-                renderTorchAtAngle(tessellator, (double) tilePos.x() - d1, (double) tilePos.y() + d2, tilePos.z(), -d, 0.0D);
-                break;
-            case BlockLogicTorch.SIDE_EAST:
-                renderTorchAtAngle(tessellator, (double) tilePos.x() + d1, (double) tilePos.y() + d2, tilePos.z(), d, 0.0D);
-                break;
-            case BlockLogicTorch.SIDE_NORTH:
-                renderTorchAtAngle(tessellator, tilePos.x(), (double) tilePos.y() + d2, (double) tilePos.z() - d1, 0.0D, -d);
-                break;
-            case BlockLogicTorch.SIDE_SOUTH:
-                renderTorchAtAngle(tessellator, tilePos.x(), (double) tilePos.y() + d2, (double) tilePos.z() + d1, 0.0D, d);
-                break;
-            default:
-                renderTorchAtAngle(tessellator, tilePos.x(), tilePos.y(), tilePos.z(), 0.0D, 0.0D);
-                break;
-        }
-        return true;
-    }
-
-    public void renderTorchAtAngle(@NotNull TessellatorGeneral tessellator, double x, double y, double z, double topOffsetX, double topOffsetZ) {
-        IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.BOTTOM, 0);
-        if (renderBlocks.overrideBlockTexture != null) {
-            texture = renderBlocks.overrideBlockTexture;
-        }
-
-        double minU = texture.getIconUMin();
-        double maxU = texture.getIconUMax();
-        double minV = texture.getIconVMin();
-        double maxV = texture.getIconVMax();
-        double topMinU = texture.getSubIconU(0.4375);
-        double topMinV = texture.getSubIconV(0.375);
-        double topMaxU = texture.getSubIconU(0.5625);
-        double topMaxV = texture.getSubIconV(0.5);
-        double bottomMinU = texture.getSubIconU(0.4375);
-        double bottomMinV = texture.getSubIconV(0.875);
-        double bottomMaxU = texture.getSubIconU(0.5625);
-        double bottomMaxV = maxV;
-
-        x += 0.5D;
-        z += 0.5D;
-        double d9 = x - 0.5D;
-        double d10 = x + 0.5D;
-        double d11 = z - 0.5D;
-        double d12 = z + 0.5D;
-        double d13 = 0.0625;
-        double d14 = 0.625;
-        tessellator.addVertexWithUV((x - d13) + topOffsetX, y + 0.0D, z + d13 + topOffsetZ, bottomMinU, bottomMaxV);
-        tessellator.addVertexWithUV((x - d13) + topOffsetX, y + 0.0D, (z - d13) + topOffsetZ, bottomMinU, bottomMinV);
-        tessellator.addVertexWithUV(x + topOffsetX + d13, y + 0.0D, (z - d13) + topOffsetZ, bottomMaxU, bottomMinV);
-        tessellator.addVertexWithUV(x + topOffsetX + d13, y + 0.0D, z + d13 + topOffsetZ, bottomMaxU, bottomMaxV);
-
-        tessellator.addVertexWithUV((x + topOffsetX * (1.0D - d14)) - d13, y + d14, (z + topOffsetZ * (1.0D - d14)) - d13, topMinU, topMinV);
-        tessellator.addVertexWithUV((x + topOffsetX * (1.0D - d14)) - d13, y + d14, z + topOffsetZ * (1.0D - d14) + d13, topMinU, topMaxV);
-        tessellator.addVertexWithUV(x + topOffsetX * (1.0D - d14) + d13, y + d14, z + topOffsetZ * (1.0D - d14) + d13, topMaxU, topMaxV);
-        tessellator.addVertexWithUV(x + topOffsetX * (1.0D - d14) + d13, y + d14, (z + topOffsetZ * (1.0D - d14)) - d13, topMaxU, topMinV);
-        tessellator.addVertexWithUV(x - d13, y + 1.0D, d11, minU, minV);
-        tessellator.addVertexWithUV((x - d13) + topOffsetX, y + 0.0D, d11 + topOffsetZ, minU, maxV);
-        tessellator.addVertexWithUV((x - d13) + topOffsetX, y + 0.0D, d12 + topOffsetZ, maxU, maxV);
-        tessellator.addVertexWithUV(x - d13, y + 1.0D, d12, maxU, minV);
-        tessellator.addVertexWithUV(x + d13, y + 1.0D, d12, minU, minV);
-        tessellator.addVertexWithUV(x + topOffsetX + d13, y + 0.0D, d12 + topOffsetZ, minU, maxV);
-        tessellator.addVertexWithUV(x + topOffsetX + d13, y + 0.0D, d11 + topOffsetZ, maxU, maxV);
-        tessellator.addVertexWithUV(x + d13, y + 1.0D, d11, maxU, minV);
-        tessellator.addVertexWithUV(d9, y + 1.0D, z + d13, minU, minV);
-        tessellator.addVertexWithUV(d9 + topOffsetX, y + 0.0D, z + d13 + topOffsetZ, minU, maxV);
-        tessellator.addVertexWithUV(d10 + topOffsetX, y + 0.0D, z + d13 + topOffsetZ, maxU, maxV);
-        tessellator.addVertexWithUV(d10, y + 1.0D, z + d13, maxU, minV);
-        tessellator.addVertexWithUV(d10, y + 1.0D, z - d13, minU, minV);
-        tessellator.addVertexWithUV(d10 + topOffsetX, y + 0.0D, (z - d13) + topOffsetZ, minU, maxV);
-        tessellator.addVertexWithUV(d9 + topOffsetX, y + 0.0D, (z - d13) + topOffsetZ, maxU, maxV);
-        tessellator.addVertexWithUV(d9, y + 1.0D, z - d13, maxU, minV);
-    }
-
-    @Override
-    public boolean shouldItemRender3d() {
-        return false;
-    }
-
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTorchRedstone.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTorchRedstone.java
deleted file mode 100644
index c04006598..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTorchRedstone.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-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.Blocks;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelTorchRedstone<T extends BlockLogic> extends BlockModelTorch<T> {
-    private static final BlockModelStandard<?> redstoneWire = (BlockModelStandard<?>) BlockModelDispatcher.getInstance().getDispatch(Blocks.WIRE_REDSTONE);
-
-    public BlockModelTorchRedstone(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        if (side == Side.TOP) {
-            return redstoneWire.getBlockTextureFromSideAndMetadata(side, data);
-        } else {
-            return super.getBlockTextureFromSideAndMetadata(side, data);
-        }
-    }
-
-    @Override
-    public @Nullable IconCoordinate getParticleTexture(@NotNull Side side, int meta) {
-        return this.blockTextures.get(Side.NORTH);
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoorPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoorPainted.java
deleted file mode 100644
index 4999bd1c5..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelTrapDoorPainted.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.block.BlockLogicTrapDoor;
-import net.minecraft.core.util.helper.Axis;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.util.helper.Sides;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelTrapDoorPainted<T extends BlockLogic> extends BlockModelTrapDoor<T> {
-    public static final IconCoordinate[] topTextures = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-    public static final IconCoordinate[] sideTextures = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-
-    static {
-        for (DyeColor c : DyeColor.blockOrderedColors()) {
-            topTextures[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/trapdoor/planks_" + c.colorID + "/top");
-            sideTextures[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/trapdoor/planks_" + c.colorID + "/side");
-        }
-    }
-
-    public BlockModelTrapDoorPainted(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        int color = (data >> 4) & DyeColor.MASK_COLOR;
-        int orientation = data & 3;
-        if (BlockLogicTrapDoor.isTrapdoorOpen(data)) {
-            int index = Sides.orientationLookUpTrapdoorOpen[6 * orientation + side.getId()];
-            if (index < 2) return topTextures[color];
-            return sideTextures[color];
-        } else {
-            if (side.getAxis() == Axis.Y) {
-                return topTextures[color];
-            } else {
-                return sideTextures[color];
-            }
-        }
-
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java
index 3f1d2099f..a6102efdf 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java
@@ -22,7 +22,7 @@ public class BlockModelWireRedstone<T extends BlockLogic> extends BlockModelStan
 
     public BlockModelWireRedstone(Block<T> block) {
         super(block);
-        setAllTextures(BLOCK_TEXTURES, "minecraft:block/wire_redstone_cross");
+        setAllTextures("minecraft:block/wire_redstone_cross");
     }
 
     @Override
@@ -33,14 +33,6 @@ public class BlockModelWireRedstone<T extends BlockLogic> extends BlockModelStan
         if (renderBlocks.overrideBlockTexture != null) {
             cross = renderBlocks.overrideBlockTexture;
         }
-        float brightness = 1.0f;
-//        int lmc = block.getLightmapCoord(worldSource, tilePos);
-//        if (Blocks.lightEmission[block.id] > 0) {
-//            lmc = LightmapHelper.setBlocklightValue(lmc, 15);
-//        }
-        int lmc = LightmapHelper.getLightmapCoord(worldSource.getSavedLightValue(LightLayer.Sky, tilePos), Math.max(worldSource.getSavedLightValue(LightLayer.Block, tilePos), meta & 0xF));
-        tessellator.setLightmapCoord1i(lmc);
-        tessellator.setColorOpaque3f(brightness, brightness, brightness);
 
         Color color = Colors.allRedstoneColors[meta & 0xF];
         float red = color.getRed() / 255.0f;
@@ -49,7 +41,9 @@ public class BlockModelWireRedstone<T extends BlockLogic> extends BlockModelStan
 
         TilePos queryPos = new TilePos();
 
-        tessellator.setColorOpaque3f(brightness * red, brightness * green, brightness * blue);
+        int lmc = LightmapHelper.getLightmapCoord(worldSource.getSavedLightValue(LightLayer.Sky, tilePos), Math.max(worldSource.getSavedLightValue(LightLayer.Block, tilePos), meta & 0xF));
+        tessellator.setLightmapCoord1i(lmc);
+        tessellator.setColorOpaque3f(red, green, blue);
         boolean west = BlockLogicWireRedstone.shouldConnectTo(worldSource, tilePos.west(queryPos), Side.WEST) || !worldSource.isBlockNormalCube(tilePos.west(queryPos)) && BlockLogicWireRedstone.shouldConnectToDiagonal(worldSource, tilePos.add(-1, -1, 0, queryPos), Side.NONE, Side.BOTTOM);
         boolean east = BlockLogicWireRedstone.shouldConnectTo(worldSource, tilePos.east(queryPos), Side.EAST) || !worldSource.isBlockNormalCube(tilePos.east(queryPos)) && BlockLogicWireRedstone.shouldConnectToDiagonal(worldSource, tilePos.add(1, -1, 0, queryPos), Side.NONE, Side.BOTTOM);
         boolean north = BlockLogicWireRedstone.shouldConnectTo(worldSource, tilePos.north(queryPos), Side.NORTH) || !worldSource.isBlockNormalCube(tilePos.north(queryPos)) && BlockLogicWireRedstone.shouldConnectToDiagonal(worldSource, tilePos.add(0, -1, -1, queryPos), Side.NONE, Side.BOTTOM);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWool.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWool.java
deleted file mode 100644
index 51517ce2f..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWool.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.minecraft.client.render.block.model;
-
-import net.minecraft.client.render.texture.stitcher.IconCoordinate;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogic;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.Side;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BlockModelWool<T extends BlockLogic> extends BlockModelStandard<T> {
-    public static final IconCoordinate[] texCoords = new IconCoordinate[DyeColor.COLOR_AMOUNT];
-
-    static {
-        for (DyeColor c : DyeColor.blockOrderedColors()) {
-            texCoords[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/wool/" + c.colorID);
-        }
-    }
-
-    public BlockModelWool(Block<T> block) {
-        super(block);
-    }
-
-    @Override
-    public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
-        return texCoords[data & DyeColor.MASK_COLOR];
-    }
-}
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
new file mode 100644
index 000000000..b5edb73fa
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGeneric.java
@@ -0,0 +1,118 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
+import net.minecraft.client.render.block.model.BlockModel;
+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.util.helper.Direction;
+import net.minecraft.core.util.helper.Side;
+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.jetbrains.annotations.Nullable;
+import org.useless.dragonfly.DisplayPos;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGeneric<T extends BlockLogic> extends BlockModel<T> {
+    public final @NotNull StaticBlockModel staticModel;
+    public boolean render3d = true;
+    public boolean forceCullSelf = false;
+
+    public BlockModelGeneric(@NotNull final Block<T> block, @NotNull final StaticBlockModel staticModel) {
+        super(block);
+        this.staticModel = staticModel;
+    }
+
+    public BlockModelGeneric(@NotNull final Block<T> block, @NotNull final BlockModelData staticModel) {
+        super(block);
+        this.staticModel = staticModel.asModel();
+    }
+
+    public @NotNull BlockModelGeneric<T> render3D(boolean flag) {
+        this.render3d = flag;
+        return this;
+    }
+
+    public @NotNull BlockModelGeneric<T> forceCullSelf(boolean flag) {
+        this.forceCullSelf = flag;
+        return this;
+    }
+
+    @Override
+    public final boolean renderNoCulling(final @NotNull TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos) {
+        return renderAttached(tessellator, worldSource, tilePos, false, null);
+    }
+
+    @Override
+    public final boolean render(final @NotNull TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos) {
+        return renderAttached(tessellator, worldSource, tilePos, true, null);
+    }
+
+    @Override
+    public final boolean renderWithOverrideTexture(final @NotNull TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos, final IconCoordinate overrideTexture) {
+        return renderAttached(tessellator, worldSource, tilePos, true, overrideTexture);
+    }
+
+    public boolean renderAttached(final @NotNull TessellatorGeneral tessellator, @NotNull final WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, final @Nullable IconCoordinate overrideTexture) {
+        return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+
+    @Override
+    public void renderStandalone(final @NotNull TessellatorGeneral tessellator, final int metadata, final int lightmapCoord) {
+        getModelFromData(metadata).renderStandalone(this, tessellator, 0, 0, 0, metadata, lightmapCoord, BlockColorDispatcher.getInstance().getDispatch(this.block));
+    }
+
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        return getModelFromData(source.getBlockData(tilePosc));
+    }
+
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.staticModel;
+    }
+
+    @Override
+    public boolean shouldItemRender3d() {
+        return this.render3d;
+    }
+
+    @Override
+    public @NotNull DisplayPos getItemDisplayPos(final @NotNull String id) {
+        return this.staticModel.getItemDisplayPos(id);
+    }
+
+    @Override
+    public int renderLayer() {
+        return this.staticModel.renderLayer();
+    }
+
+    public boolean cullSide(@NotNull WorldSource worldSource, @NotNull TilePosc blockPos, @Nullable Direction direction) {
+        if (direction != null) {
+            TilePos shifted = blockPos.add(direction, new TilePos());
+            if (this.forceCullSelf) {
+                return worldSource.getBlock(shifted) == this.block || worldSource.isBlockOpaqueCube(shifted);
+            } else {
+                return worldSource.isBlockOpaqueCube(shifted);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public @Nullable IconCoordinate getParticleTexture(final @NotNull Side side, final int meta) {
+        return getModelFromData(meta).getParticle(side);
+    }
+
+    @Override
+    public @Nullable IconCoordinate getOverlayTexture(final int meta) {
+        return getModelFromData(meta).getOverlay();
+    }
+
+    @Override
+    public int particleColorIndex(final @NotNull WorldSource worldSource, final @NotNull TilePosc tilePos, @NotNull final Side side, final int meta) {
+        return getModel(worldSource, tilePos).particleColorIndex(side);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericActivator.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericActivator.java
new file mode 100644
index 000000000..6d99429cd
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericActivator.java
@@ -0,0 +1,25 @@
+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.BlockLogicActivator;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericActivator<T extends BlockLogic> extends BlockModelGenericVeryRotatable<T> {
+    public final @NotNull StaticBlockModel active;
+    public BlockModelGenericActivator(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/activator_idle"));
+        this.active = BlockModelDispatcher.loadDataModel("minecraft:block/activator_active").asModel();
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        if ((data & BlockLogicActivator.MASK_POWERED) != 0) {
+            return this.active;
+        } else {
+            return super.getModelFromData(data);
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericAxis.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericAxis.java
new file mode 100644
index 000000000..3f96ef175
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericAxis.java
@@ -0,0 +1,41 @@
+package net.minecraft.client.render.block.model.generic;
+
+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.BlockLogicAxisAligned;
+import net.minecraft.core.util.helper.Axis;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericAxis<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public BlockModelGenericAxis(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+    }
+
+    public BlockModelGenericAxis(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        Axis axis = BlockLogicAxisAligned.metaToAxis(worldSource.getBlockData(tilePos));
+        switch (axis) {
+            case X -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 1, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case Y -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case Z -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+        }
+        return false;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBasket.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBasket.java
new file mode 100644
index 000000000..1ca363756
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBasket.java
@@ -0,0 +1,30 @@
+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.BlockLogicBasket;
+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 BlockModelGenericBasket<T extends BlockLogicBasket> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel fill;
+    public BlockModelGenericBasket(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/basket"));
+        this.fill = BlockModelDispatcher.loadDataModel("minecraft:block/basket_fill").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean rendered = super.renderAttached(tessellator, worldSource, tilePos, cullFaces, overrideTexture);
+        final int height = this.block.getLogic().getFillLevel(worldSource, tilePos);
+        if (height > 0) {
+            rendered |= this.fill.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, (height)/16f, 0, false, cullFaces, overrideTexture);
+        }
+        return rendered;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBed.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBed.java
new file mode 100644
index 000000000..b97790131
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBed.java
@@ -0,0 +1,37 @@
+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.BlockLogicBed;
+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 BlockModelGenericBed<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel head;
+    public BlockModelGenericBed(Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/bed/foot"));
+        this.head = BlockModelDispatcher.loadDataModel("minecraft:block/bed/head").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int direction = BlockLogicBed.getDirection(worldSource.getBlockData(tilePos));
+        return switch (direction) {
+            case 0 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case 1 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case 2 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        };
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return BlockLogicBed.isBlockHeadOfBed(data) ? this.head : this.staticModel;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBrazier.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBrazier.java
new file mode 100644
index 000000000..b48684d6f
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericBrazier.java
@@ -0,0 +1,36 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.model.BlockModelFire;
+import net.minecraft.client.render.block.model.BlockModelStandard;
+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.Blocks;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericBrazier<T extends BlockLogic> extends BlockModelGeneric<T> {
+    protected BlockModelStandard<?> fireModel = new BlockModelFire<>(Blocks.FIRE, true).setAllTextures("minecraft:block/fire");
+
+    public BlockModelGenericBrazier(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+    }
+
+    public BlockModelGenericBrazier(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean rendered = super.renderAttached(tessellator, worldSource, tilePos, cullFaces, overrideTexture);
+        if (overrideTexture == null) {
+            rendered |= this.fireModel.render(tessellator, worldSource, tilePos);
+        }
+        return rendered;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericButton.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericButton.java
new file mode 100644
index 000000000..892a08f49
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericButton.java
@@ -0,0 +1,42 @@
+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.BlockLogicButton;
+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 BlockModelGenericButton<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel idle;
+    public final @NotNull StaticBlockModel active;
+    public BlockModelGenericButton(@NotNull Block<T> block, @NotNull String basekey) {
+        super(block, BlockModelDispatcher.loadDataModel(basekey + "/inventory"));
+        this.idle = BlockModelDispatcher.loadDataModel(basekey + "/idle").asModel();
+        this.active = BlockModelDispatcher.loadDataModel(basekey + "/active").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int direction = worldSource.getBlockData(tilePos) & BlockLogicButton.MASK_DIRECTION;
+        return switch (direction) {
+            case BlockLogicButton.SIDE_WEST -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 1, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case BlockLogicButton.SIDE_EAST -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 3, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case BlockLogicButton.SIDE_NORTH -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case BlockLogicButton.SIDE_SOUTH -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 2, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case BlockLogicButton.SIDE_TOP -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 2, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        };
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        boolean pressed = (source.getBlockData(tilePosc) & BlockLogicButton.MASK_POWERED) != 0;
+        return pressed ? this.active : this.idle;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericButtonPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericButtonPainted.java
new file mode 100644
index 000000000..3f597f140
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericButtonPainted.java
@@ -0,0 +1,41 @@
+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.BlockLogicButton;
+import net.minecraft.core.util.helper.DyeColor;
+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 BlockModelGenericButtonPainted<T extends BlockLogic> extends BlockModelGenericButton<T> {
+    public final @NotNull StaticBlockModel[] inventory = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] idle = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] active = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericButtonPainted(@NotNull Block<T> block) {
+        super(block, "minecraft:block/button/planks/white");
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.inventory[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/button/planks/" + color.colorID + "/inventory").asModel();
+            this.idle[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/button/planks/" + color.colorID + "/idle").asModel();
+            this.active[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/button/planks/" + color.colorID + "/active").asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        int data = source.getBlockData(tilePosc);
+        int color = (data >> 4) & DyeColor.MASK_COLOR;
+        boolean pressed = (data & BlockLogicButton.MASK_POWERED) != 0;
+        return pressed ? this.active[color] : this.idle[color];
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.inventory[(data >> 4) & DyeColor.MASK_COLOR];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCake.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCake.java
new file mode 100644
index 000000000..be61fa99e
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCake.java
@@ -0,0 +1,23 @@
+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 org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericCake<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel[] models = new StaticBlockModel[6];
+    public BlockModelGenericCake(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/cake/0"));
+        for (int i = 0; i < this.models.length; i++) {
+            this.models[i] = BlockModelDispatcher.loadDataModel("minecraft:block/cake/" + i).asModel();
+        }
+    }
+
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[data % this.models.length];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericChest.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericChest.java
new file mode 100644
index 000000000..6dbfe9e0f
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericChest.java
@@ -0,0 +1,55 @@
+package net.minecraft.client.render.block.model.generic;
+
+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.BlockLogicChest;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericChest<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel left;
+    public final @NotNull StaticBlockModel right;
+
+    public BlockModelGenericChest(@NotNull Block<T> block, @NotNull BlockModelData single, @NotNull BlockModelData left, @NotNull BlockModelData right) {
+        super(block, single);
+        this.left = left.asModel();
+        this.right = right.asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        Direction direction = BlockLogicChest.getDirectionFromMeta(worldSource.getBlockData(tilePos));
+        switch (direction) {
+            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, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        BlockLogicChest.Type type = BlockLogicChest.getTypeFromMeta(source.getBlockData(tilePosc));
+        return switch (type) {
+            case LEFT -> this.left;
+            case RIGHT -> this.right;
+            case SINGLE -> this.staticModel;
+        };
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericChestPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericChestPainted.java
new file mode 100644
index 000000000..377674c03
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericChestPainted.java
@@ -0,0 +1,67 @@
+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.BlockLogicChest;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.util.helper.DyeColor;
+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 BlockModelGenericChestPainted<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel[] single = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] left = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] right = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericChestPainted(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/chest/single/" + DyeColor.WHITE.colorID));
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            this.single[c.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/chest/single/" + c.colorID).asModel();
+            this.left[c.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/chest/left/" + c.colorID).asModel();
+            this.right[c.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/chest/right/" + c.colorID).asModel();
+        }
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        Direction direction = BlockLogicChest.getDirectionFromMeta(worldSource.getBlockData(tilePos));
+        switch (direction) {
+            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, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        int data = source.getBlockData(tilePosc);
+        int color = data >> 4;
+        BlockLogicChest.Type type = BlockLogicChest.getTypeFromMeta(data);
+        return switch (type){
+            case LEFT -> this.left[color];
+            case RIGHT -> this.right[color];
+            case SINGLE -> this.single[color];
+        };
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        int color = data >> 4;
+        return this.single[color];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCropsPumpkin.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCropsPumpkin.java
new file mode 100644
index 000000000..a49d410c1
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCropsPumpkin.java
@@ -0,0 +1,32 @@
+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.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 BlockModelGenericCropsPumpkin<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel[] stages = new StaticBlockModel[4];
+    public BlockModelGenericCropsPumpkin(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/crops_pumpkin/leaf"));
+        for (int i = 0; i < this.stages.length; i++) {
+            this.stages[i] = BlockModelDispatcher.loadDataModel("minecraft:block/crops_pumpkin/stage" + (i + 1)).asModel();
+        }
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean didRender = getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        int data = worldSource.getBlockData(tilePos);
+        if (data >= 1) {
+            this.stages[(data - 1) & 0b11].renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        return didRender;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCropsWheat.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCropsWheat.java
new file mode 100644
index 000000000..ba3b3b66a
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericCropsWheat.java
@@ -0,0 +1,23 @@
+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.BlockLogicCropsWheat;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericCropsWheat<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel[] models = new StaticBlockModel[BlockLogicCropsWheat.MAX_GROWTH_STATE + 1];
+    public BlockModelGenericCropsWheat(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/crops_wheat/stage0"));
+        for (int i = 0; i < this.models.length; i++) {
+            this.models[i] = BlockModelDispatcher.loadDataModel("minecraft:block/crops_wheat/stage" + i).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[data % this.models.length];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericDoor.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericDoor.java
new file mode 100644
index 000000000..a9808ab37
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericDoor.java
@@ -0,0 +1,61 @@
+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.BlockLogicDoor;
+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 BlockModelGenericDoor<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel left;
+    public final @NotNull StaticBlockModel left_open;
+    public final @NotNull StaticBlockModel right;
+    public final @NotNull StaticBlockModel right_open;
+    public BlockModelGenericDoor(@NotNull Block<T> block, @NotNull String basekey, boolean bottom) {
+        super(block, BlockModelDispatcher.loadDataModel(basekey + "/" + (bottom ? "bottom" : "top") + "_left"));
+        String side = (bottom ? "bottom" : "top");
+        this.left = BlockModelDispatcher.loadDataModel("%s/%s_left".formatted(basekey, side)).asModel();
+        this.left_open = BlockModelDispatcher.loadDataModel("%s/%s_left_open".formatted(basekey, side)).asModel();
+        this.right = BlockModelDispatcher.loadDataModel("%s/%s_right".formatted(basekey, side)).asModel();
+        this.right_open = BlockModelDispatcher.loadDataModel("%s/%s_right_open".formatted(basekey, side)).asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int data = worldSource.getBlockData(tilePos);
+        int rotation = data & BlockLogicDoor.MASK_ROTATION;
+        boolean isOpen = (data & BlockLogicDoor.MASK_OPENED) != 0;
+        if (isOpen) {
+            return switch (rotation) {
+                case 0 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+                case 1 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+                case 2 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+                default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            };
+        } else {
+            return switch (rotation) {
+                case 0 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+                case 1 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+                case 2 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+                default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            };
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        boolean isLeft = (data & BlockLogicDoor.MASK_HINGE) != 0;
+        boolean isOpen = (data & BlockLogicDoor.MASK_OPENED) != 0;
+        if (isLeft) {
+            return isOpen ? this.left_open : this.left;
+        } else {
+            return isOpen ? this.right : this.right_open;
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericDoorPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericDoorPainted.java
new file mode 100644
index 000000000..8bb49aab2
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericDoorPainted.java
@@ -0,0 +1,43 @@
+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.BlockLogicDoor;
+import net.minecraft.core.util.helper.DyeColor;
+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 BlockModelGenericDoorPainted<T extends BlockLogic> extends BlockModelGenericDoor<T> {
+    public final @NotNull StaticBlockModel[] left = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] left_open = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] right = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] right_open = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericDoorPainted(@NotNull Block<T> block, boolean bottom) {
+        super(block, "minecraft:block/door/planks/white", bottom);
+        String side = (bottom ? "bottom" : "top");
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.left[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/door/planks/%s/%s_left".formatted(color.colorID, side)).asModel();
+            this.left_open[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/door/planks/%s/%s_left_open".formatted(color.colorID, side)).asModel();
+            this.right[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/door/planks/%s/%s_right".formatted(color.colorID, side)).asModel();
+            this.right_open[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/door/planks/%s/%s_right_open".formatted(color.colorID, side)).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        int color = (data >> 4) & DyeColor.MASK_COLOR;
+        boolean isLeft = (data & BlockLogicDoor.MASK_HINGE) != 0;
+        boolean isOpen = (data & BlockLogicDoor.MASK_OPENED) != 0;
+        if (isLeft) {
+            return isOpen ? this.left_open[color] : this.left[color];
+        } else {
+            return isOpen ? this.right[color] : this.right_open[color];
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFarmland.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFarmland.java
new file mode 100644
index 000000000..2b3617746
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFarmland.java
@@ -0,0 +1,39 @@
+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.BlockLogicFarmland;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericFarmland<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel dry_fertilized;
+    public final @NotNull StaticBlockModel wet;
+    public final @NotNull StaticBlockModel wet_fertilized;
+    public BlockModelGenericFarmland(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/farmland/dry"));
+        this.dry_fertilized = BlockModelDispatcher.loadDataModel("minecraft:block/farmland/dry_fertilized").asModel();
+        this.wet = BlockModelDispatcher.loadDataModel("minecraft:block/farmland/wet").asModel();
+        this.wet_fertilized = BlockModelDispatcher.loadDataModel("minecraft:block/farmland/wet_fertilized").asModel();
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        boolean isWet = BlockLogicFarmland.isWet(data);
+        boolean isFertilized = BlockLogicFarmland.isFertilized(data);
+        if (isWet) {
+            if (isFertilized) {
+                return this.wet_fertilized;
+            } else {
+                return this.wet;
+            }
+        } else {
+            if (isFertilized) {
+                return this.dry_fertilized;
+            } else {
+                return this.staticModel;
+            }
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFence.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFence.java
new file mode 100644
index 000000000..0e1728ea5
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFence.java
@@ -0,0 +1,50 @@
+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.BlockLogicAxisAligned;
+import net.minecraft.core.block.BlockLogicFence;
+import net.minecraft.core.util.helper.Axis;
+import net.minecraft.core.util.helper.Side;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericFence<T extends BlockLogicFence> extends BlockModelGeneric<T> {
+
+    public final @NotNull StaticBlockModel post;
+    public final @NotNull StaticBlockModel side;
+    public BlockModelGenericFence(@NotNull Block<T> block, @NotNull String basekey) {
+        super(block, BlockModelDispatcher.loadDataModel(basekey + "/inventory"));
+        this.post = BlockModelDispatcher.loadDataModel(basekey + "/post").asModel();
+        this.side = BlockModelDispatcher.loadDataModel(basekey + "/side").asModel();
+    }
+
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean north = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.NORTH);
+        boolean south = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.SOUTH);
+        boolean west = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.WEST);
+        boolean east = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.EAST);
+        if (north) {
+            this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        if (west) {
+            this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        }
+        if (south) {
+            this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        }
+        if (east) {
+            this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        }
+        return this.post.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceGate.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceGate.java
new file mode 100644
index 000000000..6e29de151
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceGate.java
@@ -0,0 +1,36 @@
+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.BlockLogicFenceGate;
+import net.minecraft.core.block.BlockLogicLever;
+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 BlockModelGenericFenceGate<T extends BlockLogic> extends BlockModelGeneric<T> {
+
+    public @NotNull StaticBlockModel open;
+    public BlockModelGenericFenceGate(@NotNull Block<T> block, @NotNull String baseKey) {
+        super(block, BlockModelDispatcher.loadDataModel(baseKey + "_closed"));
+        this.open = BlockModelDispatcher.loadDataModel(baseKey + "_open").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int data = worldSource.getBlockData(tilePos);
+        int rotation = data & BlockLogicFenceGate.MASK_DIRECTION;
+        return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, -rotation, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        boolean open = (data & BlockLogicFenceGate.MASK_OPEN) != 0;
+        return open ? this.open : this.staticModel;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceGatePainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceGatePainted.java
new file mode 100644
index 000000000..0d69469eb
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceGatePainted.java
@@ -0,0 +1,34 @@
+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.BlockLogicFenceGate;
+import net.minecraft.core.util.helper.DyeColor;
+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 BlockModelGenericFenceGatePainted<T extends BlockLogic> extends BlockModelGenericFenceGate<T> {
+
+    public @NotNull StaticBlockModel[] open = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public @NotNull StaticBlockModel[] closed = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericFenceGatePainted(@NotNull Block<T> block) {
+        super(block, "minecraft:block/fencegate/white");
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.closed[color.blockMeta] = BlockModelDispatcher.loadDataModel(String.format("minecraft:block/fencegate/%s_closed", color.colorID)).asModel();
+            this.open[color.blockMeta] = BlockModelDispatcher.loadDataModel(String.format("minecraft:block/fencegate/%s_open", color.colorID)).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        int color = (data >> 4) & DyeColor.MASK_COLOR;
+        boolean open = (data & BlockLogicFenceGate.MASK_OPEN) != 0;
+        return open ? this.open[color] : this.closed[color];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFencePainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFencePainted.java
new file mode 100644
index 000000000..4b1bbeb22
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFencePainted.java
@@ -0,0 +1,60 @@
+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.BlockLogicAxisAligned;
+import net.minecraft.core.block.BlockLogicFence;
+import net.minecraft.core.util.helper.Axis;
+import net.minecraft.core.util.helper.DyeColor;
+import net.minecraft.core.util.helper.Side;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericFencePainted<T extends BlockLogicFence> extends BlockModelGenericFence<T> {
+    public final @NotNull StaticBlockModel[] inventory = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] post = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] side = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericFencePainted(@NotNull Block<T> block) {
+        super(block, "minecraft:block/fence/white");
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.inventory[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/fence/" + color.colorID + "/inventory").asModel();
+            this.post[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/fence/" + color.colorID + "/post").asModel();
+            this.side[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/fence/" + color.colorID + "/side").asModel();
+        }
+    }
+
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int color = worldSource.getBlockData(tilePos) & DyeColor.MASK_COLOR;
+        boolean north = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.NORTH);
+        boolean south = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.SOUTH);
+        boolean west = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.WEST);
+        boolean east = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.EAST);
+        if (north) {
+            this.side[color].renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        if (west) {
+            this.side[color].renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        }
+        if (south) {
+            this.side[color].renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        }
+        if (east) {
+            this.side[color].renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        }
+        return this.post[color].renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.inventory[data & DyeColor.MASK_COLOR];
+    }
+}
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
new file mode 100644
index 000000000..3ad86b001
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFenceThin.java
@@ -0,0 +1,80 @@
+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.BlockLogicFence;
+import net.minecraft.core.block.BlockLogicFenceThin;
+import net.minecraft.core.util.helper.Side;
+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.jetbrains.annotations.Nullable;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericFenceThin<T extends BlockLogicFenceThin> extends BlockModelGeneric<T> {
+
+    public final @NotNull StaticBlockModel post;
+    public final @NotNull StaticBlockModel side;
+    public final @NotNull StaticBlockModel top;
+    public BlockModelGenericFenceThin(@NotNull Block<T> block, @NotNull String basekey) {
+        super(block, BlockModelDispatcher.loadDataModel(basekey + "/inventory"));
+        this.post = BlockModelDispatcher.loadDataModel(basekey + "/post").asModel();
+        this.side = BlockModelDispatcher.loadDataModel(basekey + "/side").asModel();
+        this.top = BlockModelDispatcher.loadDataModel(basekey + "/side_top").asModel();
+    }
+
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean didRender = false;
+
+        TilePos queryPos = new TilePos();
+
+        boolean north = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.NORTH);
+        boolean south = this.block.getLogic().canConnectTo(worldSource, tilePos, Side.SOUTH);
+        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));
+        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);
+        boolean upEast = blockAbove == this.block && this.block.getLogic().canConnectTo(worldSource, tilePos.up(queryPos), Side.EAST);
+
+        if (north) {
+            if (upNorth) {
+                didRender |= this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            } else {
+                didRender |= this.top.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+        }
+        if (west) {
+            if (upWest) {
+                didRender |= this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            } else {
+                didRender |= this.top.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            }
+        }
+        if (south) {
+            if (upSouth) {
+                didRender |= this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            } else {
+                didRender |= this.top.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            }
+        }
+        if (east) {
+            if (upEast) {
+                didRender |= this.side.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            } else {
+                didRender |= this.top.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            }
+        }
+        if (this.block.getLogic().shouldDrawColumn(worldSource, tilePos)) {
+            didRender |= this.post.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        return didRender;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFlowerStackable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFlowerStackable.java
new file mode 100644
index 000000000..aed8ac346
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFlowerStackable.java
@@ -0,0 +1,30 @@
+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.BlockLogicFlowerStackable;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericFlowerStackable<T extends BlockLogicFlowerStackable> extends BlockModelGeneric<T> {
+    private final StaticBlockModel[] MODELS;
+
+    public BlockModelGenericFlowerStackable(@NotNull Block<T> block, @NotNull String baseModel) {
+        super(block, BlockModelDispatcher.loadDataModel(baseModel + 0));
+
+        this.MODELS = new StaticBlockModel[T.MAX_STACK_COUNT + 1];
+        for (int i = 0; i < T.MAX_STACK_COUNT + 1; i++) {
+            this.MODELS[i] = BlockModelDispatcher.loadDataModel(baseModel + i).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        final int stackCount = T.getStackCount(data);
+        if (stackCount > T.MAX_STACK_COUNT) {
+            return this.MODELS[0];
+        }
+
+        return this.MODELS[stackCount];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFullyRotatable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFullyRotatable.java
new file mode 100644
index 000000000..961b5c583
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFullyRotatable.java
@@ -0,0 +1,50 @@
+package net.minecraft.client.render.block.model.generic;
+
+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.BlockLogicFullyRotatable;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericFullyRotatable<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public BlockModelGenericFullyRotatable(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+    }
+
+    public BlockModelGenericFullyRotatable(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        final Direction dir = BlockLogicFullyRotatable.metaToDirection(worldSource.getBlockData(tilePos));
+        switch (dir) {
+            case UP -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case DOWN -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 2, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case NORTH -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, -1, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case SOUTH -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case WEST -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 1, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case EAST -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, -1, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+        }
+        return false;
+    }
+}
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
new file mode 100644
index 000000000..471d6f532
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericFurnace.java
@@ -0,0 +1,36 @@
+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.entity.TileEntityFurnaceBlast;
+import net.minecraft.core.player.inventory.container.Container;
+import net.minecraft.core.world.WorldSource;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericFurnace<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel filled;
+
+    public BlockModelGenericFurnace(@NotNull Block<T> block, @NotNull String baseKey) {
+        super(block, BlockModelDispatcher.loadDataModel(baseKey));
+        this.filled = BlockModelDispatcher.loadDataModel(baseKey + "_filled").asModel();
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        if (source.getTileEntity(tilePosc) instanceof Container container) {
+            boolean hasOutput;
+            if (container instanceof TileEntityFurnaceBlast) {
+                hasOutput = container.getItem(3) != null;
+            } else {
+                hasOutput = container.getItem(2) != null;
+            }
+            if (hasOutput) {
+                return this.filled;
+            }
+        }
+        return super.getModel(source, tilePosc);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericJar.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericJar.java
new file mode 100644
index 000000000..138327f4e
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericJar.java
@@ -0,0 +1,20 @@
+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 org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericJar<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel jarDirt = BlockModelDispatcher.loadDataModel("minecraft:block/jar_dirt").asModel();
+
+    public BlockModelGenericJar(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/jar"));
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return data == 1 ? this.jarDirt : super.getModelFromData(data);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLamp.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLamp.java
new file mode 100644
index 000000000..0f10c01a3
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLamp.java
@@ -0,0 +1,32 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
+import net.minecraft.client.render.block.model.BlockModelDispatcher;
+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.DyeColor;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericLamp<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel @NotNull [] models = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel @NotNull [] activeModels = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericLamp(@NotNull Block<T> block, @NotNull String baseKey, @NotNull String activeKey) {
+        super(block, BlockModelDispatcher.loadDataModel(String.format(baseKey, DyeColor.WHITE.colorID)));
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            this.models[c.blockMeta] = BlockModelDispatcher.loadDataModel(String.format(baseKey, c.colorID)).asModel();
+            this.activeModels[c.blockMeta] = BlockModelDispatcher.loadDataModel(String.format(activeKey, c.colorID)).asModel();
+        }
+    }
+
+    @Override
+    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
+        this.activeModels[metadata & DyeColor.MASK_COLOR].renderStandalone(this, tessellator, 0, 0, 0, metadata, lightmapCoord, BlockColorDispatcher.getInstance().getDispatch(this.block));
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[data & DyeColor.MASK_COLOR];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLantern.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLantern.java
new file mode 100644
index 000000000..9da8f8995
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLantern.java
@@ -0,0 +1,22 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.BlockLogic;
+import net.minecraft.core.block.BlockLogicLanternFirefly;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericLantern<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel hangingModel;
+
+    public BlockModelGenericLantern(@NotNull Block<T> block, @NotNull final BlockModelData floorModel, @NotNull final BlockModelData hangingModel) {
+        super(block, floorModel);
+        this.hangingModel = hangingModel.asModel();
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return ((data & BlockLogicLanternFirefly.MASK_HANGING) != 0) ? this.hangingModel : super.getModelFromData(data);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLayer.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLayer.java
new file mode 100644
index 000000000..6bdc97a76
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLayer.java
@@ -0,0 +1,24 @@
+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.BlockLogicLayerBase;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericLayer<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel[] models = new StaticBlockModel[7];
+    public BlockModelGenericLayer(@NotNull Block<T> block, @NotNull String basekey) {
+        super(block, BlockModelDispatcher.loadDataModel(basekey + "/0"));
+        for (int i = 0; i < this.models.length; i++) {
+            this.models[i] = BlockModelDispatcher.loadDataModel(basekey + "/" + i).asModel();
+        }
+    }
+
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[(data & BlockLogicLayerBase.MASK_HEIGHT) % this.models.length];
+    }
+}
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
new file mode 100644
index 000000000..4d3887740
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java
@@ -0,0 +1,42 @@
+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.util.helper.Direction;
+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.jetbrains.annotations.Nullable;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericLeaves<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public static boolean fancyGraphics;
+    public @NotNull StaticBlockModel fast;
+    public BlockModelGenericLeaves(@NotNull Block<T> block, @NotNull String key) {
+        super(block, BlockModelDispatcher.loadDataModel(key + "_fancy"));
+        this.fast = BlockModelDispatcher.loadDataModel(key + "_fast").asModel();
+    }
+
+    public static void setGraphicsLevel(boolean graphicsLevel) {
+        fancyGraphics = graphicsLevel;
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return fancyGraphics ? super.getModelFromData(data) : this.fast;
+    }
+
+    @Override
+    public boolean cullSide(@NotNull WorldSource worldSource, @NotNull TilePosc blockPos, @Nullable Direction direction) {
+        if (fancyGraphics) {
+            return super.cullSide(worldSource, blockPos, direction);
+        }
+        if (direction != null) {
+            TilePos shifted = blockPos.add(direction, new TilePos());
+            return worldSource.getBlock(shifted) == this.block || worldSource.isBlockOpaqueCube(shifted);
+        }
+        return false;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeavesCacao.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeavesCacao.java
new file mode 100644
index 000000000..2e3af8e99
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeavesCacao.java
@@ -0,0 +1,41 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
+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.BlockLogicLeavesCacao;
+import net.minecraft.core.block.BlockLogicLeavesCherryFlowering;
+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 BlockModelGenericLeavesCacao<T extends BlockLogic> extends BlockModelGenericLeaves<T> {
+    public @NotNull StaticBlockModel[] overlays = new StaticBlockModel[4];
+    public BlockModelGenericLeavesCacao(@NotNull Block<T> block) {
+        super(block, "minecraft:block/leaves/cacao");
+        for (int i = 0; i < this.overlays.length; i++) {
+            this.overlays[i] = BlockModelDispatcher.loadDataModel("minecraft:block/leaves/cacao_overlay_stage" + i).asModel();
+        }
+    }
+
+    @Override
+    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
+        super.renderStandalone(tessellator, metadata, lightmapCoord);
+        this.overlays[this.overlays.length - 1].renderStandalone(this, tessellator, 0, 0, 0, metadata, lightmapCoord, BlockColorDispatcher.getInstance().getDispatch(this.block));
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean didRender = super.renderAttached(tessellator, worldSource, tilePos, cullFaces, overrideTexture);
+        int growthRate = BlockLogicLeavesCherryFlowering.getGrowthRate(worldSource.getBlockData(tilePos));
+        if (growthRate > 0) {
+            didRender |= this.overlays[Math.min(growthRate - 1, BlockLogicLeavesCacao.MAX_GROWTH_STATE - 1)].renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        return didRender;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeavesCherryFlowering.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeavesCherryFlowering.java
new file mode 100644
index 000000000..48c0959a6
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeavesCherryFlowering.java
@@ -0,0 +1,42 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
+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.BlockLogicLeavesCherryFlowering;
+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 BlockModelGenericLeavesCherryFlowering<T extends BlockLogic> extends BlockModelGenericLeaves<T> {
+    public @NotNull StaticBlockModel overlay;
+    public @NotNull StaticBlockModel overlayFlowering;
+    public BlockModelGenericLeavesCherryFlowering(@NotNull Block<T> block) {
+        super(block, "minecraft:block/leaves/cherry");
+        this.overlay = BlockModelDispatcher.loadDataModel("minecraft:block/leaves/cherry_overlay").asModel();
+        this.overlayFlowering = BlockModelDispatcher.loadDataModel("minecraft:block/leaves/cherry_overlay_flowering").asModel();
+    }
+
+    @Override
+    public void renderStandalone(@NotNull TessellatorGeneral tessellator, int metadata, int lightmapCoord) {
+        super.renderStandalone(tessellator, metadata, lightmapCoord);
+        this.overlay.renderStandalone(this, tessellator, 0, 0, 0, metadata, lightmapCoord, BlockColorDispatcher.getInstance().getDispatch(this.block));
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean didRender = super.renderAttached(tessellator, worldSource, tilePos, cullFaces, overrideTexture);
+        int growthRate = BlockLogicLeavesCherryFlowering.getGrowthRate(worldSource.getBlockData(tilePos));
+        if (growthRate > 0) {
+            didRender |= this.overlay.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        } else {
+            didRender |= this.overlayFlowering.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        return didRender;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLever.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLever.java
new file mode 100644
index 000000000..102f66c2f
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLever.java
@@ -0,0 +1,45 @@
+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.BlockLogicLever;
+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 BlockModelGenericLever<T extends BlockLogic> extends BlockModelGeneric<T> {
+
+    public @NotNull StaticBlockModel active;
+    public BlockModelGenericLever(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/lever_idle"));
+        this.active = BlockModelDispatcher.loadDataModel("minecraft:block/lever_active").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int data = worldSource.getBlockData(tilePos);
+        int rotation = data & BlockLogicLever.MASK_ROTATION;
+        return switch (rotation) {
+            case BlockLogicLever.ROTATION_EAST -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicLever.ROTATION_WEST -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicLever.ROTATION_SOUTH -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicLever.ROTATION_NORTH -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicLever.ROTATION_TOP_NS -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicLever.ROTATION_TOP_WE -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicLever.ROTATION_BOTTOM_NS -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 2, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicLever.ROTATION_BOTTOM_WE -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 2, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            default -> super.renderAttached(tessellator, worldSource, tilePos, cullFaces, overrideTexture);
+        };
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        boolean powered = (data & BlockLogicLever.MASK_POWERED) != 0;
+        return powered ? this.active : this.staticModel;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericMatcher.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericMatcher.java
new file mode 100644
index 000000000..a2f9296e2
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericMatcher.java
@@ -0,0 +1,32 @@
+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.world.WorldSource;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+import java.util.Random;
+
+public class BlockModelGenericMatcher<T extends BlockLogic> extends BlockModelGenericAxis<T> {
+    public final @NotNull StaticBlockModel[] models = new StaticBlockModel[4];
+    public final Random random = new Random();
+    public BlockModelGenericMatcher(@NotNull Block<T> block, @NotNull String baseKey) {
+        super(block, BlockModelDispatcher.loadDataModel(baseKey + 0));
+        for (int i = 0; i < 4; i++) {
+            this.models[i] = BlockModelDispatcher.loadDataModel(baseKey + i).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        this.random.setSeed(getPositionalSeed(tilePosc));
+        return this.models[this.random.nextInt(4)];
+    }
+
+    public long getPositionalSeed(@NotNull TilePosc tilePos) {
+        return tilePos.x() * 374761393L + tilePos.y() * 668265263L + tilePos.z() * 968290493L;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPebbles.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPebbles.java
new file mode 100644
index 000000000..b0785263f
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPebbles.java
@@ -0,0 +1,22 @@
+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 org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericPebbles<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel[] models = new StaticBlockModel[3];
+    public BlockModelGenericPebbles(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/pebbles/0"));
+        for (int i = 0; i < 3; i++) {
+            this.models[i] = BlockModelDispatcher.loadDataModel("minecraft:block/pebbles/" + i).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[data % 3];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPie.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPie.java
new file mode 100644
index 000000000..2afe5028a
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPie.java
@@ -0,0 +1,23 @@
+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 org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericPie<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel[] models = new StaticBlockModel[4];
+    public BlockModelGenericPie(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/pumpkin_pie/0"));
+        for (int i = 0; i < this.models.length; i++) {
+            this.models[i] = BlockModelDispatcher.loadDataModel("minecraft:block/pumpkin_pie/" + i).asModel();
+        }
+    }
+
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[data % this.models.length];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPiston.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPiston.java
new file mode 100644
index 000000000..df0372f54
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPiston.java
@@ -0,0 +1,53 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.BlockLogic;
+import net.minecraft.core.block.BlockLogicVeryRotatable;
+import net.minecraft.core.block.piston.BlockLogicPistonBase;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.world.WorldSource;
+import net.minecraft.core.world.pos.TilePos;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericPiston<T extends BlockLogic> extends BlockModelGenericVeryRotatable<T> {
+    public final @NotNull StaticBlockModel extended;
+    public BlockModelGenericPiston(@NotNull Block<T> block, @NotNull BlockModelData base, @NotNull BlockModelData extended) {
+        super(block, base);
+        this.extended = extended.asModel();
+    }
+
+    public boolean renderHeadless(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePos tilePos) {
+        final Direction dir = BlockLogicVeryRotatable.metaToDirection(worldSource.getBlockData(tilePos));
+        switch (dir) {
+            case UP -> {
+                return this.extended.renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, false, false, null);
+            }
+            case DOWN -> {
+                return this.extended.renderAttached(this, tessellator, worldSource, tilePos, -1, 0, 0, 0, 0, 0, false, false, null);
+            }
+            case NORTH -> {
+                return this.extended.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, false, null);
+            }
+            case SOUTH -> {
+                return this.extended.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, false, null);
+            }
+            case WEST -> {
+                return this.extended.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, false, null);
+            }
+            case EAST -> {
+                return this.extended.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, false, null);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        boolean extended = /*noCulling || */(data & BlockLogicPistonBase.MASK_POWERED) != 0;
+//        Direction direction = BlockLogicPistonBase.getDirection(meta);
+        return extended ? this.extended : super.getModelFromData(data);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPistonHead.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPistonHead.java
new file mode 100644
index 000000000..21092070a
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPistonHead.java
@@ -0,0 +1,68 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.BlockLogic;
+import net.minecraft.core.block.BlockLogicVeryRotatable;
+import net.minecraft.core.block.piston.BlockLogicPistonBase;
+import net.minecraft.core.block.piston.BlockLogicPistonHead;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.world.WorldSource;
+import net.minecraft.core.world.pos.TilePos;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericPistonHead<T extends BlockLogic> extends BlockModelGenericVeryRotatable<T> {
+    public final @NotNull StaticBlockModel sticky;
+    public final @NotNull StaticBlockModel steel;
+    public final @NotNull StaticBlockModel baseHalf;
+    public final @NotNull StaticBlockModel stickyHalf;
+    public final @NotNull StaticBlockModel steelHalf;
+    public BlockModelGenericPistonHead(@NotNull Block<T> block, @NotNull BlockModelData piston, @NotNull BlockModelData sticky, @NotNull BlockModelData steel, @NotNull BlockModelData pistonHalf, @NotNull BlockModelData stickyHalf, @NotNull BlockModelData steelHalf) {
+        super(block, piston);
+        this.sticky = sticky.asModel();
+        this.steel = steel.asModel();
+        this.baseHalf = pistonHalf.asModel();
+        this.stickyHalf = stickyHalf.asModel();
+        this.steelHalf = steelHalf.asModel();
+    }
+    public void renderPistonHeadNoCulling(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, int meta, @NotNull TilePos tilePos, boolean flag) {
+        var model = switch (BlockLogicPistonHead.getPistonType(meta)) {
+            case BlockLogicPistonHead.TYPE_STICKY -> flag ? this.sticky : this.stickyHalf;
+            case BlockLogicPistonHead.TYPE_STEEL -> flag ? this.steel : this.steelHalf;
+            default -> flag ? this.staticModel : this.baseHalf;
+        };
+        final Direction dir = BlockLogicVeryRotatable.metaToDirection(worldSource.getBlockData(tilePos));
+        switch (dir) {
+            case UP -> {
+                model.renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, false, false, null);
+            }
+            case DOWN -> {
+                model.renderAttached(this, tessellator, worldSource, tilePos, -1, 0, 0, 0, 0, 0, false, false, null);
+            }
+            case NORTH -> {
+                model.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, false, null);
+            }
+            case SOUTH -> {
+                model.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, false, null);
+            }
+            case WEST -> {
+                model.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, false, null);
+            }
+            case EAST -> {
+                model.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, false, null);
+            }
+        }
+    }
+
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return switch (BlockLogicPistonHead.getPistonType(data)) {
+            case BlockLogicPistonHead.TYPE_STICKY -> this.sticky;
+            case BlockLogicPistonHead.TYPE_STEEL -> this.steel;
+            default -> this.staticModel;
+        };
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPlanksPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPlanksPainted.java
new file mode 100644
index 000000000..af28f603e
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPlanksPainted.java
@@ -0,0 +1,43 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.model.BlockModelDispatcher;
+import net.minecraft.client.render.texture.stitcher.IconCoordinate;
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.BlockLogic;
+import net.minecraft.core.util.helper.DyeColor;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericPlanksPainted<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public static final IconCoordinate[] texCoords = new IconCoordinate[DyeColor.COLOR_AMOUNT];
+    static {
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            texCoords[c.blockMeta] = TextureRegistry.getTexture("minecraft:block/planks/" + c.colorID);
+        }
+    }
+
+    public final StaticBlockModel[] models = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+
+    public BlockModelGenericPlanksPainted(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            this.models[c.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/planks/" + c.colorID).asModel();
+        }
+    }
+
+    public BlockModelGenericPlanksPainted(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            this.models[c.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/planks/" + c.colorID).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[data & DyeColor.MASK_COLOR];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPortal.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPortal.java
new file mode 100644
index 000000000..1d8cfc167
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPortal.java
@@ -0,0 +1,37 @@
+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.BlockLogicPortal;
+import net.minecraft.core.util.helper.DyeColor;
+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 BlockModelGenericPortal<T extends BlockLogicPortal> extends BlockModelGeneric<T> {
+    public final StaticBlockModel[] models = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericPortal(@NotNull Block<T> block, @NotNull String baseKey) {
+        super(block, BlockModelDispatcher.loadDataModel(baseKey + DyeColor.PURPLE.colorID));
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            this.models[c.blockMeta] = BlockModelDispatcher.loadDataModel(baseKey + c.colorID).asModel();
+        }
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int dir = worldSource.getBlockData(tilePos) & 0b1;
+        if (dir > 0) {
+            return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[this.block.getLogic().fromMetadata(data).blockMeta];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPressurePlate.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPressurePlate.java
new file mode 100644
index 000000000..0414c18b7
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPressurePlate.java
@@ -0,0 +1,44 @@
+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.BlockLogicPressurePlate;
+import net.minecraft.core.util.helper.Side;
+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 BlockModelGenericPressurePlate<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel idle;
+    public final @NotNull StaticBlockModel active;
+    public BlockModelGenericPressurePlate(@NotNull Block<T> block, @NotNull String basekey) {
+        super(block, BlockModelDispatcher.loadDataModel(basekey + "/inventory"));
+        this.idle = BlockModelDispatcher.loadDataModel(basekey + "/idle").asModel();
+        this.active = BlockModelDispatcher.loadDataModel(basekey + "/active").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        Side direction = BlockLogicPressurePlate.sideFromMeta(worldSource.getBlockData(tilePos));
+        return switch (direction) {
+            case WEST -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 1, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case EAST -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 3, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case NORTH -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case SOUTH -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 2, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            case TOP -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 2, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+            default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+        };
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        int data = source.getBlockData(tilePosc);
+        boolean pressed = (data & BlockLogicPressurePlate.MASK_POWERED) != 0;
+        return pressed ? this.active : this.idle;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPressurePlatePainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPressurePlatePainted.java
new file mode 100644
index 000000000..1d0d0b62c
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericPressurePlatePainted.java
@@ -0,0 +1,40 @@
+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.BlockLogicButton;
+import net.minecraft.core.block.BlockLogicPressurePlate;
+import net.minecraft.core.util.helper.DyeColor;
+import net.minecraft.core.world.WorldSource;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericPressurePlatePainted<T extends BlockLogic> extends BlockModelGenericPressurePlate<T> {
+    public final @NotNull StaticBlockModel[] inventory = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] idle = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] active = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericPressurePlatePainted(@NotNull Block<T> block) {
+        super(block, "minecraft:block/pressure_plate/planks/white");
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.inventory[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/pressure_plate/planks/" + color.colorID + "/inventory").asModel();
+            this.idle[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/pressure_plate/planks/" + color.colorID + "/idle").asModel();
+            this.active[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/pressure_plate/planks/" + color.colorID + "/active").asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        int data = source.getBlockData(tilePosc);
+        int color = (data >> 4) & DyeColor.MASK_COLOR;
+        boolean pressed = (data & BlockLogicPressurePlate.MASK_POWERED) != 0;
+        return pressed ? this.active[color] : this.idle[color];
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        int color = (data >> 4) & DyeColor.MASK_COLOR;
+        return this.inventory[color];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRepeater.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRepeater.java
new file mode 100644
index 000000000..3d3ffed79
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRepeater.java
@@ -0,0 +1,32 @@
+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.BlockLogicRepeater;
+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 BlockModelGenericRepeater<T extends BlockLogicRepeater> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel[] models = new StaticBlockModel[4];
+    public final @NotNull StaticBlockModel[] modelsActive = new StaticBlockModel[4];
+    public BlockModelGenericRepeater(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/repeater/0"));
+        for (int i = 0; i < this.models.length; i++) {
+            this.models[i] = BlockModelDispatcher.loadDataModel("minecraft:block/repeater/" + i).asModel();
+            this.modelsActive[i] = BlockModelDispatcher.loadDataModel("minecraft:block/repeater/active" + i).asModel();
+        }
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int meta = worldSource.getBlockData(tilePos);
+        int direction = meta & BlockLogicRepeater.MASK_DIRECTION;
+        int tick = (meta & BlockLogicRepeater.MASK_TICK_DELAY) >> 2;
+        return (this.block.getLogic().isRepeaterPowered ? this.modelsActive[tick & 0b11] : this.models[tick & 0b11]).renderAttached(this, tessellator, worldSource, tilePos, 0, 4 - direction, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRope.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java
similarity index 52%
rename from game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRope.java
rename to game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java
index 12010d5cf..38258c7fd 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelRope.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRope.java
@@ -1,26 +1,32 @@
-package net.minecraft.client.render.block.model;
+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.BlockLogicJarButterfly;
 import net.minecraft.core.block.BlockLogicLanternFirefly;
-import net.minecraft.core.block.BlockLogicRope;
 import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.util.helper.Direction;
 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.joml.primitives.AABBd;
+import org.jetbrains.annotations.Nullable;
+import org.useless.dragonfly.models.block.StaticBlockModel;
 
-public class BlockModelRope<T extends BlockLogicRope>
-    extends BlockModelStandard<T> {
-    public BlockModelRope(Block<T> block) {
-        super(block);
+public class BlockModelGenericRope<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel line;
+    public final @NotNull StaticBlockModel pile;
+    public BlockModelGenericRope(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/rope/knot"));
+        this.line = BlockModelDispatcher.loadDataModel("minecraft:block/rope/line").asModel();
+        this.pile = BlockModelDispatcher.loadDataModel("minecraft:block/rope/pile").asModel();
     }
 
     @Override
-    public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
+    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()));
         boolean hasFloor = below != null && below.canPlaceOnSurface();
         boolean hasBlockNegX = canConnect(worldSource, tilePos, Direction.WEST);
@@ -30,54 +36,40 @@ public class BlockModelRope<T extends BlockLogicRope>
         boolean hasBlockNegZ = canConnect(worldSource, tilePos, Direction.NORTH);
         boolean hasBlockPosZ = canConnect(worldSource, tilePos, Direction.SOUTH);
 
+        boolean didRender = false;
+
 
         boolean drawKnot = !(hasBlockNegX && hasBlockPosX && !hasBlockNegY && !hasBlockPosY && !hasBlockNegZ && !hasBlockPosZ) &&
             !(!hasBlockNegX && !hasBlockPosX && hasBlockNegY && hasBlockPosY && !hasBlockNegZ && !hasBlockPosZ) &&
             !(!hasBlockNegX && !hasBlockPosX && !hasBlockNegY && !hasBlockPosY && hasBlockNegZ && hasBlockPosZ);
 
-        AABBd bounds = new AABBd(0, 0, 0, 1, 1, 1);
-
-        final float ropeThickness = (1 / 16f);
-        final float knotThickness = (2 / 16f);
-        final float pileWidth = (3 / 16f);
-
-        if (drawKnot) {
-            bounds.setMin(0.5f - knotThickness, 0.5f - knotThickness, 0.5f - knotThickness).setMax(0.5f + knotThickness, 0.5f + knotThickness, 0.5f + knotThickness);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+        if (hasBlockNegZ) {
+            didRender |= this.line.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
         }
-
-        if (hasBlockPosY) {
-            bounds.setMin(0.5f - ropeThickness, 0.5f, 0.5f - ropeThickness).setMax(0.5f + ropeThickness, 1, 0.5f + ropeThickness);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+        if (hasBlockPosZ) {
+            didRender |= this.line.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, true, cullFaces, overrideTexture);
         }
-        if (hasBlockNegY) {
-            bounds.setMin(0.5f - ropeThickness, 0, 0.5f - ropeThickness).setMax(0.5f + ropeThickness, 0.5f, 0.5f + ropeThickness);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+        if (hasBlockNegX) {
+            didRender |= this.line.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, true, cullFaces, overrideTexture);
         }
         if (hasBlockPosX) {
-            bounds.setMin(0.5f, 0.5f - ropeThickness, 0.5f - ropeThickness).setMax(1, 0.5f + ropeThickness, 0.5f + ropeThickness);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+            didRender |= this.line.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, true, cullFaces, overrideTexture);
         }
-        if (hasBlockNegX) {
-            bounds.setMin(0, 0.5f - ropeThickness, 0.5f - ropeThickness).setMax(0.5f, 0.5f + ropeThickness, 0.5f + ropeThickness);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+        if (hasBlockNegY) {
+            didRender |= this.line.renderAttached(this, tessellator, worldSource, tilePos, 3, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
         }
-        if (hasBlockPosZ) {
-            bounds.setMin(0.5f - ropeThickness, 0.5f - ropeThickness, 0.5f).setMax(0.5f + ropeThickness, 0.5f + ropeThickness, 1);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+        if (hasBlockPosY) {
+            didRender |= this.line.renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, true, cullFaces, overrideTexture);
         }
-        if (hasBlockNegZ) {
-            bounds.setMin(0.5f - ropeThickness, 0.5f - ropeThickness, 0f).setMax(0.5f + ropeThickness, 0.5f + ropeThickness, 0.5f);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+
+        if (drawKnot) {
+            didRender |= this.staticModel.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
         }
         if (hasFloor) {
-            bounds.setMin(0.5f - pileWidth, 0, 0.5f - pileWidth).setMax(0.5f + pileWidth, knotThickness, 0.5f + pileWidth);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
-            bounds.setMin(0.5f - knotThickness, 0, 0.5f - knotThickness).setMax(0.5f + knotThickness, ropeThickness * 3, 0.5f + knotThickness);
-            renderBlocks.renderStandardBlock(tessellator, worldSource, this, bounds, tilePos);
+            didRender |= this.pile.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
         }
 
-        return true;
+        return didRender;
     }
 
     private boolean canConnect(@NotNull WorldSource worldSource, @NotNull TilePosc tilePos, @NotNull Direction direction) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRotatable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRotatable.java
new file mode 100644
index 000000000..8e89fc9a8
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericRotatable.java
@@ -0,0 +1,50 @@
+package net.minecraft.client.render.block.model.generic;
+
+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.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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericRotatable<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public BlockModelGenericRotatable(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+    }
+
+    public BlockModelGenericRotatable(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+    }
+
+    @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, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case DOWN -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, -1, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case NORTH -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case WEST -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case EAST -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case SOUTH -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+        }
+        return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericShifted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericShifted.java
new file mode 100644
index 000000000..d1ec5f1a1
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericShifted.java
@@ -0,0 +1,34 @@
+package net.minecraft.client.render.block.model.generic;
+
+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.world.WorldSource;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericShifted<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public BlockModelGenericShifted(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+    }
+
+    public BlockModelGenericShifted(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        // Shift grass position with deterministic position based random
+        long dRandom = (tilePos.x() * 0x2fc20fL) ^ (long) tilePos.z() * 0x6ebfff5L ^ (long) tilePos.y();
+        dRandom = dRandom * dRandom * 0x285b825L + dRandom * 11L;
+        double xd = ((double) ((float) (dRandom >> 16 & 15L) / 15F) - 0.5D) * 0.5D;
+        double yd = ((double) ((float) (dRandom >> 20 & 15L) / 15F) - 1.0D) * 0.2D;
+        double zd = ((double) ((float) (dRandom >> 24 & 15L) / 15F) - 0.5D) * 0.5D;
+
+        return this.staticModel.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, xd, yd, zd, false, cullFaces, overrideTexture);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSlab.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSlab.java
new file mode 100644
index 000000000..39393183f
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSlab.java
@@ -0,0 +1,26 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.BlockLogic;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericSlab<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel upper;
+    public final @NotNull StaticBlockModel full;
+    public BlockModelGenericSlab(@NotNull Block<T> block, @NotNull BlockModelData lower, @NotNull BlockModelData upper, @NotNull BlockModelData full) {
+        super(block, lower);
+        this.upper = upper.asModel();
+        this.full = full.asModel();
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return switch (data & 0b11) {
+            case 1 -> this.full;
+            case 2 -> this.upper;
+            default -> this.staticModel;
+        };
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSlabPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSlabPainted.java
new file mode 100644
index 000000000..7a7043637
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSlabPainted.java
@@ -0,0 +1,35 @@
+package net.minecraft.client.render.block.model.generic;
+
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
+import net.minecraft.client.render.block.model.BlockModelDispatcher;
+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.DyeColor;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericSlabPainted<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel[] upper = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] lower = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] full = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericSlabPainted(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/slab/planks/white/lower"));
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.upper[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/slab/planks/" + color.colorID + "/upper").asModel();
+            this.lower[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/slab/planks/" + color.colorID + "/lower").asModel();
+            this.full[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/slab/planks/" + color.colorID + "/full").asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        int color = (data >> 4) & DyeColor.MASK_COLOR;
+        return switch (data & 0b11) {
+            case 1 -> this.full[color];
+            case 2 -> this.upper[color];
+            default -> this.lower[color];
+        };
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSpikes.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSpikes.java
new file mode 100644
index 000000000..4c1b2bbf0
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSpikes.java
@@ -0,0 +1,30 @@
+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.BlockLogicSpikes;
+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 BlockModelGenericSpikes<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public @NotNull StaticBlockModel spikes;
+    public BlockModelGenericSpikes(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/spikes_base"));
+        this.spikes = BlockModelDispatcher.loadDataModel("minecraft:block/spikes").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        boolean didRender = super.renderAttached(tessellator, worldSource, tilePos, cullFaces, overrideTexture);
+        if (BlockLogicSpikes.isSpikesUp(worldSource.getBlockData(tilePos))) {
+            didRender |= this.spikes.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        }
+        return didRender;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericStairs.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericStairs.java
new file mode 100644
index 000000000..5c8e32660
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericStairs.java
@@ -0,0 +1,36 @@
+package net.minecraft.client.render.block.model.generic;
+
+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.world.WorldSource;
+import net.minecraft.core.world.pos.TilePosc;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericStairs<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public BlockModelGenericStairs(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+    }
+
+    public BlockModelGenericStairs(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int meta = worldSource.getBlockData(tilePos);
+        int hRotation = meta & 0b0011;
+        int vRotation = (meta & 0b1000) >> 3;
+        int yRot = switch (hRotation) {
+            case 0 -> 0;
+            case 1 -> 2;
+            case 2 -> 3;
+            default -> 1;
+        };
+        return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, vRotation * 2, yRot, 0, 0, 0, 0, true, cullFaces, overrideTexture);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericStairsPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericStairsPainted.java
new file mode 100644
index 000000000..0c707829b
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericStairsPainted.java
@@ -0,0 +1,29 @@
+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.util.helper.DyeColor;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericStairsPainted<T extends BlockLogic> extends BlockModelGenericStairs<T> {
+    public final @NotNull StaticBlockModel[] models = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericStairsPainted(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/stairs/planks/" + DyeColor.WHITE.colorID));
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.models[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/stairs/planks/" + color.colorID).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[(data >> 4) & DyeColor.MASK_COLOR];
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTorch.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTorch.java
new file mode 100644
index 000000000..2f4a1de17
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTorch.java
@@ -0,0 +1,32 @@
+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.BlockLogicTorch;
+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 BlockModelGenericTorch<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel wallTorch;
+    public BlockModelGenericTorch(@NotNull Block<T> block, @NotNull String baseKey) {
+        super(block, BlockModelDispatcher.loadDataModel(baseKey));
+        this.wallTorch = BlockModelDispatcher.loadDataModel(baseKey + "_wall").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        return switch (worldSource.getBlockData(tilePos) & BlockLogicTorch.MASK_DIRECTION) {
+            case BlockLogicTorch.SIDE_WEST -> this.wallTorch.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicTorch.SIDE_EAST -> this.wallTorch.renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicTorch.SIDE_NORTH -> this.wallTorch.renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case BlockLogicTorch.SIDE_SOUTH -> this.wallTorch.renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        };
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTrapdoor.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTrapdoor.java
new file mode 100644
index 000000000..f7d8613fd
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTrapdoor.java
@@ -0,0 +1,41 @@
+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.BlockLogicTrapDoor;
+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 BlockModelGenericTrapdoor<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel open;
+    public final @NotNull StaticBlockModel top;
+    public BlockModelGenericTrapdoor(@NotNull Block<T> block, @NotNull String basekey) {
+        super(block, BlockModelDispatcher.loadDataModel(basekey + "/bottom"));
+        this.open = BlockModelDispatcher.loadDataModel(basekey + "/open").asModel();
+        this.top = BlockModelDispatcher.loadDataModel(basekey + "/top").asModel();
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int rotation = worldSource.getBlockData(tilePos) & BlockLogicTrapDoor.MASK_DIRECTION;
+        return switch (rotation & 0b11) {
+            case 1 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case 2 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case 3 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        };
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        if ((data & BlockLogicTrapDoor.MASK_OPEN) != 0) return this.open;
+        if ((data & BlockLogicTrapDoor.MASK_UPPER_HALF) != 0) return this.top;
+        return this.staticModel;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTrapdoorPainted.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTrapdoorPainted.java
new file mode 100644
index 000000000..ef1d41a03
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericTrapdoorPainted.java
@@ -0,0 +1,47 @@
+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.BlockLogicTrapDoor;
+import net.minecraft.core.util.helper.DyeColor;
+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 BlockModelGenericTrapdoorPainted<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final @NotNull StaticBlockModel[] bottom = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] open = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public final @NotNull StaticBlockModel[] top = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericTrapdoorPainted(@NotNull Block<T> block) {
+        super(block, BlockModelDispatcher.loadDataModel("minecraft:block/trapdoor/planks/white/bottom"));
+        for (DyeColor color : DyeColor.blockOrderedColors()) {
+            this.bottom[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/trapdoor/planks/" + color.colorID + "/bottom").asModel();
+            this.open[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/trapdoor/planks/" + color.colorID + "/open").asModel();
+            this.top[color.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/trapdoor/planks/" + color.colorID + "/top").asModel();
+        }
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        int rotation = worldSource.getBlockData(tilePos) & BlockLogicTrapDoor.MASK_DIRECTION;
+        return switch (rotation & 0b11) {
+            case 1 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case 2 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 1, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            case 3 -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 3, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            default -> getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        };
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        int color = (data >> 4) & DyeColor.MASK_COLOR;
+        if ((data & BlockLogicTrapDoor.MASK_OPEN) != 0) return this.open[color];
+        if ((data & BlockLogicTrapDoor.MASK_UPPER_HALF) != 0) return this.top[color];
+        return this.bottom[color];
+    }
+}
\ No newline at end of file
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericVeryRotatable.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericVeryRotatable.java
new file mode 100644
index 000000000..92148e825
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericVeryRotatable.java
@@ -0,0 +1,50 @@
+package net.minecraft.client.render.block.model.generic;
+
+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.BlockLogicVeryRotatable;
+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.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericVeryRotatable<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public BlockModelGenericVeryRotatable(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+    }
+
+    public BlockModelGenericVeryRotatable(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+    }
+
+    @Override
+    public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+        final Direction dir = BlockLogicVeryRotatable.metaToDirection(worldSource.getBlockData(tilePos));
+        switch (dir) {
+            case UP -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 1, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+            }
+            case DOWN -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, -1, 0, 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 SOUTH -> {
+                return getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, 0, 2, 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);
+            }
+        }
+        return false;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericWool.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericWool.java
new file mode 100644
index 000000000..2e6fc433b
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericWool.java
@@ -0,0 +1,31 @@
+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.util.helper.DyeColor;
+import org.jetbrains.annotations.NotNull;
+import org.useless.dragonfly.data.block.BlockModelData;
+import org.useless.dragonfly.models.block.StaticBlockModel;
+
+public class BlockModelGenericWool<T extends BlockLogic> extends BlockModelGeneric<T> {
+    public final StaticBlockModel[] models = new StaticBlockModel[DyeColor.COLOR_AMOUNT];
+    public BlockModelGenericWool(@NotNull Block<T> block, @NotNull StaticBlockModel staticModel) {
+        super(block, staticModel);
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            this.models[c.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/wool/" + c.colorID).asModel();
+        }
+    }
+
+    public BlockModelGenericWool(@NotNull Block<T> block, @NotNull BlockModelData staticModel) {
+        super(block, staticModel);
+        for (DyeColor c : DyeColor.blockOrderedColors()) {
+            this.models[c.blockMeta] = BlockModelDispatcher.loadDataModel("minecraft:block/wool/" + c.colorID).asModel();
+        }
+    }
+
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return this.models[data & DyeColor.MASK_COLOR];
+    }
+}
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 da5b77a44..96912b50d 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
@@ -14,12 +14,11 @@ 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.render.tileentity.TileEntityRenderer;
-import net.minecraft.core.Global;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.motion.CarriedBlock;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.BlocksContainer;
 import net.minecraft.core.world.pos.TilePos;
@@ -110,7 +109,7 @@ 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() != Gamemode.spectator && entity.getGamemode() == Gamemode.spectator) {
+        if (Minecraft.getMinecraft().thePlayer.getGamemode() != Gamemodes.SPECTATOR && entity.getGamemode() == Gamemodes.SPECTATOR) {
             return;
         }
         if (Minecraft.getMinecraft().gameSettings.immersiveMode.drawNames() && this.renderDispatcher.camera != null) // Render name
diff --git a/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTerrainImpl.java b/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTerrainImpl.java
index eb328e0e7..fab038112 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTerrainImpl.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTerrainImpl.java
@@ -175,6 +175,7 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
 
 	public void checkIsDrawing() {
 		if(!this.drawing) {
+			this.drawing = false;
 			throw new IllegalStateException("Not drawing!");
 		}
 	}
diff --git a/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/TextureRegistry.java b/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/TextureRegistry.java
index f5fee0b2c..5092ad179 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/TextureRegistry.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/TextureRegistry.java
@@ -103,9 +103,9 @@ public class TextureRegistry {
         final int slashIndex = id.value().indexOf("/");
         String atlasId = id.value().substring(0, slashIndex);
         final AtlasStitcher atlas = stitcherMap.get(atlasId);
-        if (atlas == null) throw new IllegalArgumentException("Failed to find atlas '" + atlasId + "'!");
+        if (atlas == null) throw new IllegalArgumentException("Failed to find atlas '" + atlasId + "'! From ID: " + id);
 
-        return atlas.iconMap.containsKey(NamespaceID.fromPool(id.namespace(), id.value().substring(slashIndex + 1)));
+        return atlas.iconMap.containsKey(id);
     }
     public static @NotNull AtlasStitcher register(@NotNull AtlasStitcher atlas){
         for (String id : atlas.idDirMap.keySet()) {
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 74d1e7ac7..a897e1903 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
@@ -4,10 +4,11 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.TileEntityRenderDispatcher;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
-import net.minecraft.client.render.block.model.BlockModelPiston;
-import net.minecraft.client.render.block.model.BlockModelPistonHead;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPiston;
+import net.minecraft.client.render.block.model.generic.BlockModelGenericPistonHead;
 import net.minecraft.client.render.renderer.BlendFactor;
 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.TextureRegistry;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
@@ -39,26 +40,20 @@ public class TileEntityRendererMovingPiston extends TileEntityRenderer<TileEntit
             }
             TilePos tileEntPos = new TilePos(tileEntity.x, tileEntity.y, tileEntity.z);
             TextureRegistry.worldAtlas.bind();
-            Lighting.disable();
+            GLRenderer.setShader(Shaders.TERRAIN);
             GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
             GLRenderer.enableState(State.BLEND);
             GLRenderer.disableState(State.CULL_FACE);
             tessellator.startDrawingQuads();
             tessellator.setTranslation(((float) x - (float) tileEntity.x) + tileEntity.getXOff(partialTick), ((float) y - (float) tileEntity.y) + tileEntity.getYOff(partialTick), ((float) z - (float) tileEntity.z) + tileEntity.getZOff(partialTick));
             if (Block.hasLogicClass(block, BlockLogicPistonHead.class) && tileEntity.getProgress(partialTick) < 0.5F) {
-                ((BlockModelPistonHead) BlockModelDispatcher.getInstance().getDispatch(block)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, (Block<BlockLogicPistonHead>) block, tileEntPos, false);
+                ((BlockModelGenericPistonHead<?>) BlockModelDispatcher.getInstance().getDispatch(block)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, tileEntity.getBlockMeta(), tileEntPos, false);
             } else if (tileEntity.isSourcePiston() && !tileEntity.isExtending()) {
-                BlockModelPiston<?> pistonBase = (BlockModelPiston<?>) BlockModelDispatcher.getInstance().getDispatch(block);
+                BlockModelGenericPiston<?> pistonBase = (BlockModelGenericPiston<?>) BlockModelDispatcher.getInstance().getDispatch(block);
                 if (Block.hasLogicClass(block, BlockLogicPistonBaseSteel.class)) { // Todo remove this terrible hardcoded render code
-                    BlockModelPistonHead blockModelPistonHead = ((BlockModelPistonHead) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD_STEEL));
-                    blockModelPistonHead.setFaceTextureOverride(pistonBase.getFaceTexture());
-                    blockModelPistonHead.renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, Blocks.PISTON_HEAD_STEEL, tileEntPos, tileEntity.getProgress(partialTick) < 0.5F);
-                    blockModelPistonHead.setFaceTextureOverride(null);
+                    ((BlockModelGenericPistonHead<?>) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD_STEEL)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, BlockLogicPistonHead.TYPE_STEEL << 3, tileEntPos, tileEntity.getProgress(partialTick) < 0.5F);
                 } else {
-                    BlockModelPistonHead blockModelPistonHead = ((BlockModelPistonHead) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD));
-                    blockModelPistonHead.setFaceTextureOverride(pistonBase.getFaceTexture());
-                    blockModelPistonHead.renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, Blocks.PISTON_HEAD, tileEntPos, tileEntity.getProgress(partialTick) < 0.5F);
-                    blockModelPistonHead.setFaceTextureOverride(null);
+                    ((BlockModelGenericPistonHead<?>) BlockModelDispatcher.getInstance().getDispatch(Blocks.PISTON_HEAD)).renderPistonHeadNoCulling(tessellator, tileEntity.worldObj, tileEntity.getBlockMeta(), tileEntPos, tileEntity.getProgress(partialTick) < 0.5F);
                 }
                 tessellator.setTranslation((float) x - (float) tileEntity.x, (float) y - (float) tileEntity.y, (float) z - (float) tileEntity.z);
                 pistonBase.renderHeadless(tessellator, tileEntity.worldObj, tileEntPos);
@@ -71,8 +66,6 @@ public class TileEntityRendererMovingPiston extends TileEntityRenderer<TileEntit
             tessellator.setTranslation(0.0D, 0.0D, 0.0D);
             tessellator.draw();
 
-            Lighting.enableLight();
-
             TileEntity movedEntity = tileEntity.getMovedEntity();
             TileEntityRenderer<TileEntity> renderer = TileEntityRenderDispatcher.instance.getRenderer(movedEntity);
             if (renderer != null) {
diff --git a/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java b/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
index 85b158547..185e962b9 100644
--- a/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
+++ b/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
@@ -65,7 +65,7 @@ public class ItemDragHandler extends Gui {
                 this.renderItemStack = this.draggingItemStack.copy();
                 this.renderItemStack.stackSize = 1;
 
-				boolean isCreativeDragging = this.draggingButton == 2 && !this.mc.thePlayer.getGamemode().consumeBlocks();
+				boolean isCreativeDragging = this.draggingButton == 2 && !this.mc.thePlayer.getGamemode().hasBlockConsumption();
 				
 				if(isCreativeDragging) {
                     this.renderItemStackCount = this.draggingItemStack.getMaxStackSize();
@@ -91,7 +91,7 @@ public class ItemDragHandler extends Gui {
 	private void onDragOverSlot(Slot slot) {
 		if(slot == null) return;
 		
-		boolean isCreativeDragging = this.draggingButton == 2 && !this.mc.thePlayer.getGamemode().consumeBlocks();
+		boolean isCreativeDragging = this.draggingButton == 2 && !this.mc.thePlayer.getGamemode().hasBlockConsumption();
 		if(this.draggedSlots.size() >= this.draggingItemStack.stackSize && !isCreativeDragging) {
 			return;
 		}
@@ -244,7 +244,7 @@ public class ItemDragHandler extends Gui {
 		
 		InventoryAction action = mode == 1 ? InventoryAction.DRAG_ITEMS_ONE : InventoryAction.DRAG_ITEMS_ALL;
 		
-		if(mode == 2 && !this.mc.thePlayer.getGamemode().consumeBlocks()) {
+		if(mode == 2 && !this.mc.thePlayer.getGamemode().hasBlockConsumption()) {
 			action = InventoryAction.CREATIVE_DRAG;
 		}
 		
diff --git a/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java b/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java
index 6dee67e1c..6f4c58628 100644
--- a/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java
+++ b/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java
@@ -111,9 +111,9 @@ public final class DisplayPos {
         @Override
         public DisplayPos deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
             JsonObject object = json.getAsJsonObject();
-            float[] rotation = GsonHelper.getAsFloatArray(object.get("rotation"), 3);
-            float[] translation = GsonHelper.getAsFloatArray(object.get("translation"), 3);
-            float[] scale = GsonHelper.getAsFloatArray(object.get("scale"), 3);
+            float[] rotation = object.has("rotation") ? GsonHelper.getAsFloatArray(object.get("rotation"), 3) : new float[] { 0, 0, 0 };
+            float[] translation = object.has("translation") ? GsonHelper.getAsFloatArray(object.get("translation"), 3) : new float[] { 0, 0, 0 };
+            float[] scale = object.has("scale") ? GsonHelper.getAsFloatArray(object.get("scale"), 3) : new float[] { 0, 0, 0 };
             return new DisplayPos(
                 translation[0] * BlockModelMojangData.BLOCKS_PER_UNIT, translation[1] * BlockModelMojangData.BLOCKS_PER_UNIT, translation[2] * BlockModelMojangData.BLOCKS_PER_UNIT,
                 rotation[0], rotation[1], rotation[2],
diff --git a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java
index 954aab092..e198d6534 100644
--- a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java
+++ b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java
@@ -14,6 +14,7 @@ import com.google.gson.stream.JsonReader;
 import com.mojang.logging.LogUtils;
 import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.texturepack.TexturePackList;
 import net.minecraft.core.util.HardIllegalArgumentException;
 import net.minecraft.core.util.collection.NamespaceID;
@@ -114,7 +115,7 @@ public class BlockModelMojangData implements BlockModelData {
         @Nullable final Object2IntMap<@NotNull Direction> particleIndices,
         @Nullable final List<@NotNull Element> elements)
     {
-        this.modelId = id.makePermanent();
+        this.modelId = new NamespaceID(id);
         this.parent = parent;
         if (parent != null) {
             final BlockModelMojangData parentData = BlockModelMojangData.Cache.loadModelData(texturePackList, parent);
@@ -178,7 +179,7 @@ public class BlockModelMojangData implements BlockModelData {
     public static class Builder {
         protected @Nullable String parent = DEFAULT_PARENT;
         protected boolean ambientOcclusion = DEFAULT_AMBIENT_OCCLUSION;
-        protected int renderLayer = DEFAULT_RENDER_LAYER;
+        protected @Nullable Integer renderLayer = null;
         protected @Nullable Map<@NotNull String, @NotNull DisplayPos> displayPosMap = null;
         protected @Nullable Map<@NotNull String, @NotNull String> textures = null;
         protected @Nullable Object2IntMap<@NotNull Direction> particleIndices = null;
@@ -345,6 +346,21 @@ public class BlockModelMojangData implements BlockModelData {
             return model;
         }
 
+        private static @NotNull BlockModelMojangData MISSING_MODEL = new BlockModelMojangData.Builder()
+            .addElement(new Element.Builder(0, 0, 0, 16, 16, 16)
+                .addFace(Direction.UP, new Face.Builder("minecraft:block/missing"))
+                .addFace(Direction.DOWN, new Face.Builder("minecraft:block/missing"))
+                .addFace(Direction.NORTH, new Face.Builder("minecraft:block/missing"))
+                .addFace(Direction.SOUTH, new Face.Builder("minecraft:block/missing"))
+                .addFace(Direction.WEST, new Face.Builder("minecraft:block/missing"))
+                .addFace(Direction.EAST, new Face.Builder("minecraft:block/missing"))
+            )
+            .setAO(true)
+            .build(Minecraft.getMinecraft().texturePackList, "minecraft:block/missing");
+        public static @NotNull BlockModelMojangData getMissingModel() {
+            return MISSING_MODEL;
+        }
+
         public static void resetCache() {
             modelDataCache.clear();
         }
diff --git a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java
index 3bd050f7a..c5a46949c 100644
--- a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java
+++ b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java
@@ -1,6 +1,7 @@
 package org.useless.dragonfly.data.block.mojang;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 import net.minecraft.client.render.block.model.BlockModelStandard;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -9,11 +10,16 @@ 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.Vector2f;
+import org.joml.Vector2fc;
+import org.joml.Vector3d;
+import org.joml.Vector3dc;
+import org.joml.Vector3f;
+import org.joml.Vector3fc;
 import org.slf4j.Logger;
 import org.useless.dragonfly.DisplayPos;
+import org.useless.dragonfly.data.block.BlockModelData;
 
-import java.util.Arrays;
-import java.util.HashMap;
 import java.util.Map;
 
 import static org.useless.dragonfly.data.block.mojang.BlockModelMojangData.BLOCKS_PER_UNIT;
@@ -23,10 +29,10 @@ public class CompiledBlockModelMojangData {
 
     public final BlockModelMojangData data;
 
-    public final @NotNull Map<@NotNull String, @NotNull IconCoordinate> textures = new HashMap<>();
+    public final @NotNull Map<@NotNull String, IconCoordinate> textures = new Object2ObjectOpenHashMap<>();
     public final @NotNull C_Element @NotNull [] elements;
     public final int @NotNull [] particleIndices;
-    public final @NotNull Map<@NotNull String, @NotNull DisplayPos> displayPosMap;
+    public final @NotNull Map<@NotNull String, DisplayPos> displayPosMap;
     public final int renderLayer;
 
     public CompiledBlockModelMojangData(BlockModelMojangData data) {
@@ -37,62 +43,63 @@ public class CompiledBlockModelMojangData {
         } else {
             for (String key : data.textures.keySet()) {
                 IconCoordinate coordinate = getTexture("#" + key, null, true);
-                if (coordinate != null) textures.put("#" + key, coordinate);
+                if (coordinate != null) this.textures.put("#" + key, coordinate);
             }
         }
 
-        IconCoordinate particleAll = textures.get("#particle");
+        IconCoordinate particleAll = this.textures.get("#particle");
 
         if (particleAll != null) { // Modern mojang format support, the modern mc version only has a global particle texture symbol rather than per side
-            textures.putIfAbsent("#particle_up", particleAll);
-            textures.putIfAbsent("#particle_down", particleAll);
-            textures.putIfAbsent("#particle_north", particleAll);
-            textures.putIfAbsent("#particle_south", particleAll);
-            textures.putIfAbsent("#particle_west", particleAll);
-            textures.putIfAbsent("#particle_east", particleAll);
-            textures.putIfAbsent("#overlay", particleAll);
+            this.textures.putIfAbsent("#particle_up", particleAll);
+            this.textures.putIfAbsent("#particle_down", particleAll);
+            this.textures.putIfAbsent("#particle_north", particleAll);
+            this.textures.putIfAbsent("#particle_south", particleAll);
+            this.textures.putIfAbsent("#particle_west", particleAll);
+            this.textures.putIfAbsent("#particle_east", particleAll);
+            this.textures.putIfAbsent("#overlay", particleAll);
         } else {
-            if (textures.get("#particle_up") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_up' symbol!", data.modelId());
-            if (textures.get("#particle_down") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_down' symbol!", data.modelId());
-            if (textures.get("#particle_north") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_north' symbol!", data.modelId());
-            if (textures.get("#particle_south") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_south' symbol!", data.modelId());
-            if (textures.get("#particle_west") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_west' symbol!", data.modelId());
-            if (textures.get("#particle_east") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_east' symbol!", data.modelId());
+            if (this.textures.get("#particle_up") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_up' symbol!", data.modelId());
+            if (this.textures.get("#particle_down") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_down' symbol!", data.modelId());
+            if (this.textures.get("#particle_north") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_north' symbol!", data.modelId());
+            if (this.textures.get("#particle_south") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_south' symbol!", data.modelId());
+            if (this.textures.get("#particle_west") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_west' symbol!", data.modelId());
+            if (this.textures.get("#particle_east") == null) LOGGER.warn("Model '{}' does not have an assigned '#particle_east' symbol!", data.modelId());
         }
-        if (textures.get("#overlay") == null) LOGGER.warn("Model '{}' does not have an assigned '#overlay' symbol!", data.modelId());
+        if (this.textures.get("#overlay") == null) LOGGER.warn("Model '{}' does not have an assigned '#overlay' symbol!", data.modelId());
 
-        displayPosMap = new HashMap<>();
-        if (data.displayPositions != null) displayPosMap.putAll(data.displayPositions);
+        this.displayPosMap = new Object2ObjectOpenHashMap<>();
+        if (data.displayPositions != null) this.displayPosMap.putAll(data.displayPositions);
 
-        particleIndices = new int[6];
+        this.particleIndices = new int[6];
         if (data.particleIndices != null) {
-            particleIndices[Direction.UP.getId()] = data.particleIndices.getOrDefault(Direction.UP, 0);
-            particleIndices[Direction.DOWN.getId()] = data.particleIndices.getOrDefault(Direction.DOWN, 0);
-            particleIndices[Direction.NORTH.getId()] = data.particleIndices.getOrDefault(Direction.NORTH, 0);
-            particleIndices[Direction.SOUTH.getId()] = data.particleIndices.getOrDefault(Direction.SOUTH, 0);
-            particleIndices[Direction.WEST.getId()] = data.particleIndices.getOrDefault(Direction.WEST, 0);
-            particleIndices[Direction.EAST.getId()] = data.particleIndices.getOrDefault(Direction.EAST, 0);
+            this.particleIndices[Direction.UP.getId()] = data.particleIndices.getOrDefault(Direction.UP, 0);
+            this.particleIndices[Direction.DOWN.getId()] = data.particleIndices.getOrDefault(Direction.DOWN, 0);
+            this.particleIndices[Direction.NORTH.getId()] = data.particleIndices.getOrDefault(Direction.NORTH, 0);
+            this.particleIndices[Direction.SOUTH.getId()] = data.particleIndices.getOrDefault(Direction.SOUTH, 0);
+            this.particleIndices[Direction.WEST.getId()] = data.particleIndices.getOrDefault(Direction.WEST, 0);
+            this.particleIndices[Direction.EAST.getId()] = data.particleIndices.getOrDefault(Direction.EAST, 0);
         }
 
-        renderLayer = data.renderLayer == null ? 0 : data.renderLayer;
+        this.renderLayer = data.renderLayer == null ? 0 : data.renderLayer;
 
-        elements = new C_Element[data.elements == null ? 0 : data.elements.size()];
+        this.elements = new C_Element[data.elements == null ? 0 : data.elements.size()];
         if (data.elements != null) {
             int i = 0;
             for (Element e : data.elements) {
-                elements[i++] = new C_Element(e);
+                this.elements[i] = new C_Element(this, e);
+                i++;
             }
         }
     }
 
     protected IconCoordinate getTexture(@NotNull final String textureSymbol, @Nullable final IconCoordinate defaultCoordinate, final boolean logWarnings) {
         try {
-            if (data.textures == null) {
-                if (logWarnings) LOGGER.warn("Model '{}' does not have assigned texture data!", data.modelId());
+            if (this.data.textures == null) {
+                if (logWarnings) LOGGER.warn("Model '{}' does not have assigned texture data!", this.data.modelId());
                 return defaultCoordinate;
             }
 
-            @Nullable String path = data.textures.get(textureSymbol.startsWith("#") ? textureSymbol.substring(1) : textureSymbol);
+            @Nullable String path = this.data.textures.get(textureSymbol.startsWith("#") ? textureSymbol.substring(1) : textureSymbol);
 
             if (path == null) {
                 if (logWarnings) LOGGER.warn("Texture for symbol '{}' is not assigned to any value!", textureSymbol);
@@ -110,7 +117,7 @@ public class CompiledBlockModelMojangData {
             }
 
         } catch (StackOverflowError stackOverflowError) {
-            LOGGER.error("Recursive texture lookup from symbol '{}' in model '{}'!", textureSymbol, data.modelId());
+            LOGGER.error("Recursive texture lookup from symbol '{}' in model '{}'!", textureSymbol, this.data.modelId());
             return defaultCoordinate;
         }
     }
@@ -121,20 +128,9 @@ public class CompiledBlockModelMojangData {
         public static final int VERTEX_BOTTOM_RIGHT = 2;
         public static final int VERTEX_BOTTOM_LEFT = 1;
 
-        public static final int VERTEX_FLOAT_X = 0;
-        public static final int VERTEX_FLOAT_Y = 1;
-        public static final int VERTEX_FLOAT_Z = 2;
-        public static final int VERTEX_FLOAT_U = 3;
-        public static final int VERTEX_FLOAT_V = 4;
-        public static final int FLOATS_PER_VERTEX = 5;
-
-        public static final int NORMAL_FLOAT_X = 0;
-        public static final int NORMAL_FLOAT_Y = 1;
-        public static final int NORMAL_FLOAT_Z = 2;
-        public static final int FLOATS_PER_NORMAL = 3;
-
         public final int lightEmission;
         public final boolean shade;
+        public final boolean flip;
 
         public final float minX;
         public final float minY;
@@ -144,27 +140,41 @@ public class CompiledBlockModelMojangData {
         public final float maxZ;
 
         public final int faces;
-        public final float @NotNull [] vertexData;
-        public final float @NotNull [] normalData;
+        public final @NotNull Element sourceElement;
+        public final @NotNull Vector3dc @NotNull [] vertexPoses;
+        public final @NotNull Vector2fc @NotNull [] vertexUvs;
+        public final @NotNull Vector3fc @NotNull [] faceNormals;
+        public final @NotNull Vector3fc @NotNull [] faceUps;
+        public final @NotNull Vector3fc @NotNull [] faceLefts;
         public final int @NotNull [] tintIndices;
         public final @Nullable Direction @NotNull [] cullfaces;
         public final @NotNull Direction @NotNull [] directions;
-        public final @NotNull String @NotNull [] textures;
-
-        public C_Element(Element element) {
-            faces = element.faces.size();
-            vertexData = new float[faces * 4 * FLOATS_PER_VERTEX];
-            normalData = new float[faces * FLOATS_PER_NORMAL];
-            tintIndices = new int[faces];
-            cullfaces = new Direction[faces];
-            directions = new Direction[faces];
-            textures = new String[faces];
-
-            shade = element.shade;
-            lightEmission = element.lightEmission;
+        public final @NotNull IconCoordinate @NotNull [] textures;
+
+        public C_Element(@NotNull CompiledBlockModelMojangData data, @NotNull Element element) {
+            this.faces = element.faces.size();
+            this.sourceElement = element;
+            this.vertexPoses = new Vector3dc[this.faces * 4];
+            this.vertexUvs = new Vector2fc[this.faces * 4];
+            this.faceNormals = new Vector3fc[this.faces];
+            this.faceUps = new Vector3fc[this.faces];
+            this.faceLefts = new Vector3fc[this.faces];
+            this.tintIndices = new int[this.faces];
+            this.cullfaces = new Direction[this.faces];
+            this.directions = new Direction[this.faces];
+            this.textures = new IconCoordinate[this.faces];
+
+            this.shade = element.shade;
+            this.lightEmission = element.lightEmission;
+
+            int negs = 0;
+            if (element.fromX > element.toX) negs++;
+            if (element.fromY > element.toY) negs++;
+            if (element.fromZ > element.toZ) negs++;
+            this.flip = (negs & 0b1) != 0;
 
             if (element.rotation != null && element.rotation.rescale) {
-                float x = (45 - Math.abs(((element.rotation.angle + 360) % 360) - 45))/45f;
+                float x = (45 - Math.abs(((element.rotation.angle + 90) % 90) - 45))/45f;
                 float scalar = MathHelper.sqrt_float(1 + x * x);
 
                 float cx = element.rotation.originX * BLOCKS_PER_UNIT;
@@ -173,42 +183,42 @@ public class CompiledBlockModelMojangData {
 
                 switch (element.rotation.axis) {
                     case X:
-                        minX = element.fromX * BLOCKS_PER_UNIT;
-                        minY = (((element.fromY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
-                        minZ = (((element.fromZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
+                        this.minX = element.fromX * BLOCKS_PER_UNIT;
+                        this.minY = (((element.fromY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
+                        this.minZ = (((element.fromZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
 
-                        maxX = element.toX * BLOCKS_PER_UNIT;
-                        maxY = (((element.toY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
-                        maxZ = (((element.toZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
+                        this.maxX = element.toX * BLOCKS_PER_UNIT;
+                        this.maxY = (((element.toY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
+                        this.maxZ = (((element.toZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
                         break;
                     case Y:
-                        minY = element.fromY * BLOCKS_PER_UNIT;
-                        minX = (((element.fromX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
-                        minZ = (((element.fromZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
+                        this.minY = element.fromY * BLOCKS_PER_UNIT;
+                        this.minX = (((element.fromX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
+                        this.minZ = (((element.fromZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
 
-                        maxY = element.toY * BLOCKS_PER_UNIT;
-                        maxX = (((element.toX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
-                        maxZ = (((element.toZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
+                        this.maxY = element.toY * BLOCKS_PER_UNIT;
+                        this.maxX = (((element.toX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
+                        this.maxZ = (((element.toZ * BLOCKS_PER_UNIT) - cz) * scalar) + cz;
                         break;
                     case Z:
                     default:
-                        minZ = element.fromZ * BLOCKS_PER_UNIT;
-                        minX = (((element.fromX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
-                        minY = (((element.fromY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
+                        this.minZ = element.fromZ * BLOCKS_PER_UNIT;
+                        this.minX = (((element.fromX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
+                        this.minY = (((element.fromY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
 
-                        maxZ = element.toZ * BLOCKS_PER_UNIT;
-                        maxX = (((element.toX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
-                        maxY = (((element.toY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
+                        this.maxZ = element.toZ * BLOCKS_PER_UNIT;
+                        this.maxX = (((element.toX * BLOCKS_PER_UNIT) - cx) * scalar) + cx;
+                        this.maxY = (((element.toY * BLOCKS_PER_UNIT) - cy) * scalar) + cy;
                         break;
                 }
             } else {
-                minX = element.fromX * BLOCKS_PER_UNIT;
-                minY = element.fromY * BLOCKS_PER_UNIT;
-                minZ = element.fromZ * BLOCKS_PER_UNIT;
+                this.minX = element.fromX * BLOCKS_PER_UNIT;
+                this.minY = element.fromY * BLOCKS_PER_UNIT;
+                this.minZ = element.fromZ * BLOCKS_PER_UNIT;
 
-                maxX = element.toX * BLOCKS_PER_UNIT;
-                maxY = element.toY * BLOCKS_PER_UNIT;
-                maxZ = element.toZ * BLOCKS_PER_UNIT;
+                this.maxX = element.toX * BLOCKS_PER_UNIT;
+                this.maxY = element.toY * BLOCKS_PER_UNIT;
+                this.maxZ = element.toZ * BLOCKS_PER_UNIT;
             }
 
 
@@ -223,227 +233,170 @@ public class CompiledBlockModelMojangData {
                 float minV = f.v1 * BLOCKS_PER_UNIT;
                 float maxV = f.v2 * BLOCKS_PER_UNIT;
 
-                tintIndices[i] = f.tintIndex;
-                cullfaces[i] = f.cullFace;
-                directions[i] = d;
-                textures[i] = f.texture;
-                int offset = i * 4 * FLOATS_PER_VERTEX;
-                int rot = 4 - f.rotation;
+                this.tintIndices[i] = f.tintIndex;
+                this.cullfaces[i] = f.cullFace;
+                this.directions[i] = d;
+                this.textures[i] = data.textures.getOrDefault(f.texture, BlockModelStandard.BLOCK_TEXTURE_UNASSIGNED);
+                int vertexIndex = i * 4;
+                int rot = 4 - (f.rotation / 90);
                 switch (d) {
                     case UP:
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
+                        this.faceUps[i] = new Vector3f(0, 0, 1);
+                        this.faceLefts[i] = new Vector3f(1, 0, 0);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_LEFT] = new Vector3d(this.maxX, this.maxY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_LEFT + rot) & 0b11)] = new Vector2f(maxU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_RIGHT] = new Vector3d(this.minX, this.maxY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_RIGHT + rot) & 0b11)] = new Vector2f(minU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_RIGHT] = new Vector3d(this.minX, this.maxY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_RIGHT + rot) & 0b11)] = new Vector2f(minU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_LEFT] = new Vector3d(this.maxX, this.maxY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_LEFT + rot) & 0b11)] = new Vector2f(maxU, minV);
                         break;
                     case DOWN:
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
+                        this.faceUps[i] = new Vector3f(0, 0, 1);
+                        this.faceLefts[i] = new Vector3f(-1, 0, 0);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_LEFT] = new Vector3d(this.minX, this.minY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_LEFT + rot) & 0b11)] = new Vector2f(minU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_RIGHT] = new Vector3d(this.maxX, this.minY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_RIGHT + rot) & 0b11)] = new Vector2f(maxU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_RIGHT] = new Vector3d(this.maxX, this.minY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_RIGHT + rot) & 0b11)] = new Vector2f(maxU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_LEFT] = new Vector3d(this.minX, this.minY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_LEFT + rot) & 0b11)] = new Vector2f(minU, maxV);
                         break;
                     case NORTH:
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
+                        this.faceUps[i] = new Vector3f(-1, 0, 0);
+                        this.faceLefts[i] = new Vector3f(0, 1, 0);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_LEFT] = new Vector3d(this.minX, this.maxY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_LEFT + rot) & 0b11)] = new Vector2f(maxU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_RIGHT] = new Vector3d(this.minX, this.minY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_RIGHT + rot) & 0b11)] = new Vector2f(maxU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_RIGHT] = new Vector3d(this.maxX, this.minY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_RIGHT + rot) & 0b11)] = new Vector2f(minU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_LEFT] = new Vector3d(this.maxX, this.maxY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_LEFT + rot) & 0b11)] = new Vector2f(minU, minV);
                         break;
                     case SOUTH:
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
+                        this.faceUps[i] = new Vector3f(0, 1, 0);
+                        this.faceLefts[i] = new Vector3f(-1, 0, 0);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_LEFT] = new Vector3d(this.minX, this.maxY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_LEFT + rot) & 0b11)] = new Vector2f(minU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_RIGHT] = new Vector3d(this.maxX, this.maxY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_RIGHT + rot) & 0b11)] = new Vector2f(maxU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_RIGHT] = new Vector3d(this.maxX, this.minY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_RIGHT + rot) & 0b11)] = new Vector2f(maxU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_LEFT] = new Vector3d(this.minX, this.minY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_LEFT + rot) & 0b11)] = new Vector2f(minU, maxV);
                         break;
                     case WEST:
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = minX;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
+                        this.faceUps[i] = new Vector3f(0, 0, 1);
+                        this.faceLefts[i] = new Vector3f(0, 1, 0);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_LEFT] = new Vector3d(this.minX, this.maxY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_LEFT + rot) & 0b11)] = new Vector2f(maxU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_RIGHT] = new Vector3d(this.minX, this.minY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_RIGHT + rot) & 0b11)] = new Vector2f(maxU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_RIGHT] = new Vector3d(this.minX, this.minY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_RIGHT + rot) & 0b11)] = new Vector2f(minU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_LEFT] = new Vector3d(this.minX, this.maxY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_LEFT + rot) & 0b11)] = new Vector2f(minU, minV);
                         break;
                     case EAST:
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_TOP_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_TOP_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
-
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = maxZ;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = minU;
-                        vertexData[offset + ((VERTEX_TOP_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = maxY;
-                        vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_BOTTOM_RIGHT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = minV;
-
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] = maxX;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] = minY;
-                        vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] = minZ;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_U] = maxU;
-                        vertexData[offset + ((VERTEX_BOTTOM_LEFT + rot) % 4 * FLOATS_PER_VERTEX) + VERTEX_FLOAT_V] = maxV;
+                        this.faceUps[i] = new Vector3f(0, 0, 1);
+                        this.faceLefts[i] = new Vector3f(0, -1, 0);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_LEFT] = new Vector3d(this.maxX, this.minY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_LEFT + rot) & 0b11)] = new Vector2f(minU, maxV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_TOP_RIGHT] = new Vector3d(this.maxX, this.maxY, this.maxZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_TOP_RIGHT + rot) & 0b11)] = new Vector2f(minU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_RIGHT] = new Vector3d(this.maxX, this.maxY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_RIGHT + rot) & 0b11)] = new Vector2f(maxU, minV);
+
+                        this.vertexPoses[vertexIndex + VERTEX_BOTTOM_LEFT] = new Vector3d(this.maxX, this.minY, this.minZ);
+                        this.vertexUvs[vertexIndex + ((VERTEX_BOTTOM_LEFT + rot) & 0b11)] = new Vector2f(maxU, maxV);
                         break;
                 }
                 i++;
             }
 
+            for (int f = 0; f < this.faces; f++) {
+                int offset = f * 4;
+                Vector3dc br = this.vertexPoses[offset + VERTEX_BOTTOM_RIGHT];
+                Vector3dc bl = this.vertexPoses[offset + VERTEX_BOTTOM_LEFT];
+                Vector3dc tr = this.vertexPoses[offset + VERTEX_TOP_RIGHT];
+
+                Vector3d a = br.sub(bl, new Vector3d());
+                Vector3d b = tr.sub(bl, new Vector3d());
+
+                this.faceNormals[f] = new Vector3f(a.cross(b, new Vector3d())).normalize();
+            }
+
             if (element.rotation != null) {
-                for (int f = 0; f < faces; f++) {
+                for (int f = 0; f < this.faces; f++) {
                     for (int v = 0; v < 4; v++) {
-                        final int offset = f * 4 * FLOATS_PER_VERTEX + v * FLOATS_PER_VERTEX;
-                        final float x = vertexData[offset + VERTEX_FLOAT_X] - element.rotation.originX * BLOCKS_PER_UNIT;
-                        final float y = vertexData[offset + VERTEX_FLOAT_Y] - element.rotation.originY * BLOCKS_PER_UNIT;
-                        final float z = vertexData[offset + VERTEX_FLOAT_Z] - element.rotation.originZ * BLOCKS_PER_UNIT;
-                        final float nx;
-                        final float ny;
-                        final float nz;
-                        final float sin = MathHelper.sin(MathHelper.toRadians(element.rotation.angle));
-                        final float cos = MathHelper.cos(MathHelper.toRadians(element.rotation.angle));
+                        final int offset = f * 4 + v;
                         switch (element.rotation.axis) {
                             case X:
-                                nx = x;
-                                ny = y * cos - z * sin;
-                                nz = z * cos + y * sin;
+                                this.vertexPoses[offset] = this.vertexPoses[offset]
+                                    .sub(element.rotation.originX * BLOCKS_PER_UNIT, element.rotation.originY * BLOCKS_PER_UNIT, element.rotation.originZ * BLOCKS_PER_UNIT, new Vector3d())
+                                    .rotateX(MathHelper.toRadians(element.rotation.angle))
+                                    .add(element.rotation.originX * BLOCKS_PER_UNIT, element.rotation.originY * BLOCKS_PER_UNIT, element.rotation.originZ * BLOCKS_PER_UNIT);
                                 break;
                             case Y:
-                                nx = x * cos - z * sin;
-                                ny = y;
-                                nz = z * cos + x * sin;
+                                this.vertexPoses[offset] = this.vertexPoses[offset]
+                                    .sub(element.rotation.originX * BLOCKS_PER_UNIT, element.rotation.originY * BLOCKS_PER_UNIT, element.rotation.originZ * BLOCKS_PER_UNIT, new Vector3d())
+                                    .rotateY(MathHelper.toRadians(element.rotation.angle))
+                                    .add(element.rotation.originX * BLOCKS_PER_UNIT, element.rotation.originY * BLOCKS_PER_UNIT, element.rotation.originZ * BLOCKS_PER_UNIT);
                                 break;
                             case Z:
                             default:
-                                nx = x * cos - y * sin;
-                                ny = y * cos + x * sin;
-                                nz = z;
+                                this.vertexPoses[offset] = this.vertexPoses[offset]
+                                    .sub(element.rotation.originX * BLOCKS_PER_UNIT, element.rotation.originY * BLOCKS_PER_UNIT, element.rotation.originZ * BLOCKS_PER_UNIT, new Vector3d())
+                                    .rotateZ(MathHelper.toRadians(element.rotation.angle))
+                                    .add(element.rotation.originX * BLOCKS_PER_UNIT, element.rotation.originY * BLOCKS_PER_UNIT, element.rotation.originZ * BLOCKS_PER_UNIT);
                                 break;
                         }
-                        vertexData[offset + VERTEX_FLOAT_X] = nx + element.rotation.originX * BLOCKS_PER_UNIT;
-                        vertexData[offset + VERTEX_FLOAT_Y] = ny + element.rotation.originY * BLOCKS_PER_UNIT;
-                        vertexData[offset + VERTEX_FLOAT_Z] = nz + element.rotation.originZ * BLOCKS_PER_UNIT;
                     }
-                }
-            }
-
-            for (int f = 0; f < faces; f++) {
-                int offset = f * 4 * FLOATS_PER_VERTEX;
-                float ax = vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] - vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X];
-                float ay = vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] - vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y];
-                float az = vertexData[offset + (VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] - vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z];
-
-                float bx = vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X] - vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_X];
-                float by = vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y] - vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Y];
-                float bz = vertexData[offset + (VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z] - vertexData[offset + (VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX) + VERTEX_FLOAT_Z];
-
-                float nx = (ay * bz) - (az * by);
-                float ny = (az * bx) - (ax * bz);
-                float nz = (ax * by) - (ay * bx);
-
-                float length = MathHelper.sqrt_float(nx * nx + ny * ny + nz * nz);
-
-                nx /= length;
-                ny /= length;
-                nz /= length;
 
-                normalData[f * FLOATS_PER_NORMAL + NORMAL_FLOAT_X] = nx;
-                normalData[f * FLOATS_PER_NORMAL + NORMAL_FLOAT_Y] = ny;
-                normalData[f * FLOATS_PER_NORMAL + NORMAL_FLOAT_Z] = nz;
+                    switch (element.rotation.axis) {
+                        case X -> {
+                            this.faceUps[f] = this.faceUps[f].rotateX(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                            this.faceLefts[f] = this.faceLefts[f].rotateX(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                            this.faceNormals[f] = this.faceNormals[f].rotateX(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                        }
+                        case Y -> {
+                            this.faceUps[f] = this.faceUps[f].rotateY(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                            this.faceLefts[f] = this.faceLefts[f].rotateY(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                            this.faceNormals[f] = this.faceNormals[f].rotateY(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                        }
+                        case Z -> {
+                            this.faceUps[f] = this.faceUps[f].rotateZ(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                            this.faceLefts[f] = this.faceLefts[f].rotateZ(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                            this.faceNormals[f] = this.faceNormals[f].rotateZ(org.joml.Math.toRadians(element.rotation.angle), new Vector3f());
+                        }
+                    }
+                }
             }
         }
     }
diff --git a/game/client/src/main/java/org/useless/dragonfly/models/block/StaticBlockModel.java b/game/client/src/main/java/org/useless/dragonfly/models/block/StaticBlockModel.java
index 09ad1bf82..3186374da 100644
--- a/game/client/src/main/java/org/useless/dragonfly/models/block/StaticBlockModel.java
+++ b/game/client/src/main/java/org/useless/dragonfly/models/block/StaticBlockModel.java
@@ -1,12 +1,13 @@
 package org.useless.dragonfly.models.block;
 
 import net.minecraft.client.render.block.color.BlockColor;
-import net.minecraft.client.render.block.model.BlockModel;
+import net.minecraft.client.render.block.model.generic.BlockModelGeneric;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.core.block.BlockLogic;
 import net.minecraft.core.util.helper.Side;
 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.DisplayPos;
@@ -16,12 +17,12 @@ public interface StaticBlockModel {
     /**
      * @return True if anything rendered, false otherwise
      */
-    boolean renderStandalone(@NotNull BlockModel<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, double x, double y, double z, int metadata, @NotNull BlockColor color);
+    boolean renderStandalone(@NotNull BlockModelGeneric<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, double x, double y, double z, int metadata, int lightmapCoord, @NotNull BlockColor color);
 
     /**
      * @return True if anything rendered, false otherwise
      */
-    boolean renderAttached(@NotNull BlockModel<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, int x, int y, int z, double xOff, double yOff, double zOff, boolean cullFaces, @Nullable IconCoordinate overrideTexture);
+    boolean renderAttached(@NotNull BlockModelGeneric<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc blockPos, int rotX, int rotY, int rotZ, double xOff, double yOff, double zOff, boolean uvlock, boolean cullFaces, @Nullable IconCoordinate overrideTexture);
 
     /**
      * @return Block texture to overlay when inside a block
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 057e81576..7aa17e976 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
@@ -5,18 +5,28 @@ import net.minecraft.client.render.LightingCache;
 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.BlockModel;
-import net.minecraft.client.render.block.model.BlockModelStandard;
+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;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 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.Vector2f;
+import org.joml.Vector2fc;
+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;
@@ -26,145 +36,211 @@ import org.useless.dragonfly.models.block.StaticBlockModel;
 import java.util.Locale;
 
 import static net.minecraft.client.render.block.model.BlockModel.FULL_CUBE_THRESHOLD;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.FLOATS_PER_NORMAL;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.FLOATS_PER_VERTEX;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.NORMAL_FLOAT_X;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.NORMAL_FLOAT_Y;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.NORMAL_FLOAT_Z;
 import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_BOTTOM_LEFT;
 import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_BOTTOM_RIGHT;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_FLOAT_U;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_FLOAT_V;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_FLOAT_X;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_FLOAT_Y;
-import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_FLOAT_Z;
+import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_TOP_LEFT;
 import static org.useless.dragonfly.data.block.mojang.CompiledBlockModelMojangData.C_Element.VERTEX_TOP_RIGHT;
 
 public class StaticBlockModelMojang implements StaticBlockModel {
     protected static final Minecraft MC = Minecraft.getMinecraft();
     protected static final LightingCache LIGHTING_CACHE = new LightingCache();
 
-    protected static final byte[] V_TOP_X = new byte[]{0, 0, -1, 0, 0, 0};
-    protected static final byte[] V_TOP_Y = new byte[]{0, 0, 0, 1, 0, 0};
-    protected static final byte[] V_TOP_Z = new byte[]{1, 1, 0, 0, 1, 1};
+    protected final @NotNull CompiledBlockModelMojangData compiled;
 
-    protected static final byte[] V_LEF_X = new byte[]{-1, 1, 0, -1, 0, 0};
-    protected static final byte[] V_LEF_Y = new byte[]{0, 0, 1, 0, 1, -1};
-    protected static final byte[] V_LEF_Z = new byte[]{0, 0, 0, 0, 0, 0};
-
-    protected final CompiledBlockModelMojangData compiled;
-
-    public StaticBlockModelMojang(BlockModelMojangData data) {
+    public StaticBlockModelMojang(@NotNull BlockModelMojangData data) {
         this.compiled = new CompiledBlockModelMojangData(data);
     }
 
     @Override
-    public boolean renderStandalone(@NotNull BlockModel<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, double x, double y, double z, int metadata, @NotNull BlockColor color) {
+    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];
 
-            GLRenderer.globalSetLightEnabled(element.shade);
-
-            tessellator.startDrawingQuads();
+            tessellator.setColor1i(0xFFFFFFFF);
+            tessellator.setLightmapCoord1i(lightmapCoord);
             for (int face = 0; face < element.faces; face++) {
-                IconCoordinate coordinate = this.compiled.textures.getOrDefault(element.textures[face], BlockModelStandard.BLOCK_TEXTURE_UNASSIGNED);
+                IconCoordinate coordinate = element.textures[face];
 
-                GLRenderer.setLightmapCoord2i(15, 15);
                 if (element.tintIndices[face] >= 0) {
                     tessellator.setColor1i(color.getFallbackColor(metadata, element.tintIndices[face]));
+                } else {
+                    tessellator.setColor1i(0xFFFFFFFF);
                 }
 
-                final int offset = face * 4 * FLOATS_PER_VERTEX;
+                final int offset = face * 4;
                 for (int v = 0; v < 4; v++) {
-                    tessellator.setNormal(element.normalData[face * FLOATS_PER_NORMAL + NORMAL_FLOAT_X], element.normalData[face * FLOATS_PER_NORMAL + NORMAL_FLOAT_Y], element.normalData[face * FLOATS_PER_NORMAL + NORMAL_FLOAT_Z]);
+                    if (element.shade) {
+                        Vector3fc normal = element.faceNormals[face];
+                        tessellator.setNormal(normal.x(), normal.y(), normal.z());
+                    } else {
+                        tessellator.setNormal(0, 1, 0);
+                    }
+                    Vector3dc pos = element.vertexPoses[offset + v];
+                    Vector2fc uvs = element.vertexUvs[offset + v];
                     tessellator.addVertexWithUV(
-                        element.vertexData[offset + v * FLOATS_PER_VERTEX + VERTEX_FLOAT_X] - 0.5f,
-                        element.vertexData[offset + v * FLOATS_PER_VERTEX + VERTEX_FLOAT_Y] - 0.5f,
-                        element.vertexData[offset + v * FLOATS_PER_VERTEX + VERTEX_FLOAT_Z] - 0.5f,
-                        coordinate.getSubIconU(element.vertexData[offset + v * FLOATS_PER_VERTEX + VERTEX_FLOAT_U]),
-                        coordinate.getSubIconV(element.vertexData[offset + v * FLOATS_PER_VERTEX + VERTEX_FLOAT_V]));
+                        pos.x() - 0.5f,
+                        pos.y() - 0.5f,
+                        pos.z() - 0.5f,
+                        coordinate.getSubIconU(uvs.x()),
+                        coordinate.getSubIconV(uvs.y()));
                 }
             }
-            tessellator.draw();
         }
+        tessellator.draw();
         GLRenderer.popFrame();
         return true;
     }
 
     @Override
-    public boolean renderAttached(@NotNull BlockModel<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, int x, int y, int z, double xOff, double yOff, double zOff, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
+    public boolean renderAttached(@NotNull BlockModelGeneric<? extends BlockLogic> sourceModel, @NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc blockPos, int rotX, int rotY, int rotZ, double xOff, double yOff, double zOff, boolean uvlock, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
         if (this.compiled.elements.length == 0) return false;
         boolean didRender = false;
-        LIGHTING_CACHE.setupCache(sourceModel.block, worldSource, x, y, z);
+        LIGHTING_CACHE.setupCache(sourceModel.block, worldSource, blockPos);
+        byte cullCache = 0;
 
         BlockColor color = BlockColorDispatcher.getInstance().getDispatch(sourceModel.block);
         for (int i = 0; i < this.compiled.elements.length; i++) {
             final C_Element element = this.compiled.elements[i];
             for (int face = 0; face < element.faces; face++) {
-                if (cullFaces && cullSide(worldSource, x, y, z, element.cullfaces[face])) continue;
-                final IconCoordinate coordinate = overrideTexture == null ? this.compiled.textures.getOrDefault(element.textures[face], BlockModelStandard.BLOCK_TEXTURE_UNASSIGNED) : overrideTexture;
-                final Direction direction = element.directions[face];
+                Direction cullDir = element.cullfaces[face];
+                if (cullFaces && cullDir != null) {
+                    cullDir = Direction.rotateZ(Direction.rotateY(Direction.rotateX(element.cullfaces[face], rotX), rotY), rotZ);
+                    if ((cullCache & (1 << cullDir.getId())) != 0) {
+                        continue;
+                    }
+                    if (sourceModel.cullSide(worldSource, blockPos, cullDir)) {
+                        cullCache |= (byte) (1 << cullDir.getId());
+                        continue;
+                    }
+                }
+                final IconCoordinate coordinate = overrideTexture == null ? element.textures[face] : overrideTexture;
+                Direction direction = Direction.rotateZ(Direction.rotateY(Direction.rotateX(element.directions[face], rotX), rotY), rotZ);
 
                 final float minBrightness = element.lightEmission / 15f;
 
-                final int topX = V_TOP_X[direction.getId()];
-                final int topY = V_TOP_Y[direction.getId()];
-                final int topZ = V_TOP_Z[direction.getId()];
-                final float topP;
-                final float botP;
-                final int lefX = V_LEF_X[direction.getId()];
-                final int lefY = V_LEF_Y[direction.getId()];
-                final int lefZ = V_LEF_Z[direction.getId()];
-                final float lefP;
-                final float rigP;
-                final float depth;
-                switch (direction) {
-                    case DOWN:
-                        depth = 0 + element.minY;
-                        topP = element.maxZ;
-                        botP = element.minZ;
-                        lefP = 1 - element.minX;
-                        rigP = 1 - element.maxX;
-                        break;
-                    case UP:
-                        depth = 1 - element.maxY;
-                        topP = element.maxZ;
-                        botP = element.minZ;
-                        lefP = element.maxX;
-                        rigP = element.minX;
-                        break;
-                    case NORTH:
-                        depth = 0 + element.minZ;
-                        topP = 1 - element.minX;
-                        botP = 1 - element.maxX;
-                        lefP = element.maxY;
-                        rigP = element.minY;
-                        break;
-                    case SOUTH:
-                        depth = 1 - element.maxZ;
-                        topP = element.maxY;
-                        botP = element.minY;
-                        lefP = 1 - element.minX;
-                        rigP = 1 - element.maxX;
-                        break;
-                    case WEST:
-                        depth = 0 + element.minX;
-                        topP = element.maxZ;
-                        botP = element.minZ;
-                        lefP = element.maxY;
-                        rigP = element.minY;
-                        break;
-                    case EAST:
-                    default:
-                        depth = 1 - element.maxX;
-                        topP = element.maxZ;
-                        botP = element.minZ;
-                        lefP = 1 - element.minY;
-                        rigP = 1 - element.maxY;
-                        break;
+                Vector3f q = new Vector3f();
+                final Vector3f top = q.set(element.faceUps[face]);
+                if (rotX != 0) { top.rotateX(rotX * org.joml.Math.PI_OVER_2_f); }
+                if (rotY != 0) { top.rotateY(rotY * org.joml.Math.PI_OVER_2_f); }
+                if (rotZ != 0) { top.rotateZ(rotZ * org.joml.Math.PI_OVER_2_f); }
+                final int topX = org.joml.Math.round(top.x());
+                final int topY = org.joml.Math.round(top.y());
+                final int topZ = org.joml.Math.round(top.z());
+                float topP;
+                float botP;
+
+                final Vector3f left = q.set(element.faceLefts[face]);
+                if (rotX != 0) { left.rotateX(rotX * org.joml.Math.PI_OVER_2_f); }
+                if (rotY != 0) { left.rotateY(rotY * org.joml.Math.PI_OVER_2_f); }
+                if (rotZ != 0) { left.rotateZ(rotZ * org.joml.Math.PI_OVER_2_f); }
+                final int lefX = org.joml.Math.round(left.x());
+                final int lefY = org.joml.Math.round(left.y());
+                final int lefZ = org.joml.Math.round(left.z());
+                float lefP;
+                float rigP;
+                float depth;
+                if (element.flip) {
+                    switch (element.directions[face]) {
+                        case DOWN:
+                            depth = 1 - element.minY;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = 1 - element.minX;
+                            rigP = 1 - element.maxX;
+                            break;
+                        case UP:
+                            depth = 0 + element.maxY;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = element.maxX;
+                            rigP = element.minX;
+                            break;
+                        case NORTH:
+                            depth = 1 - element.minZ;
+                            topP = 1 - element.minX;
+                            botP = 1 - element.maxX;
+                            lefP = element.maxY;
+                            rigP = element.minY;
+                            break;
+                        case SOUTH:
+                            depth = 0 + element.maxZ;
+                            topP = element.maxY;
+                            botP = element.minY;
+                            lefP = 1 - element.minX;
+                            rigP = 1 - element.maxX;
+                            break;
+                        case WEST:
+                            depth = 1 - element.maxX;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = element.maxY;
+                            rigP = element.minY;
+                            break;
+                        case EAST:
+                        default:
+                            depth = 0 + element.minX;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = 1 - element.minY;
+                            rigP = 1 - element.maxY;
+                            break;
+                    }
+                } else {
+                    switch (element.directions[face]) {
+                        case DOWN:
+                            depth = 0 + element.minY;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = 1 - element.minX;
+                            rigP = 1 - element.maxX;
+                            break;
+                        case UP:
+                            depth = 1 - element.maxY;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = element.maxX;
+                            rigP = element.minX;
+                            break;
+                        case NORTH:
+                            depth = 0 + element.minZ;
+                            topP = 1 - element.minX;
+                            botP = 1 - element.maxX;
+                            lefP = element.maxY;
+                            rigP = element.minY;
+                            break;
+                        case SOUTH:
+                            depth = 1 - element.maxZ;
+                            topP = element.maxY;
+                            botP = element.minY;
+                            lefP = 1 - element.minX;
+                            rigP = 1 - element.maxX;
+                            break;
+                        case WEST:
+                            depth = 0 + element.minX;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = element.maxY;
+                            rigP = element.minY;
+                            break;
+                        case EAST:
+                        default:
+                            depth = 1 - element.maxX;
+                            topP = element.maxZ;
+                            botP = element.minZ;
+                            lefP = 1 - element.minY;
+                            rigP = 1 - element.maxY;
+                            break;
+                    }
                 }
 
                 final boolean useAO = this.compiled.data.ambientOcclusion && MC.isAmbientOcclusionEnabled() && element.shade;
@@ -174,7 +250,7 @@ public class StaticBlockModelMojang implements StaticBlockModel {
                 final float g;
                 final float b;
                 if (element.tintIndices[face] >= 0) {
-                    int c = color.getWorldColor(worldSource, x, y, z, element.tintIndices[face]);
+                    int c = color.getWorldColor(worldSource, blockPos, element.tintIndices[face]);
                     r = Color.redFromInt(c) / 255f;
                     g = Color.greenFromInt(c) / 255f;
                     b = Color.blueFromInt(c) / 255f;
@@ -184,9 +260,9 @@ public class StaticBlockModelMojang implements StaticBlockModel {
                     b = 1;
                 }
 
-                final int dirX = direction.getOffsetX();
-                final int dirY = direction.getOffsetY();
-                final int dirZ = direction.getOffsetZ();
+                final int dirX = element.flip ? -direction.getOffsetX() : direction.getOffsetX();
+                final int dirY = element.flip ? -direction.getOffsetY() : direction.getOffsetY();
+                final int dirZ = element.flip ? -direction.getOffsetZ() : direction.getOffsetZ();
 
                 final int lightmapCoordTopLeft;
                 final int lightmapCoordBottomLeft;
@@ -343,44 +419,96 @@ public class StaticBlockModelMojang implements StaticBlockModel {
                 colorGreenTopRight *= ltr;
                 colorBlueTopRight *= ltr;
 
-                final int offset = face * 4 * FLOATS_PER_VERTEX;
+                final int offset = face * 4;
 
-                tessellator.setNormal(direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ());
+                Vector3f norm = q.set(element.faceNormals[face]);
+                if (rotX != 0) { norm.rotateX(rotX * org.joml.Math.PI_OVER_2_f); }
+                if (rotY != 0) { norm.rotateY(rotY * org.joml.Math.PI_OVER_2_f); }
+                if (rotZ != 0) { norm.rotateZ(rotZ * org.joml.Math.PI_OVER_2_f); }
+
+                if (element.shade) {
+                    tessellator.setNormal(norm.x(), norm.y(), norm.z());
+                } else {
+                    tessellator.setNormal(0, 1, 0);
+                }
+
+                Vector3d v = new Vector3d();
+
+                Vector3d posTL = v.set(element.vertexPoses[offset + VERTEX_TOP_LEFT]);
+                if (rotX != 0 || rotY != 0 || rotZ != 0) {
+                    posTL.sub(0.5, 0.5, 0.5)
+                        .rotateX(rotX * org.joml.Math.PI_OVER_2)
+                        .rotateY(rotY * org.joml.Math.PI_OVER_2)
+                        .rotateZ(rotZ * org.joml.Math.PI_OVER_2)
+                        .add(0.5, 0.5, 0.5);
+                }
+                Vector2fc uvsTL = element.vertexUvs[offset + VERTEX_TOP_LEFT];
+                if (uvlock) uvsTL = rotateUV(uvsTL, rotX, rotY, rotZ, element.directions[face], new Vector2f());
                 tessellator.setColorOpaque3f(colorRedTopLeft, colorGreenTopLeft, colorBlueTopLeft);
                 tessellator.setLightmapCoord1i(lightmapCoordTopLeft);
                 tessellator.addVertexWithUV(
-                    element.vertexData[offset + VERTEX_FLOAT_X] + x + xOff,
-                    element.vertexData[offset + VERTEX_FLOAT_Y] + y + yOff,
-                    element.vertexData[offset + VERTEX_FLOAT_Z] + z + zOff,
-                    coordinate.getSubIconU(element.vertexData[offset + VERTEX_FLOAT_U]),
-                    coordinate.getSubIconV(element.vertexData[offset + VERTEX_FLOAT_V]));
-
+                    posTL.x() + blockPos.x() + xOff,
+                    posTL.y() + blockPos.y() + yOff,
+                    posTL.z() + blockPos.z() + zOff,
+                    coordinate.getSubIconU(uvsTL.x()),
+                    coordinate.getSubIconV(uvsTL.y()));
+
+                Vector3d posBL = v.set(element.vertexPoses[offset + VERTEX_BOTTOM_LEFT]);
+                if (rotX != 0 || rotY != 0 || rotZ != 0) {
+                    posBL.sub(0.5, 0.5, 0.5)
+                        .rotateX(rotX * org.joml.Math.PI_OVER_2)
+                        .rotateY(rotY * org.joml.Math.PI_OVER_2)
+                        .rotateZ(rotZ * org.joml.Math.PI_OVER_2)
+                        .add(0.5, 0.5, 0.5);
+                }
+                Vector2fc uvsBL = element.vertexUvs[offset + VERTEX_BOTTOM_LEFT];
+                if (uvlock) uvsBL = rotateUV(uvsBL, rotX, rotY, rotZ, element.directions[face], new Vector2f());
                 tessellator.setColorOpaque3f(colorRedBottomLeft, colorGreenBottomLeft, colorBlueBottomLeft);
                 tessellator.setLightmapCoord1i(lightmapCoordBottomLeft);
                 tessellator.addVertexWithUV(
-                    element.vertexData[offset + VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX + VERTEX_FLOAT_X] + x + xOff,
-                    element.vertexData[offset + VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX + VERTEX_FLOAT_Y] + y + yOff,
-                    element.vertexData[offset + VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX + VERTEX_FLOAT_Z] + z + zOff,
-                    coordinate.getSubIconU(element.vertexData[offset + VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX + VERTEX_FLOAT_U]),
-                    coordinate.getSubIconV(element.vertexData[offset + VERTEX_BOTTOM_LEFT * FLOATS_PER_VERTEX + VERTEX_FLOAT_V]));
-
+                    posBL.x() + blockPos.x() + xOff,
+                    posBL.y() + blockPos.y() + yOff,
+                    posBL.z() + blockPos.z() + zOff,
+                    coordinate.getSubIconU(uvsBL.x()),
+                    coordinate.getSubIconV(uvsBL.y()));
+
+                Vector3d posBR = v.set(element.vertexPoses[offset + VERTEX_BOTTOM_RIGHT]);
+                if (rotX != 0 || rotY != 0 || rotZ != 0) {
+                    posBR.sub(0.5, 0.5, 0.5)
+                        .rotateX(rotX * org.joml.Math.PI_OVER_2)
+                        .rotateY(rotY * org.joml.Math.PI_OVER_2)
+                        .rotateZ(rotZ * org.joml.Math.PI_OVER_2)
+                        .add(0.5, 0.5, 0.5);
+                }
+                Vector2fc uvsBR = element.vertexUvs[offset + VERTEX_BOTTOM_RIGHT];
+                if (uvlock) uvsBR = rotateUV(uvsBR, rotX, rotY, rotZ, element.directions[face], new Vector2f());
                 tessellator.setColorOpaque3f(colorRedBottomRight, colorGreenBottomRight, colorBlueBottomRight);
                 tessellator.setLightmapCoord1i(lightmapCoordBottomRight);
                 tessellator.addVertexWithUV(
-                    element.vertexData[offset + VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_X] + x + xOff,
-                    element.vertexData[offset + VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_Y] + y + yOff,
-                    element.vertexData[offset + VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_Z] + z + zOff,
-                    coordinate.getSubIconU(element.vertexData[offset + VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_U]),
-                    coordinate.getSubIconV(element.vertexData[offset + VERTEX_BOTTOM_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_V]));
-
+                    posBR.x() + blockPos.x() + xOff,
+                    posBR.y() + blockPos.y() + yOff,
+                    posBR.z() + blockPos.z() + zOff,
+                    coordinate.getSubIconU(uvsBR.x()),
+                    coordinate.getSubIconV(uvsBR.y()));
+
+                Vector3d posTR = v.set(element.vertexPoses[offset + VERTEX_TOP_RIGHT]);
+                if (rotX != 0 || rotY != 0 || rotZ != 0) {
+                    posTR.sub(0.5, 0.5, 0.5)
+                        .rotateX(rotX * org.joml.Math.PI_OVER_2)
+                        .rotateY(rotY * org.joml.Math.PI_OVER_2)
+                        .rotateZ(rotZ * org.joml.Math.PI_OVER_2)
+                        .add(0.5, 0.5, 0.5);
+                }
+                Vector2fc uvsTR = element.vertexUvs[offset + VERTEX_TOP_RIGHT];
+                if (uvlock) uvsTR = rotateUV(uvsTR, rotX, rotY, rotZ, element.directions[face], new Vector2f());
                 tessellator.setColorOpaque3f(colorRedTopRight, colorGreenTopRight, colorBlueTopRight);
                 tessellator.setLightmapCoord1i(lightmapCoordTopRight);
                 tessellator.addVertexWithUV(
-                    element.vertexData[offset + VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_X] + x + xOff,
-                    element.vertexData[offset + VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_Y] + y + yOff,
-                    element.vertexData[offset + VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_Z] + z + zOff,
-                    coordinate.getSubIconU(element.vertexData[offset + VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_U]),
-                    coordinate.getSubIconV(element.vertexData[offset + VERTEX_TOP_RIGHT * FLOATS_PER_VERTEX + VERTEX_FLOAT_V]));
+                    posTR.x() + blockPos.x() + xOff,
+                    posTR.y() + blockPos.y() + yOff,
+                    posTR.z() + blockPos.z() + zOff,
+                    coordinate.getSubIconU(uvsTR.x()),
+                    coordinate.getSubIconV(uvsTR.y()));
 
                 tessellator.setNormal(0, 1, 0);
                 didRender = true;
@@ -389,6 +517,75 @@ public class StaticBlockModelMojang implements StaticBlockModel {
         return didRender;
     }
 
+    public @NotNull Vector2f rotateUV(@NotNull Vector2fc uvs, int rotX, int rotY, int rotZ, @NotNull Direction srcDirection, @NotNull Vector2f dest) {
+        Direction dir = srcDirection;
+        float u = uvs.x() - 0.5f;
+        float v = uvs.y() - 0.5f;
+        rotX = (rotX & 0b11);
+        while (rotX > 0) {
+            if (dir.getAxis() == Axis.X) {
+                if (dir == Direction.WEST) {
+                    float _u = u;
+                    u = -v;
+                    v = _u;
+                } else {
+                    float _u = u;
+                    u = v;
+                    v = -_u;
+                }
+            } else {
+                if (dir == Direction.NORTH || dir == Direction.DOWN) {
+                    v = -v;
+                    u = -u;
+                }
+            }
+            dir = Direction.rotateX(dir, 1);
+            rotX--;
+        }
+
+        rotY = (rotY & 0b11);
+        while (rotY > 0) {
+            if (dir.getAxis() == Axis.Y) {
+                if (dir == Direction.DOWN) {
+                    float _v = v;
+                    v = u;
+                    u = -_v;
+                } else {
+                    float _u = u;
+                    u = v;
+                    v = -_u;
+                }
+            }
+            dir = Direction.rotateY(dir, 1);
+            rotY--;
+        }
+
+        rotZ = (rotZ & 0b11);
+        while (rotZ > 0) {
+            if (dir.getAxis() == Axis.Z) {
+                if (dir == Direction.NORTH) {
+                    float _u = u;
+                    u = -v;
+                    v = _u;
+                } else {
+                    float _u = u;
+                    u = v;
+                    v = -_u;
+                }
+            } else {
+                if (dir == Direction.DOWN || dir == Direction.UP || dir == Direction.WEST || dir == Direction.EAST) {
+                    float _v = v;
+                    v = -u;
+                    u = _v;
+                }
+            }
+            dir = Direction.rotateZ(dir, 1);
+            rotZ--;
+        }
+
+        return dest.set(u + 0.5f, v + 0.5f);
+    }
+
     @Override
     public @Nullable IconCoordinate getOverlay() {
         // This breaks the modern mc format of using the "#particle" symbol for the overlay, but due to our changes to the spec this is the best way of going about it
@@ -415,10 +612,6 @@ public class StaticBlockModelMojang implements StaticBlockModel {
         return this.compiled.displayPosMap.getOrDefault(id, DisplayPos.DEFAULT_DISPLAY_POS);
     }
 
-    protected boolean cullSide(WorldSource worldSource, int x, int y, int z, @Nullable Direction direction) {
-        return direction != null && worldSource.isBlockOpaqueCube(x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ());
-    }
-
     protected float getBrightness(int relX, int relY, int relZ, float min) {
         return Math.max(LIGHTING_CACHE.getBrightness(relX, relY, relZ), min);
     }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/activator_active.json b/game/client/src/main/resources/assets/minecraft/models/block/activator_active.json
new file mode 100644
index 000000000..9c8fa7ed3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/activator_active.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/activator/top_active",
+    "down": "minecraft:block/activator/bottom_active",
+    "south": "minecraft:block/activator/side_active",
+    "north": "minecraft:block/activator/front_active",
+    "west": "minecraft:block/activator/side_active",
+    "east": "minecraft:block/activator/side_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/activator_idle.json b/game/client/src/main/resources/assets/minecraft/models/block/activator_idle.json
new file mode 100644
index 000000000..27baf99d8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/activator_idle.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/activator/top",
+    "down": "minecraft:block/activator/bottom",
+    "south": "minecraft:block/activator/side",
+    "north": "minecraft:block/activator/front",
+    "west": "minecraft:block/activator/side",
+    "east": "minecraft:block/activator/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/algae.json b/game/client/src/main/resources/assets/minecraft/models/block/algae.json
new file mode 100644
index 000000000..16c480c56
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/algae.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"ambientocclusion": false,
+	"parent": "block/block",
+	"textures": {
+		"all": "minecraft:block/algae",
+		"down": "#all",
+		"up": "#all",
+		"north": "#all",
+		"east": "#all",
+		"south": "#all",
+		"west": "#all",
+		"overlay": "#north",
+		"particle_up": "#up",
+		"particle_down": "#down",
+		"particle_north": "#north",
+		"particle_south": "#south",
+		"particle_west": "#west",
+		"particle_east": "#east"
+	},
+	"elements": [
+		{
+			"from": [0, -2.75, 0],
+			"to": [16, -1.75, 16],
+			"shade": false,
+			"faces": {
+				"up": {"uv": [0, 0, 16, 16], "texture": "#all", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/basalt.json
new file mode 100644
index 000000000..707a500f0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/basalt_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/basalt_mossy.json
new file mode 100644
index 000000000..ed392adb9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/basalt_mossy.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/template_mossy",
+  "textures": {
+    "base": "minecraft:block/basalt",
+    "overlay": "minecraft:block/moss_overlay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/basket.json b/game/client/src/main/resources/assets/minecraft/models/block/basket.json
new file mode 100644
index 000000000..0cbec7af1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/basket.json
@@ -0,0 +1,42 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/cube",
+	"textures": {
+		"bottom": "block/basket/bottom",
+		"side": "block/basket/side",
+		"top": "block/basket/top",
+		"down": "#bottom",
+		"up": "#top",
+		"north": "#side",
+		"east": "#side",
+		"south": "#side",
+		"west": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom"}
+			}
+		},
+		{
+			"from": [15, 1, 1],
+			"to": [1, 16, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [15, 1, 1]},
+			"faces": {
+				"north": {"uv": [1, 0, 15, 15], "texture": "#side"},
+				"east": {"uv": [1, 0, 15, 15], "texture": "#side"},
+				"south": {"uv": [1, 0, 15, 15], "texture": "#side"},
+				"west": {"uv": [1, 0, 15, 15], "texture": "#side"},
+				"down": {"uv": [1, 1, 15, 15], "texture": "#bottom"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/basket_fill.json b/game/client/src/main/resources/assets/minecraft/models/block/basket_fill.json
new file mode 100644
index 000000000..e4519752a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/basket_fill.json
@@ -0,0 +1,22 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/cube",
+	"textures": {
+		"down": "#up",
+		"up": "minecraft:block/basket/fill",
+		"north": "#up",
+		"east": "#up",
+		"south": "#up",
+		"west": "#up"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 1, 16],
+			"faces": {
+				"up": {"uv": [0, 0, 16, 16], "texture": "#up"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/bed/foot.json b/game/client/src/main/resources/assets/minecraft/models/block/bed/foot.json
new file mode 100644
index 000000000..d5f89ca50
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/bed/foot.json
@@ -0,0 +1,40 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/bed/bottom",
+		"front": "block/bed/foot_front",
+		"side": "block/bed/foot_side",
+		"top": "block/bed/foot_top",
+		"overlay": "#front",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#front",
+		"particle_east": "#front"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 9, 16],
+			"faces": {
+				"north": {"uv": [16, 7, 0, 16], "texture": "#side", "cullface": "north"},
+				"south": {"uv": [0, 7, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 7, 16, 16], "texture": "#front", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"}
+			}
+		},
+		{
+			"from": [0, 0, 16],
+			"to": [16, 3, 0],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 16]},
+			"faces": {
+				"north": {"uv": [16, 13, 0, 16], "texture": "#side"},
+				"south": {"uv": [0, 13, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 13, 16, 16], "texture": "#front"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#bottom"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/bed/head.json b/game/client/src/main/resources/assets/minecraft/models/block/bed/head.json
new file mode 100644
index 000000000..79b60dc14
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/bed/head.json
@@ -0,0 +1,40 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/bed/bottom",
+		"front": "block/bed/head_front",
+		"side": "block/bed/head_side",
+		"top": "block/bed/head_top",
+		"overlay": "#front",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#front",
+		"particle_east": "#front"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 9, 16],
+			"faces": {
+				"north": {"uv": [16, 7, 0, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 7, 16, 16], "texture": "#front", "cullface": "east"},
+				"south": {"uv": [0, 7, 16, 16], "texture": "#side", "cullface": "south"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"}
+			}
+		},
+		{
+			"from": [0, 0, 16],
+			"to": [16, 3, 0],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 16]},
+			"faces": {
+				"north": {"uv": [16, 13, 0, 16], "texture": "#side"},
+				"east": {"uv": [0, 13, 16, 16], "texture": "#front"},
+				"south": {"uv": [0, 13, 16, 16], "texture": "#side"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#bottom"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/bedrock.json b/game/client/src/main/resources/assets/minecraft/models/block/bedrock.json
new file mode 100644
index 000000000..adc6359e2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/bedrock.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/bedrock"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_ash.json b/game/client/src/main/resources/assets/minecraft/models/block/block_ash.json
new file mode 100644
index 000000000..08dec0eea
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_ash.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_baked_sugarcane.json b/game/client/src/main/resources/assets/minecraft/models/block/block_baked_sugarcane.json
new file mode 100644
index 000000000..96d54ca04
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_baked_sugarcane.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/block_baked_sugarcane/top",
+		"side": "minecraft:block/block_baked_sugarcane/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_charcoal.json b/game/client/src/main/resources/assets/minecraft/models/block/block_charcoal.json
new file mode 100644
index 000000000..7dd278ca8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_charcoal.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_charcoal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_clay.json b/game/client/src/main/resources/assets/minecraft/models/block/block_clay.json
new file mode 100644
index 000000000..604a85374
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_clay.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_clay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_coal.json b/game/client/src/main/resources/assets/minecraft/models/block/block_coal.json
new file mode 100644
index 000000000..aa23af357
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_coal.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_coal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_diamond.json b/game/client/src/main/resources/assets/minecraft/models/block/block_diamond.json
new file mode 100644
index 000000000..5d1090515
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_diamond.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_diamond"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_gold.json b/game/client/src/main/resources/assets/minecraft/models/block/block_gold.json
new file mode 100644
index 000000000..c9eab2485
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_gold.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_gold"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_iron.json b/game/client/src/main/resources/assets/minecraft/models/block/block_iron.json
new file mode 100644
index 000000000..1dab600ab
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_iron.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_iron"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_lapis.json b/game/client/src/main/resources/assets/minecraft/models/block/block_lapis.json
new file mode 100644
index 000000000..da57d97dd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_lapis.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_lapis"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_nethercoal.json b/game/client/src/main/resources/assets/minecraft/models/block/block_nethercoal.json
new file mode 100644
index 000000000..247d22c48
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_nethercoal.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_nethercoal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_olivine.json b/game/client/src/main/resources/assets/minecraft/models/block/block_olivine.json
new file mode 100644
index 000000000..121d7b3ad
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_olivine.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_olivine"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_quartz.json b/game/client/src/main/resources/assets/minecraft/models/block/block_quartz.json
new file mode 100644
index 000000000..cbfcc067c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_quartz.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_quartz"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_redstone.json b/game/client/src/main/resources/assets/minecraft/models/block/block_redstone.json
new file mode 100644
index 000000000..ed24243f6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_redstone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_redstone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_snow.json b/game/client/src/main/resources/assets/minecraft/models/block/block_snow.json
new file mode 100644
index 000000000..c5983ee41
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_snow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_steel.json b/game/client/src/main/resources/assets/minecraft/models/block/block_steel.json
new file mode 100644
index 000000000..87db4b8f0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_steel.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/block_steel"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_sugarcane.json b/game/client/src/main/resources/assets/minecraft/models/block/block_sugarcane.json
new file mode 100644
index 000000000..8a2421818
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_sugarcane.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/block_sugarcane/top",
+		"side": "minecraft:block/block_sugarcane/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/block_thin.json b/game/client/src/main/resources/assets/minecraft/models/block/block_thin.json
new file mode 100644
index 000000000..cc0c24472
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/block_thin.json
@@ -0,0 +1,24 @@
+{   "parent": "block/block",
+    "display": {
+        "gui": {
+            "rotation": [ 30, 225, 0 ],
+            "translation": [ 0, 2, 0],
+            "scale":[ 0.625, 0.625, 0.625 ]
+        },
+        "thirdperson_righthand": {
+            "rotation": [ 75, 45, 0 ],
+            "translation": [ 0, 2.5, 2],
+            "scale": [ 0.375, 0.375, 0.375 ]
+        },
+        "firstperson_righthand": {
+            "rotation": [ 0, 45, 0 ],
+            "translation": [ 0, 4.2, 0 ],
+            "scale": [ 0.40, 0.40, 0.40 ]
+        },
+        "firstperson_lefthand": {
+            "rotation": [ 0, 225, 0 ],
+            "translation": [ 0, 4.2, 0 ],
+            "scale": [ 0.40, 0.40, 0.40 ]
+        }
+    }
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/bone_shale.json b/game/client/src/main/resources/assets/minecraft/models/block/bone_shale.json
new file mode 100644
index 000000000..dc210d620
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/bone_shale.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/bone_shale/top",
+    "bottom": "minecraft:block/bone_shale/bottom",
+    "side": "minecraft:block/bone_shale/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/bookshelf.json b/game/client/src/main/resources/assets/minecraft/models/block/bookshelf.json
new file mode 100644
index 000000000..d75c48d6c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/bookshelf.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/planks/oak",
+		"side": "minecraft:block/bookshelf"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brazier.json b/game/client/src/main/resources/assets/minecraft/models/block/brazier.json
new file mode 100644
index 000000000..4cc81c876
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brazier.json
@@ -0,0 +1,40 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "minecraft:block/block",
+	"textures": {
+		"side": "block/brazier/base",
+		"bottom": "block/brazier/side",
+		"overlay": "#side",
+		"particle_up": "#side",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "west"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		},
+		{
+			"from": [15.95, 0.05, 0.05],
+			"to": [0.05, 15.95, 15.95],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#bottom"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#bottom"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#bottom"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brazier_active.json b/game/client/src/main/resources/assets/minecraft/models/block/brazier_active.json
new file mode 100644
index 000000000..96a8df8b2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brazier_active.json
@@ -0,0 +1,5 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "minecraft:block/brazier"
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_basalt.json
new file mode 100644
index 000000000..740e8547d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_clay.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_clay.json
new file mode 100644
index 000000000..342a0456f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_clay.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_clay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_gold.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_gold.json
new file mode 100644
index 000000000..f6a01a742
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_gold.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_gold"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_granite.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_granite.json
new file mode 100644
index 000000000..58e416df9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_iron.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_iron.json
new file mode 100644
index 000000000..31af403e6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_iron.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_iron"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_lapis.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_lapis.json
new file mode 100644
index 000000000..dc2e8d6f8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_lapis.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_lapis"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_limestone.json
new file mode 100644
index 000000000..77da88fc4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_marble.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_marble.json
new file mode 100644
index 000000000..e20a29bc5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_marble.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_marble"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_netherrack.json
new file mode 100644
index 000000000..41397e21d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_netherrack.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_permafrost.json
new file mode 100644
index 000000000..7c490b424
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_sandstone.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_sandstone.json
new file mode 100644
index 000000000..259b18fd4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_sandstone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_sandstone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_slate.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_slate.json
new file mode 100644
index 000000000..635bc75fd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_slate.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_slate"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_steel.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_steel.json
new file mode 100644
index 000000000..f9ce539d2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_steel.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_steel"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_stone.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_stone.json
new file mode 100644
index 000000000..7e8ecab87
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_stone_polished.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_stone_polished.json
new file mode 100644
index 000000000..ba9091549
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_stone_polished.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_polished_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/brick_stone_polished_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/brick_stone_polished_mossy.json
new file mode 100644
index 000000000..ede55bd2c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/brick_stone_polished_mossy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_polished_stone_mossy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/active.json
new file mode 100644
index 000000000..e7ae984b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/active.json
@@ -0,0 +1,24 @@
+{
+    "textures": {
+        "overlay": "#texture",
+        "particle_up": "#texture",
+        "particle_down": "#texture",
+        "particle_north": "#texture",
+        "particle_south": "#texture",
+        "particle_west": "#texture",
+        "particle_east": "#texture"
+    },
+    "elements": [
+        {   "from": [ 5, 0, 6 ],
+            "to": [ 11, 1.02, 10 ],
+            "faces": {
+                "down":  { "uv": [ 5,  6, 11, 10 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [ 5,  6, 11, 10 ], "texture": "#texture" },
+                "north": { "uv": [ 5, 14, 11, 15 ], "texture": "#texture" },
+                "south": { "uv": [ 5, 14, 11, 15 ], "texture": "#texture" },
+                "west":  { "uv": [ 6, 14, 10, 15 ], "texture": "#texture" },
+                "east":  { "uv": [ 6, 14, 10, 15 ], "texture": "#texture" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/idle.json
new file mode 100644
index 000000000..d0ee6323e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/idle.json
@@ -0,0 +1,24 @@
+{
+    "textures": {
+        "overlay": "#texture",
+        "particle_up": "#texture",
+        "particle_down": "#texture",
+        "particle_north": "#texture",
+        "particle_south": "#texture",
+        "particle_west": "#texture",
+        "particle_east": "#texture"
+    },
+    "elements": [
+        {   "from": [ 5, 0, 6 ],
+            "to": [ 11, 2, 10 ],
+            "faces": {
+                "down":  { "uv": [ 5,  6, 11, 10 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [ 5,  6, 11, 10 ], "texture": "#texture" },
+                "north": { "uv": [ 5, 14, 11, 16 ], "texture": "#texture" },
+                "south": { "uv": [ 5, 14, 11, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 6, 14, 10, 16 ], "texture": "#texture" },
+                "east":  { "uv": [ 6, 14, 10, 16 ], "texture": "#texture" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/inventory.json
new file mode 100644
index 000000000..d243a74f1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/inventory.json
@@ -0,0 +1,24 @@
+{   "parent": "block/block",
+    "textures": {
+        "overlay": "#texture",
+        "particle_up": "#texture",
+        "particle_down": "#texture",
+        "particle_north": "#texture",
+        "particle_south": "#texture",
+        "particle_west": "#texture",
+        "particle_east": "#texture"
+    },
+    "elements": [
+        {   "from": [ 5, 6, 6 ],
+            "to": [ 11, 10, 10 ],
+            "faces": {
+                "down":  { "uv": [ 5, 6, 11, 10 ], "texture": "#texture" },
+                "up":    { "uv": [ 5, 10, 11, 6 ], "texture": "#texture" },
+                "north": { "uv": [ 5, 12, 11, 16 ], "texture": "#texture" },
+                "south": { "uv": [ 5, 12, 11, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 6, 12, 10, 16 ], "texture": "#texture" },
+                "east":  { "uv": [ 6, 12, 10, 16 ], "texture": "#texture" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/active.json
new file mode 100644
index 000000000..586a06e19
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/idle.json
new file mode 100644
index 000000000..f0379cd06
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/inventory.json
new file mode 100644
index 000000000..79515c625
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/black/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/active.json
new file mode 100644
index 000000000..62e0e45e1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/idle.json
new file mode 100644
index 000000000..b7d7ab072
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/inventory.json
new file mode 100644
index 000000000..d92703264
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/blue/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/active.json
new file mode 100644
index 000000000..54cac681a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/idle.json
new file mode 100644
index 000000000..2ec0c464a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/inventory.json
new file mode 100644
index 000000000..19a08ea53
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/brown/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/active.json
new file mode 100644
index 000000000..a2a00c5f1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/idle.json
new file mode 100644
index 000000000..b6b359909
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/inventory.json
new file mode 100644
index 000000000..f30435f66
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/cyan/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/active.json
new file mode 100644
index 000000000..8a0b7f2d8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/idle.json
new file mode 100644
index 000000000..4d29c037b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/inventory.json
new file mode 100644
index 000000000..f20ed9440
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/gray/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/active.json
new file mode 100644
index 000000000..fd33d2f84
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/idle.json
new file mode 100644
index 000000000..931490087
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/inventory.json
new file mode 100644
index 000000000..36c307840
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/green/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/active.json
new file mode 100644
index 000000000..c0a13a6a3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/idle.json
new file mode 100644
index 000000000..2e6816c9d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/inventory.json
new file mode 100644
index 000000000..be9e65fad
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lightblue/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/active.json
new file mode 100644
index 000000000..7759bd83c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/idle.json
new file mode 100644
index 000000000..0b50e01ae
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/inventory.json
new file mode 100644
index 000000000..4746d0f44
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/lime/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/active.json
new file mode 100644
index 000000000..c47bd3a95
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/idle.json
new file mode 100644
index 000000000..ab5891eb7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/inventory.json
new file mode 100644
index 000000000..2d345a62b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/magenta/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/active.json
new file mode 100644
index 000000000..1e861e73a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/idle.json
new file mode 100644
index 000000000..ddd75a273
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/inventory.json
new file mode 100644
index 000000000..e272cc558
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/oak/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/active.json
new file mode 100644
index 000000000..59f9aa4d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/idle.json
new file mode 100644
index 000000000..59b0dace9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/inventory.json
new file mode 100644
index 000000000..afc47fca2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/orange/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/active.json
new file mode 100644
index 000000000..f23a32360
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/idle.json
new file mode 100644
index 000000000..0a609c682
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/inventory.json
new file mode 100644
index 000000000..088fb53bc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/pink/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/active.json
new file mode 100644
index 000000000..6652bad1e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/idle.json
new file mode 100644
index 000000000..cca64b609
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/inventory.json
new file mode 100644
index 000000000..4b78ef398
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/purple/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/active.json
new file mode 100644
index 000000000..508026f8f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/idle.json
new file mode 100644
index 000000000..a99aec03e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/inventory.json
new file mode 100644
index 000000000..802eff2dd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/red/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/active.json
new file mode 100644
index 000000000..fd1d3b61a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/idle.json
new file mode 100644
index 000000000..d9d743b96
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/inventory.json
new file mode 100644
index 000000000..34205fbf7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/silver/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/active.json
new file mode 100644
index 000000000..cc726b220
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/idle.json
new file mode 100644
index 000000000..febd8563d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/inventory.json
new file mode 100644
index 000000000..5cc32751f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/white/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/active.json
new file mode 100644
index 000000000..07e03bb75
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/idle.json
new file mode 100644
index 000000000..2f128a016
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/inventory.json
new file mode 100644
index 000000000..69200ebdf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/planks/yellow/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/stone/active.json b/game/client/src/main/resources/assets/minecraft/models/block/button/stone/active.json
new file mode 100644
index 000000000..0aae66c40
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/stone/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/active",
+  "textures": {
+    "texture": "minecraft:block/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/stone/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/button/stone/idle.json
new file mode 100644
index 000000000..def7ee15d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/stone/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/idle",
+  "textures": {
+    "texture": "minecraft:block/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/button/stone/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/button/stone/inventory.json
new file mode 100644
index 000000000..66c3ab3d1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/button/stone/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/button/inventory",
+  "textures": {
+    "texture": "minecraft:block/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cactus.json b/game/client/src/main/resources/assets/minecraft/models/block/cactus.json
new file mode 100644
index 000000000..6e9f35488
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cactus.json
@@ -0,0 +1,38 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "minecraft:block/cube",
+	"textures": {
+		"bottom": "block/cactus/bottom",
+		"side": "block/cactus/side",
+		"top": "block/cactus/top",
+		"down": "#bottom",
+		"up": "#top",
+		"north": "#side",
+		"east": "#side",
+		"south": "#side",
+		"west": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 1],
+			"to": [16, 16, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 1]},
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"up": {"uv": [0, 1, 16, 15], "texture": "#top", "cullface": "up"},
+				"down": {"uv": [0, 1, 16, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		},
+		{
+			"from": [1, 0, 0],
+			"to": [15, 16, 16],
+			"faces": {
+				"east": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		}
+	],
+	"display": {}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cake/0.json b/game/client/src/main/resources/assets/minecraft/models/block/cake/0.json
new file mode 100644
index 000000000..624c306d4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cake/0.json
@@ -0,0 +1,31 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/cake/bottom",
+		"side": "block/cake/side",
+		"up": "block/cake/top",
+		"overlay": "#up",
+		"particle_up": "#up",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [1, 0, 1],
+			"to": [15, 8, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 1]},
+			"faces": {
+				"north": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"east": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"south": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"up": {"uv": [1, 1, 15, 15], "texture": "#up"},
+				"down": {"uv": [1, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cake/1.json b/game/client/src/main/resources/assets/minecraft/models/block/cake/1.json
new file mode 100644
index 000000000..ad9f4c34e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cake/1.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/cake/bottom",
+		"inner": "block/cake/inner",
+		"side": "block/cake/side",
+		"up": "block/cake/top",
+		"overlay": "#up",
+		"particle_up": "#up",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#inner",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [3, 0, 1],
+			"to": [15, 8, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 1]},
+			"faces": {
+				"north": {"uv": [1, 8, 13, 16], "texture": "#side"},
+				"east": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"south": {"uv": [3, 8, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 8, 15, 16], "texture": "#inner"},
+				"up": {"uv": [3, 1, 15, 15], "texture": "#up"},
+				"down": {"uv": [3, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cake/2.json b/game/client/src/main/resources/assets/minecraft/models/block/cake/2.json
new file mode 100644
index 000000000..a19c4fc05
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cake/2.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/cake/bottom",
+		"inner": "block/cake/inner",
+		"side": "block/cake/side",
+		"up": "block/cake/top",
+		"overlay": "#up",
+		"particle_up": "#up",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#inner",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [5, 0, 1],
+			"to": [15, 8, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 1]},
+			"faces": {
+				"north": {"uv": [1, 8, 11, 16], "texture": "#side"},
+				"east": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"south": {"uv": [5, 8, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 8, 15, 16], "texture": "#inner"},
+				"up": {"uv": [5, 1, 15, 15], "texture": "#up"},
+				"down": {"uv": [5, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cake/3.json b/game/client/src/main/resources/assets/minecraft/models/block/cake/3.json
new file mode 100644
index 000000000..c7128c770
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cake/3.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/cake/bottom",
+		"inner": "block/cake/inner",
+		"side": "block/cake/side",
+		"up": "block/cake/top",
+		"overlay": "#up",
+		"particle_up": "#up",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#inner",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [7, 0, 1],
+			"to": [15, 8, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 1]},
+			"faces": {
+				"north": {"uv": [1, 8, 9, 16], "texture": "#side"},
+				"east": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"south": {"uv": [7, 8, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 8, 15, 16], "texture": "#inner"},
+				"up": {"uv": [7, 1, 15, 15], "texture": "#up"},
+				"down": {"uv": [7, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cake/4.json b/game/client/src/main/resources/assets/minecraft/models/block/cake/4.json
new file mode 100644
index 000000000..8edc2d370
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cake/4.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/cake/bottom",
+		"inner": "block/cake/inner",
+		"side": "block/cake/side",
+		"up": "block/cake/top",
+		"overlay": "#up",
+		"particle_up": "#up",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#inner",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [9, 0, 1],
+			"to": [15, 8, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 1]},
+			"faces": {
+				"north": {"uv": [1, 8, 7, 16], "texture": "#side"},
+				"east": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"south": {"uv": [9, 8, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 8, 15, 16], "texture": "#inner"},
+				"up": {"uv": [9, 1, 15, 15], "texture": "#up"},
+				"down": {"uv": [9, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cake/5.json b/game/client/src/main/resources/assets/minecraft/models/block/cake/5.json
new file mode 100644
index 000000000..8126c2cab
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cake/5.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/cake/bottom",
+		"inner": "block/cake/inner",
+		"side": "block/cake/side",
+		"up": "block/cake/top",
+		"overlay": "#up",
+		"particle_up": "#up",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#inner",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [11, 0, 1],
+			"to": [15, 8, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [1, 0, 1]},
+			"faces": {
+				"north": {"uv": [1, 8, 5, 16], "texture": "#side"},
+				"east": {"uv": [1, 8, 15, 16], "texture": "#side"},
+				"south": {"uv": [11, 8, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 8, 15, 16], "texture": "#inner"},
+				"up": {"uv": [11, 1, 15, 15], "texture": "#up"},
+				"down": {"uv": [11, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/capstone_marble.json b/game/client/src/main/resources/assets/minecraft/models/block/capstone_marble.json
new file mode 100644
index 000000000..1b175d9c3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/capstone_marble.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/capstone_marble/top",
+		"side": "minecraft:block/capstone_marble/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/carved_basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/carved_basalt.json
new file mode 100644
index 000000000..6f08830ab
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/carved_basalt.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_basalt_top",
+		"side": "minecraft:block/carved_basalt"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/carved_granite.json b/game/client/src/main/resources/assets/minecraft/models/block/carved_granite.json
new file mode 100644
index 000000000..831624b78
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/carved_granite.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_granite_top",
+		"side": "minecraft:block/carved_granite"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/carved_limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/carved_limestone.json
new file mode 100644
index 000000000..612663c2c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/carved_limestone.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_limestone_top",
+		"side": "minecraft:block/carved_limestone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/carved_netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/carved_netherrack.json
new file mode 100644
index 000000000..937a74922
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/carved_netherrack.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_netherrack_top",
+		"side": "minecraft:block/carved_netherrack"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/carved_permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/carved_permafrost.json
new file mode 100644
index 000000000..a3899b516
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/carved_permafrost.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_permafrost_top",
+		"side": "minecraft:block/carved_permafrost"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/carved_stone.json b/game/client/src/main/resources/assets/minecraft/models/block/carved_stone.json
new file mode 100644
index 000000000..94b353d5e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/carved_stone.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_stone_top",
+		"side": "minecraft:block/carved_stone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/black.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/black.json
new file mode 100644
index 000000000..e68d98526
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/black.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_black/top_right",
+    "down": "minecraft:block/chest/planks_black/top_right",
+    "south": "minecraft:block/chest/planks_black/right_back",
+    "north": "minecraft:block/chest/planks_black/left_front",
+    "west": "minecraft:block/chest/planks_black/side",
+    "east": "minecraft:block/chest/planks_black/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/blue.json
new file mode 100644
index 000000000..085f706fd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/blue.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_blue/top_right",
+    "down": "minecraft:block/chest/planks_blue/top_right",
+    "south": "minecraft:block/chest/planks_blue/right_back",
+    "north": "minecraft:block/chest/planks_blue/left_front",
+    "west": "minecraft:block/chest/planks_blue/side",
+    "east": "minecraft:block/chest/planks_blue/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/brown.json
new file mode 100644
index 000000000..2fa134783
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/brown.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_brown/top_right",
+    "down": "minecraft:block/chest/planks_brown/top_right",
+    "south": "minecraft:block/chest/planks_brown/right_back",
+    "north": "minecraft:block/chest/planks_brown/left_front",
+    "west": "minecraft:block/chest/planks_brown/side",
+    "east": "minecraft:block/chest/planks_brown/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/cyan.json
new file mode 100644
index 000000000..88ae020ad
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/cyan.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_cyan/top_right",
+    "down": "minecraft:block/chest/planks_cyan/top_right",
+    "south": "minecraft:block/chest/planks_cyan/right_back",
+    "north": "minecraft:block/chest/planks_cyan/left_front",
+    "west": "minecraft:block/chest/planks_cyan/side",
+    "east": "minecraft:block/chest/planks_cyan/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/gray.json
new file mode 100644
index 000000000..145ec7215
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/gray.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_gray/top_right",
+    "down": "minecraft:block/chest/planks_gray/top_right",
+    "south": "minecraft:block/chest/planks_gray/right_back",
+    "north": "minecraft:block/chest/planks_gray/left_front",
+    "west": "minecraft:block/chest/planks_gray/side",
+    "east": "minecraft:block/chest/planks_gray/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/green.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/green.json
new file mode 100644
index 000000000..ef32aea50
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/green.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_green/top_right",
+    "down": "minecraft:block/chest/planks_green/top_right",
+    "south": "minecraft:block/chest/planks_green/right_back",
+    "north": "minecraft:block/chest/planks_green/left_front",
+    "west": "minecraft:block/chest/planks_green/side",
+    "east": "minecraft:block/chest/planks_green/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/lightblue.json
new file mode 100644
index 000000000..9c347370c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/lightblue.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_lightblue/top_right",
+    "down": "minecraft:block/chest/planks_lightblue/top_right",
+    "south": "minecraft:block/chest/planks_lightblue/right_back",
+    "north": "minecraft:block/chest/planks_lightblue/left_front",
+    "west": "minecraft:block/chest/planks_lightblue/side",
+    "east": "minecraft:block/chest/planks_lightblue/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/lime.json
new file mode 100644
index 000000000..922526246
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/lime.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_lime/top_right",
+    "down": "minecraft:block/chest/planks_lime/top_right",
+    "south": "minecraft:block/chest/planks_lime/right_back",
+    "north": "minecraft:block/chest/planks_lime/left_front",
+    "west": "minecraft:block/chest/planks_lime/side",
+    "east": "minecraft:block/chest/planks_lime/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/magenta.json
new file mode 100644
index 000000000..d780d926d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/magenta.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_magenta/top_right",
+    "down": "minecraft:block/chest/planks_magenta/top_right",
+    "south": "minecraft:block/chest/planks_magenta/right_back",
+    "north": "minecraft:block/chest/planks_magenta/left_front",
+    "west": "minecraft:block/chest/planks_magenta/side",
+    "east": "minecraft:block/chest/planks_magenta/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/orange.json
new file mode 100644
index 000000000..bb8fd5d84
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/orange.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_orange/top_right",
+    "down": "minecraft:block/chest/planks_orange/top_right",
+    "south": "minecraft:block/chest/planks_orange/right_back",
+    "north": "minecraft:block/chest/planks_orange/left_front",
+    "west": "minecraft:block/chest/planks_orange/side",
+    "east": "minecraft:block/chest/planks_orange/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/pink.json
new file mode 100644
index 000000000..bd03ef7a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/pink.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_pink/top_right",
+    "down": "minecraft:block/chest/planks_pink/top_right",
+    "south": "minecraft:block/chest/planks_pink/right_back",
+    "north": "minecraft:block/chest/planks_pink/left_front",
+    "west": "minecraft:block/chest/planks_pink/side",
+    "east": "minecraft:block/chest/planks_pink/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/planks.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/planks.json
new file mode 100644
index 000000000..31233ba90
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/planks.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks/top_right",
+    "down": "minecraft:block/chest/planks/top_right",
+    "south": "minecraft:block/chest/planks/right_back",
+    "north": "minecraft:block/chest/planks/left_front",
+    "west": "minecraft:block/chest/planks/side",
+    "east": "minecraft:block/chest/planks/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/purple.json
new file mode 100644
index 000000000..cf3642525
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/purple.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_purple/top_right",
+    "down": "minecraft:block/chest/planks_purple/top_right",
+    "south": "minecraft:block/chest/planks_purple/right_back",
+    "north": "minecraft:block/chest/planks_purple/left_front",
+    "west": "minecraft:block/chest/planks_purple/side",
+    "east": "minecraft:block/chest/planks_purple/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/red.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/red.json
new file mode 100644
index 000000000..8b7ac6dba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/red.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_red/top_right",
+    "down": "minecraft:block/chest/planks_red/top_right",
+    "south": "minecraft:block/chest/planks_red/right_back",
+    "north": "minecraft:block/chest/planks_red/left_front",
+    "west": "minecraft:block/chest/planks_red/side",
+    "east": "minecraft:block/chest/planks_red/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/silver.json
new file mode 100644
index 000000000..d0b93ab2e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/silver.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_silver/top_right",
+    "down": "minecraft:block/chest/planks_silver/top_right",
+    "south": "minecraft:block/chest/planks_silver/right_back",
+    "north": "minecraft:block/chest/planks_silver/left_front",
+    "west": "minecraft:block/chest/planks_silver/side",
+    "east": "minecraft:block/chest/planks_silver/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/white.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/white.json
new file mode 100644
index 000000000..24515ce26
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/white.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_white/top_right",
+    "down": "minecraft:block/chest/planks_white/top_right",
+    "south": "minecraft:block/chest/planks_white/right_back",
+    "north": "minecraft:block/chest/planks_white/left_front",
+    "west": "minecraft:block/chest/planks_white/side",
+    "east": "minecraft:block/chest/planks_white/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/left/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/yellow.json
new file mode 100644
index 000000000..d89c24f4e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/left/yellow.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_yellow/top_right",
+    "down": "minecraft:block/chest/planks_yellow/top_right",
+    "south": "minecraft:block/chest/planks_yellow/right_back",
+    "north": "minecraft:block/chest/planks_yellow/left_front",
+    "west": "minecraft:block/chest/planks_yellow/side",
+    "east": "minecraft:block/chest/planks_yellow/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/legacy.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/legacy.json
new file mode 100644
index 000000000..a30ab83a2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/legacy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/chest/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/black.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/black.json
new file mode 100644
index 000000000..42995805f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/black.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_black/top_left",
+    "down": "minecraft:block/chest/planks_black/top_left",
+    "south": "minecraft:block/chest/planks_black/left_back",
+    "north": "minecraft:block/chest/planks_black/right_front",
+    "west": "minecraft:block/chest/planks_black/side",
+    "east": "minecraft:block/chest/planks_black/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/blue.json
new file mode 100644
index 000000000..83e8b5be4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/blue.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_blue/top_left",
+    "down": "minecraft:block/chest/planks_blue/top_left",
+    "south": "minecraft:block/chest/planks_blue/left_back",
+    "north": "minecraft:block/chest/planks_blue/right_front",
+    "west": "minecraft:block/chest/planks_blue/side",
+    "east": "minecraft:block/chest/planks_blue/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/brown.json
new file mode 100644
index 000000000..01a1c6047
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/brown.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_brown/top_left",
+    "down": "minecraft:block/chest/planks_brown/top_left",
+    "south": "minecraft:block/chest/planks_brown/left_back",
+    "north": "minecraft:block/chest/planks_brown/right_front",
+    "west": "minecraft:block/chest/planks_brown/side",
+    "east": "minecraft:block/chest/planks_brown/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/cyan.json
new file mode 100644
index 000000000..2ed0ea1ed
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/cyan.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_cyan/top_left",
+    "down": "minecraft:block/chest/planks_cyan/top_left",
+    "south": "minecraft:block/chest/planks_cyan/left_back",
+    "north": "minecraft:block/chest/planks_cyan/right_front",
+    "west": "minecraft:block/chest/planks_cyan/side",
+    "east": "minecraft:block/chest/planks_cyan/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/gray.json
new file mode 100644
index 000000000..b1124892e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/gray.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_gray/top_left",
+    "down": "minecraft:block/chest/planks_gray/top_left",
+    "south": "minecraft:block/chest/planks_gray/left_back",
+    "north": "minecraft:block/chest/planks_gray/right_front",
+    "west": "minecraft:block/chest/planks_gray/side",
+    "east": "minecraft:block/chest/planks_gray/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/green.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/green.json
new file mode 100644
index 000000000..a74301718
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/green.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_green/top_left",
+    "down": "minecraft:block/chest/planks_green/top_left",
+    "south": "minecraft:block/chest/planks_green/left_back",
+    "north": "minecraft:block/chest/planks_green/right_front",
+    "west": "minecraft:block/chest/planks_green/side",
+    "east": "minecraft:block/chest/planks_green/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/lightblue.json
new file mode 100644
index 000000000..c3a5af30a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/lightblue.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_lightblue/top_left",
+    "down": "minecraft:block/chest/planks_lightblue/top_left",
+    "south": "minecraft:block/chest/planks_lightblue/left_back",
+    "north": "minecraft:block/chest/planks_lightblue/right_front",
+    "west": "minecraft:block/chest/planks_lightblue/side",
+    "east": "minecraft:block/chest/planks_lightblue/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/lime.json
new file mode 100644
index 000000000..139591ae5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/lime.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_lime/top_left",
+    "down": "minecraft:block/chest/planks_lime/top_left",
+    "south": "minecraft:block/chest/planks_lime/left_back",
+    "north": "minecraft:block/chest/planks_lime/right_front",
+    "west": "minecraft:block/chest/planks_lime/side",
+    "east": "minecraft:block/chest/planks_lime/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/magenta.json
new file mode 100644
index 000000000..051cd47ef
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/magenta.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_magenta/top_left",
+    "down": "minecraft:block/chest/planks_magenta/top_left",
+    "south": "minecraft:block/chest/planks_magenta/left_back",
+    "north": "minecraft:block/chest/planks_magenta/right_front",
+    "west": "minecraft:block/chest/planks_magenta/side",
+    "east": "minecraft:block/chest/planks_magenta/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/orange.json
new file mode 100644
index 000000000..bab034a84
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/orange.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_orange/top_left",
+    "down": "minecraft:block/chest/planks_orange/top_left",
+    "south": "minecraft:block/chest/planks_orange/left_back",
+    "north": "minecraft:block/chest/planks_orange/right_front",
+    "west": "minecraft:block/chest/planks_orange/side",
+    "east": "minecraft:block/chest/planks_orange/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/pink.json
new file mode 100644
index 000000000..900c689f4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/pink.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_pink/top_left",
+    "down": "minecraft:block/chest/planks_pink/top_left",
+    "south": "minecraft:block/chest/planks_pink/left_back",
+    "north": "minecraft:block/chest/planks_pink/right_front",
+    "west": "minecraft:block/chest/planks_pink/side",
+    "east": "minecraft:block/chest/planks_pink/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/planks.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/planks.json
new file mode 100644
index 000000000..576236632
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/planks.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks/top_left",
+    "down": "minecraft:block/chest/planks/top_left",
+    "south": "minecraft:block/chest/planks/left_back",
+    "north": "minecraft:block/chest/planks/right_front",
+    "west": "minecraft:block/chest/planks/side",
+    "east": "minecraft:block/chest/planks/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/purple.json
new file mode 100644
index 000000000..4c7e6e017
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/purple.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_purple/top_left",
+    "down": "minecraft:block/chest/planks_purple/top_left",
+    "south": "minecraft:block/chest/planks_purple/left_back",
+    "north": "minecraft:block/chest/planks_purple/right_front",
+    "west": "minecraft:block/chest/planks_purple/side",
+    "east": "minecraft:block/chest/planks_purple/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/red.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/red.json
new file mode 100644
index 000000000..2876979de
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/red.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_red/top_left",
+    "down": "minecraft:block/chest/planks_red/top_left",
+    "south": "minecraft:block/chest/planks_red/left_back",
+    "north": "minecraft:block/chest/planks_red/right_front",
+    "west": "minecraft:block/chest/planks_red/side",
+    "east": "minecraft:block/chest/planks_red/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/silver.json
new file mode 100644
index 000000000..80a24f7e1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/silver.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_silver/top_left",
+    "down": "minecraft:block/chest/planks_silver/top_left",
+    "south": "minecraft:block/chest/planks_silver/left_back",
+    "north": "minecraft:block/chest/planks_silver/right_front",
+    "west": "minecraft:block/chest/planks_silver/side",
+    "east": "minecraft:block/chest/planks_silver/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/white.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/white.json
new file mode 100644
index 000000000..d43e0f920
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/white.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_white/top_left",
+    "down": "minecraft:block/chest/planks_white/top_left",
+    "south": "minecraft:block/chest/planks_white/left_back",
+    "north": "minecraft:block/chest/planks_white/right_front",
+    "west": "minecraft:block/chest/planks_white/side",
+    "east": "minecraft:block/chest/planks_white/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/right/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/yellow.json
new file mode 100644
index 000000000..c5548092f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/right/yellow.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_yellow/top_left",
+    "down": "minecraft:block/chest/planks_yellow/top_left",
+    "south": "minecraft:block/chest/planks_yellow/left_back",
+    "north": "minecraft:block/chest/planks_yellow/right_front",
+    "west": "minecraft:block/chest/planks_yellow/side",
+    "east": "minecraft:block/chest/planks_yellow/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/black.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/black.json
new file mode 100644
index 000000000..868c24d60
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/black.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_black/top",
+    "down": "minecraft:block/chest/planks_black/top",
+    "south": "minecraft:block/chest/planks_black/side",
+    "north": "minecraft:block/chest/planks_black/front",
+    "west": "minecraft:block/chest/planks_black/side",
+    "east": "minecraft:block/chest/planks_black/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/blue.json
new file mode 100644
index 000000000..5e36ee04e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/blue.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_blue/top",
+    "down": "minecraft:block/chest/planks_blue/top",
+    "south": "minecraft:block/chest/planks_blue/side",
+    "north": "minecraft:block/chest/planks_blue/front",
+    "west": "minecraft:block/chest/planks_blue/side",
+    "east": "minecraft:block/chest/planks_blue/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/brown.json
new file mode 100644
index 000000000..d64a68821
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/brown.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_brown/top",
+    "down": "minecraft:block/chest/planks_brown/top",
+    "south": "minecraft:block/chest/planks_brown/side",
+    "north": "minecraft:block/chest/planks_brown/front",
+    "west": "minecraft:block/chest/planks_brown/side",
+    "east": "minecraft:block/chest/planks_brown/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/cyan.json
new file mode 100644
index 000000000..17762aa8a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/cyan.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_cyan/top",
+    "down": "minecraft:block/chest/planks_cyan/top",
+    "south": "minecraft:block/chest/planks_cyan/side",
+    "north": "minecraft:block/chest/planks_cyan/front",
+    "west": "minecraft:block/chest/planks_cyan/side",
+    "east": "minecraft:block/chest/planks_cyan/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/gray.json
new file mode 100644
index 000000000..935596991
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/gray.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_gray/top",
+    "down": "minecraft:block/chest/planks_gray/top",
+    "south": "minecraft:block/chest/planks_gray/side",
+    "north": "minecraft:block/chest/planks_gray/front",
+    "west": "minecraft:block/chest/planks_gray/side",
+    "east": "minecraft:block/chest/planks_gray/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/green.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/green.json
new file mode 100644
index 000000000..ea5fd9a06
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/green.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_green/top",
+    "down": "minecraft:block/chest/planks_green/top",
+    "south": "minecraft:block/chest/planks_green/side",
+    "north": "minecraft:block/chest/planks_green/front",
+    "west": "minecraft:block/chest/planks_green/side",
+    "east": "minecraft:block/chest/planks_green/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lightblue.json
new file mode 100644
index 000000000..fa6a3e1e2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lightblue.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_lightblue/top",
+    "down": "minecraft:block/chest/planks_lightblue/top",
+    "south": "minecraft:block/chest/planks_lightblue/side",
+    "north": "minecraft:block/chest/planks_lightblue/front",
+    "west": "minecraft:block/chest/planks_lightblue/side",
+    "east": "minecraft:block/chest/planks_lightblue/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lime.json
new file mode 100644
index 000000000..fc28f69b3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/lime.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_lime/top",
+    "down": "minecraft:block/chest/planks_lime/top",
+    "south": "minecraft:block/chest/planks_lime/side",
+    "north": "minecraft:block/chest/planks_lime/front",
+    "west": "minecraft:block/chest/planks_lime/side",
+    "east": "minecraft:block/chest/planks_lime/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/magenta.json
new file mode 100644
index 000000000..43099184a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/magenta.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_magenta/top",
+    "down": "minecraft:block/chest/planks_magenta/top",
+    "south": "minecraft:block/chest/planks_magenta/side",
+    "north": "minecraft:block/chest/planks_magenta/front",
+    "west": "minecraft:block/chest/planks_magenta/side",
+    "east": "minecraft:block/chest/planks_magenta/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/orange.json
new file mode 100644
index 000000000..fb945d6c4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/orange.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_orange/top",
+    "down": "minecraft:block/chest/planks_orange/top",
+    "south": "minecraft:block/chest/planks_orange/side",
+    "north": "minecraft:block/chest/planks_orange/front",
+    "west": "minecraft:block/chest/planks_orange/side",
+    "east": "minecraft:block/chest/planks_orange/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/pink.json
new file mode 100644
index 000000000..7b864c7e1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/pink.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_pink/top",
+    "down": "minecraft:block/chest/planks_pink/top",
+    "south": "minecraft:block/chest/planks_pink/side",
+    "north": "minecraft:block/chest/planks_pink/front",
+    "west": "minecraft:block/chest/planks_pink/side",
+    "east": "minecraft:block/chest/planks_pink/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/planks.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/planks.json
new file mode 100644
index 000000000..fe1010a1e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/planks.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks/top",
+    "down": "minecraft:block/chest/planks/top",
+    "south": "minecraft:block/chest/planks/side",
+    "north": "minecraft:block/chest/planks/front",
+    "west": "minecraft:block/chest/planks/side",
+    "east": "minecraft:block/chest/planks/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/purple.json
new file mode 100644
index 000000000..fe197824c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/purple.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_purple/top",
+    "down": "minecraft:block/chest/planks_purple/top",
+    "south": "minecraft:block/chest/planks_purple/side",
+    "north": "minecraft:block/chest/planks_purple/front",
+    "west": "minecraft:block/chest/planks_purple/side",
+    "east": "minecraft:block/chest/planks_purple/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/red.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/red.json
new file mode 100644
index 000000000..bc3dc92f3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/red.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_red/top",
+    "down": "minecraft:block/chest/planks_red/top",
+    "south": "minecraft:block/chest/planks_red/side",
+    "north": "minecraft:block/chest/planks_red/front",
+    "west": "minecraft:block/chest/planks_red/side",
+    "east": "minecraft:block/chest/planks_red/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/silver.json
new file mode 100644
index 000000000..527dbbd40
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/silver.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_silver/top",
+    "down": "minecraft:block/chest/planks_silver/top",
+    "south": "minecraft:block/chest/planks_silver/side",
+    "north": "minecraft:block/chest/planks_silver/front",
+    "west": "minecraft:block/chest/planks_silver/side",
+    "east": "minecraft:block/chest/planks_silver/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/white.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/white.json
new file mode 100644
index 000000000..0aecdff66
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/white.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_white/top",
+    "down": "minecraft:block/chest/planks_white/top",
+    "south": "minecraft:block/chest/planks_white/side",
+    "north": "minecraft:block/chest/planks_white/front",
+    "west": "minecraft:block/chest/planks_white/side",
+    "east": "minecraft:block/chest/planks_white/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/chest/single/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/yellow.json
new file mode 100644
index 000000000..73eee629b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/chest/single/yellow.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/chest/planks_yellow/top",
+    "down": "minecraft:block/chest/planks_yellow/top",
+    "south": "minecraft:block/chest/planks_yellow/side",
+    "north": "minecraft:block/chest/planks_yellow/front",
+    "west": "minecraft:block/chest/planks_yellow/side",
+    "east": "minecraft:block/chest/planks_yellow/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_basalt.json
new file mode 100644
index 000000000..9cf099869
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_basalt_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_basalt_mossy.json
new file mode 100644
index 000000000..825d328f0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_basalt_mossy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_basalt_mossy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_granite.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_granite.json
new file mode 100644
index 000000000..f421362b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_granite_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_granite_mossy.json
new file mode 100644
index 000000000..a1e5a778c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_granite_mossy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_granite_mossy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_limestone.json
new file mode 100644
index 000000000..e83e25a08
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_limestone_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_limestone_mossy.json
new file mode 100644
index 000000000..78e0af069
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_limestone_mossy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_limestone_mossy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/igneous.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/igneous.json
new file mode 100644
index 000000000..7a79c2035
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/igneous.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_netherrack/igneous"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/mossy.json
new file mode 100644
index 000000000..efb81e928
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/mossy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_netherrack/mossy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/normal.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/normal.json
new file mode 100644
index 000000000..def591e4c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_netherrack/normal.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_netherrack/normal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_permafrost.json
new file mode 100644
index 000000000..6b20443b7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_stone.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_stone.json
new file mode 100644
index 000000000..199549004
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cobbled_stone_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_stone_mossy.json
new file mode 100644
index 000000000..632b2b55e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cobbled_stone_mossy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_stone_mossy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/leaf.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/leaf.json
new file mode 100644
index 000000000..c6ad40c0f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/leaf.json
@@ -0,0 +1,39 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"ambientocclusion": false,
+	"textures": {
+		"leaf": "block/crops_pumpkin/stage0",
+		"overlay": "#leaf",
+		"particle_up": "#leaf",
+		"particle_down": "#leaf",
+		"particle_north": "#leaf",
+		"particle_south": "#leaf",
+		"particle_west": "#leaf",
+		"particle_east": "#leaf"
+	},
+	"elements": [
+		{
+			"name": "leaf0",
+			"from": [4, 0, 0],
+			"to": [20, 0, 16],
+			"shade": false,
+			"rotation": {"angle": 10, "axis": "z", "origin": [4, 0, 0], "rescale": true},
+			"faces": {
+				"up": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#leaf"},
+				"down": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#leaf"}
+			}
+		},
+		{
+			"name": "leaf1",
+			"from": [-4, 0, 0],
+			"to": [12, 0, 16],
+			"shade": false,
+			"rotation": {"angle": -10, "axis": "z", "origin": [12, 0, 0], "rescale": true},
+			"faces": {
+				"up": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#leaf"},
+				"down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#leaf"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage1.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage1.json
new file mode 100644
index 000000000..28d8b4fa3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage1.json
@@ -0,0 +1,31 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"side": "block/crops_pumpkin/stage1_side",
+		"top": "block/crops_pumpkin/stage1_top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#top",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"name": "pumpkin",
+			"from": [4, 0, 4],
+			"to": [12, 8, 12],
+			"rotation": {"angle": 0, "axis": "y", "origin": [4, 0, 4]},
+			"faces": {
+				"north": {"uv": [4, 8, 12, 16], "texture": "#side"},
+				"east": {"uv": [4, 8, 12, 16], "texture": "#side"},
+				"south": {"uv": [4, 8, 12, 16], "texture": "#side"},
+				"west": {"uv": [4, 8, 12, 16], "texture": "#top"},
+				"up": {"uv": [4, 4, 12, 12], "texture": "#top"},
+				"down": {"uv": [4, 4, 12, 12], "texture": "#top"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage2.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage2.json
new file mode 100644
index 000000000..356422dd4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage2.json
@@ -0,0 +1,31 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"side": "block/crops_pumpkin/stage2_side",
+		"top": "block/crops_pumpkin/stage2_top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#top",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"name": "pumpkin",
+			"from": [3, 0, 3],
+			"to": [13, 10, 13],
+			"rotation": {"angle": 0, "axis": "y", "origin": [4, 0, 4]},
+			"faces": {
+				"north": {"uv": [3, 6, 13, 16], "texture": "#side"},
+				"east": {"uv": [3, 6, 13, 16], "texture": "#side"},
+				"south": {"uv": [3, 6, 13, 16], "texture": "#side"},
+				"west": {"uv": [3, 6, 13, 16], "texture": "#side"},
+				"up": {"uv": [3, 3, 13, 13], "texture": "#top"},
+				"down": {"uv": [3, 6, 13, 16], "texture": "#top"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage3.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage3.json
new file mode 100644
index 000000000..1fd71c502
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage3.json
@@ -0,0 +1,31 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"side": "block/crops_pumpkin/stage3_side",
+		"top": "block/crops_pumpkin/stage3_top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#top",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"name": "pumpkin",
+			"from": [2, 0, 2],
+			"to": [14, 12, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [4, 0, 4]},
+			"faces": {
+				"north": {"uv": [2, 4, 14, 16], "texture": "#side"},
+				"east": {"uv": [2, 4, 14, 16], "texture": "#side"},
+				"south": {"uv": [2, 4, 14, 16], "texture": "#side"},
+				"west": {"uv": [2, 4, 14, 16], "texture": "#side"},
+				"up": {"uv": [2, 2, 14, 14], "texture": "#top"},
+				"down": {"uv": [2, 2, 14, 14], "texture": "#top"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage4.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage4.json
new file mode 100644
index 000000000..50fe33a9a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_pumpkin/stage4.json
@@ -0,0 +1,31 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"side": "block/crops_pumpkin/stage4_side",
+		"top": "block/crops_pumpkin/stage4_top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#top",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"name": "pumpkin",
+			"from": [1, 0, 1],
+			"to": [15, 14, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [4, 0, 4]},
+			"faces": {
+				"north": {"uv": [1, 2, 15, 16], "texture": "#side"},
+				"east": {"uv": [1, 2, 15, 16], "texture": "#side"},
+				"south": {"uv": [1, 2, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 2, 15, 16], "texture": "#side"},
+				"up": {"uv": [1, 1, 15, 15], "texture": "#top"},
+				"down": {"uv": [1, 1, 15, 15], "texture": "#top"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage0.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage0.json
new file mode 100644
index 000000000..36b35a7d3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage1.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage1.json
new file mode 100644
index 000000000..952204823
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage2.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage2.json
new file mode 100644
index 000000000..d309592ee
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage3.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage3.json
new file mode 100644
index 000000000..3af7ee48c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage4.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage4.json
new file mode 100644
index 000000000..de28ea3ae
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage4.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage4"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage5.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage5.json
new file mode 100644
index 000000000..0d7cde689
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage5.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage5"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage6.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage6.json
new file mode 100644
index 000000000..b417d6fe0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage6.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage6"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage7.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage7.json
new file mode 100644
index 000000000..891855071
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/stage7.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/crops_wheat/template",
+  "textures": {
+    "crop": "minecraft:block/crops_wheat/stage7"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/template.json b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/template.json
new file mode 100644
index 000000000..470d5f7ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/crops_wheat/template.json
@@ -0,0 +1,46 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#crop",
+        "particle_up": "#crop",
+        "particle_down": "#crop",
+        "particle_north": "#crop",
+        "particle_south": "#crop",
+        "particle_west": "#crop",
+        "particle_east": "#crop"
+    },
+    "elements": [
+        {   "from": [ 4, -1, 0 ],
+            "to": [ 4, 15, 16 ],
+            "shade": false,
+            "faces": {
+                "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#crop" },
+                "east": { "uv": [ 16, 0, 0, 16 ], "texture": "#crop" }
+            }
+        },
+        {   "from": [ 12, -1, 0 ],
+            "to": [ 12, 15, 16 ],
+            "shade": false,
+            "faces": {
+                "west": { "uv": [ 16, 0, 0, 16 ], "texture": "#crop" },
+                "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#crop" }
+            }
+        },
+        {   "from": [ 0, -1, 4 ],
+            "to": [ 16, 15, 4 ],
+            "shade": false,
+            "faces": {
+                "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#crop" },
+                "south": { "uv": [ 16, 0, 0, 16 ], "texture": "#crop" }
+            }
+        },
+        {   "from": [ 0, -1, 12 ],
+            "to": [ 16, 15, 12 ],
+            "shade": false,
+            "faces": {
+                "north": { "uv": [ 16, 0, 0, 16 ], "texture": "#crop" },
+                "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#crop" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cube_bottom_top.json b/game/client/src/main/resources/assets/minecraft/models/block/cube_bottom_top.json
new file mode 100644
index 000000000..6c37dcf12
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cube_bottom_top.json
@@ -0,0 +1,11 @@
+{
+    "parent": "block/cube",
+    "textures": {
+        "down": "#bottom",
+        "up": "#top",
+        "north": "#side",
+        "east": "#side",
+        "south": "#side",
+        "west": "#side"
+    }
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cube_column.json b/game/client/src/main/resources/assets/minecraft/models/block/cube_column.json
new file mode 100644
index 000000000..6f6c5d066
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cube_column.json
@@ -0,0 +1,11 @@
+{
+    "parent": "block/cube",
+    "textures": {
+        "down": "#end",
+        "up": "#end",
+        "north": "#side",
+        "east": "#side",
+        "south": "#side",
+        "west": "#side"
+    }
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cube_emissive.json b/game/client/src/main/resources/assets/minecraft/models/block/cube_emissive.json
deleted file mode 100644
index 434e02d87..000000000
--- a/game/client/src/main/resources/assets/minecraft/models/block/cube_emissive.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-    "parent": "block/block",
-    "textures": {
-        "overlay": "#north",
-        "particle_up": "#up",
-        "particle_down": "#down",
-        "particle_north": "#north",
-        "particle_south": "#south",
-        "particle_west": "#west",
-        "particle_east": "#east"
-    },
-    "elements": [
-        {   "from": [ 0, 0, 0 ],
-            "to": [ 16, 16, 16 ],
-            "faces": {
-                "down":  { "texture": "#down", "cullface": "down" },
-                "up":    { "texture": "#up", "cullface": "up" },
-                "north": { "texture": "#north", "cullface": "north" },
-                "south": { "texture": "#south", "cullface": "south" },
-                "west":  { "texture": "#west", "cullface": "west" },
-                "east":  { "texture": "#east", "cullface": "east" }
-            }
-        },
-        {   
-            "from": [ 0, 0, 0 ],
-            "to": [ 16, 16, 16 ],
-            "light_emission": 15,
-            "shade": false,
-            "faces": {
-                "down":  { "texture": "#down_emissive", "cullface": "down" },
-                "up":    { "texture": "#up_emissive", "cullface": "up" },
-                "north": { "texture": "#north_emissive", "cullface": "north" },
-                "south": { "texture": "#south_emissive", "cullface": "south" },
-                "west":  { "texture": "#west_emissive", "cullface": "west" },
-                "east":  { "texture": "#east_emissive", "cullface": "east" }
-            }
-    }
-    ]
-}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cube_emissive_all.json b/game/client/src/main/resources/assets/minecraft/models/block/cube_emissive_all.json
deleted file mode 100644
index bcd6347a8..000000000
--- a/game/client/src/main/resources/assets/minecraft/models/block/cube_emissive_all.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "parent": "block/cube_emissive",
-    "textures": {
-        "down": "#all",
-        "up": "#all",
-        "north": "#all",
-        "east": "#all",
-        "south": "#all",
-        "west": "#all",
-        "down_emissive": "#all_emissive",
-        "up_emissive": "#all_emissive",
-        "north_emissive": "#all_emissive",
-        "east_emissive": "#all_emissive",
-        "south_emissive": "#all_emissive",
-        "west_emissive": "#all_emissive"
-    }
-}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cube_top.json b/game/client/src/main/resources/assets/minecraft/models/block/cube_top.json
new file mode 100644
index 000000000..64c465a28
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cube_top.json
@@ -0,0 +1,11 @@
+{
+    "parent": "block/cube",
+    "textures": {
+        "down": "#side",
+        "up": "#top",
+        "north": "#side",
+        "east": "#side",
+        "south": "#side",
+        "west": "#side"
+    }
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/deadbush.json b/game/client/src/main/resources/assets/minecraft/models/block/deadbush.json
new file mode 100644
index 000000000..06011688e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/deadbush.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/deadbush"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/dirt.json b/game/client/src/main/resources/assets/minecraft/models/block/dirt.json
new file mode 100644
index 000000000..047941382
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/dirt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/dirt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/dirt_scorched.json b/game/client/src/main/resources/assets/minecraft/models/block/dirt_scorched.json
new file mode 100644
index 000000000..d5bea96ad
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/dirt_scorched.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/dirt_scorched"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/dirt_scorched_rich.json b/game/client/src/main/resources/assets/minecraft/models/block/dirt_scorched_rich.json
new file mode 100644
index 000000000..9dd1a3bd2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/dirt_scorched_rich.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/dirt_scorched_rich"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/dispenser.json b/game/client/src/main/resources/assets/minecraft/models/block/dispenser.json
new file mode 100644
index 000000000..4a4f74842
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/dispenser.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/dispenser/top",
+    "down": "minecraft:block/dispenser/bottom",
+    "south": "minecraft:block/dispenser/side",
+    "north": "minecraft:block/dispenser/front",
+    "west": "minecraft:block/dispenser/side",
+    "east": "minecraft:block/dispenser/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_left.json
new file mode 100644
index 000000000..51b488210
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_left.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#bottom",
+        "particle_up": "#bottom",
+        "particle_down": "#bottom",
+        "particle_north": "#bottom",
+        "particle_south": "#bottom",
+        "particle_west": "#bottom",
+        "particle_east": "#bottom"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [ 16, 13,  0, 16 ], "texture": "#bottom", "cullface": "down", "rotation": 90 },
+                "north": { "uv": [  3,  0,  0, 16 ], "texture": "#bottom", "cullface": "north" },
+                "south": { "uv": [  0,  0,  3, 16 ], "texture": "#bottom", "cullface": "south" },
+                "west":  { "uv": [  0,  0, 16, 16 ], "texture": "#bottom", "cullface": "west" },
+                "east":  { "uv": [ 16,  0,  0, 16 ], "texture": "#bottom" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_left_open.json
new file mode 100644
index 000000000..8a412eddf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_left_open.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#bottom",
+        "particle_up": "#bottom",
+        "particle_down": "#bottom",
+        "particle_north": "#bottom",
+        "particle_south": "#bottom",
+        "particle_west": "#bottom",
+        "particle_east": "#bottom"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [  0, 16, 16, 13 ], "texture": "#bottom", "cullface": "down", "rotation": 90 },
+                "north": { "uv": [  0,  0,  3, 16 ], "texture": "#bottom", "cullface": "north" },
+                "south": { "uv": [  0,  0,  3, 16 ], "texture": "#bottom", "cullface": "south" },
+                "west":  { "uv": [ 16,  0,  0, 16 ], "texture": "#bottom", "cullface": "west" },
+                "east":  { "uv": [  0,  0, 16, 16 ], "texture": "#bottom" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_right.json
new file mode 100644
index 000000000..c164fd5d9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_right.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#bottom",
+        "particle_up": "#bottom",
+        "particle_down": "#bottom",
+        "particle_north": "#bottom",
+        "particle_south": "#bottom",
+        "particle_west": "#bottom",
+        "particle_east": "#bottom"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [  0, 13, 16, 16 ], "texture": "#bottom", "cullface": "down", "rotation": 90 },
+                "north": { "uv": [  3,  0,  0, 16 ], "texture": "#bottom", "cullface": "north" },
+                "south": { "uv": [  0,  0,  3, 16 ], "texture": "#bottom", "cullface": "south" },
+                "west":  { "uv": [ 16,  0,  0, 16 ], "texture": "#bottom", "cullface": "west" },
+                "east":  { "uv": [  0,  0, 16, 16 ], "texture": "#bottom" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_right_open.json
new file mode 100644
index 000000000..6942843cf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/bottom_right_open.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#bottom",
+        "particle_up": "#bottom",
+        "particle_down": "#bottom",
+        "particle_north": "#bottom",
+        "particle_south": "#bottom",
+        "particle_west": "#bottom",
+        "particle_east": "#bottom"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [ 16, 16,  0, 13 ], "texture": "#bottom", "cullface": "down", "rotation": 90 },
+                "north": { "uv": [  3,  0,  0, 16 ], "texture": "#bottom", "cullface": "north" },
+                "south": { "uv": [  3,  0,  0, 16 ], "texture": "#bottom", "cullface": "south" },
+                "west":  { "uv": [  0,  0, 16, 16 ], "texture": "#bottom", "cullface": "west" },
+                "east":  { "uv": [ 16,  0,  0, 16 ], "texture": "#bottom" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_left.json
new file mode 100644
index 000000000..bc0573c68
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/glass/bottom_left"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_left_open.json
new file mode 100644
index 000000000..fc2a86d55
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/glass/bottom_left"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_right.json
new file mode 100644
index 000000000..8eea90b3b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/glass/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_right_open.json
new file mode 100644
index 000000000..3be8651a7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/glass/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_left.json
new file mode 100644
index 000000000..9af8f7087
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/glass/top_left"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_left_open.json
new file mode 100644
index 000000000..158812a1a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/glass/top_left"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_right.json
new file mode 100644
index 000000000..10ed39cb0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/glass/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_right_open.json
new file mode 100644
index 000000000..24358c793
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/glass/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/glass/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_left.json
new file mode 100644
index 000000000..468a0a102
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/iron/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_left_open.json
new file mode 100644
index 000000000..73864410c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/iron/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_right.json
new file mode 100644
index 000000000..629a1f595
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/iron/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_right_open.json
new file mode 100644
index 000000000..e3b750106
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/iron/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_left.json
new file mode 100644
index 000000000..2a576100f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/iron/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_left_open.json
new file mode 100644
index 000000000..def78d593
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/iron/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_right.json
new file mode 100644
index 000000000..af27943c6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/iron/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_right_open.json
new file mode 100644
index 000000000..5a49f9d0c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/iron/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/iron/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_left.json
new file mode 100644
index 000000000..ebbb43e23
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_black/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_left_open.json
new file mode 100644
index 000000000..308e475d9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_black/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_right.json
new file mode 100644
index 000000000..42803a358
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_black/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_right_open.json
new file mode 100644
index 000000000..7c5ef9bbc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_black/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_left.json
new file mode 100644
index 000000000..788c75be7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_black/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_left_open.json
new file mode 100644
index 000000000..7093f2525
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_black/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_right.json
new file mode 100644
index 000000000..665bbccd5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_black/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_right_open.json
new file mode 100644
index 000000000..9f8a84f7b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/black/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_black/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_left.json
new file mode 100644
index 000000000..5e8cde605
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_blue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_left_open.json
new file mode 100644
index 000000000..6dc39f63a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_blue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_right.json
new file mode 100644
index 000000000..187984dc3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_blue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_right_open.json
new file mode 100644
index 000000000..02356bbc7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_blue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_left.json
new file mode 100644
index 000000000..d411876c3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_blue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_left_open.json
new file mode 100644
index 000000000..24226735a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_blue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_right.json
new file mode 100644
index 000000000..cd8ce9bea
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_blue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_right_open.json
new file mode 100644
index 000000000..41750ae58
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/blue/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_blue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_left.json
new file mode 100644
index 000000000..82981ac8e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_brown/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_left_open.json
new file mode 100644
index 000000000..77999c717
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_brown/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_right.json
new file mode 100644
index 000000000..a3a2f7c61
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_brown/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_right_open.json
new file mode 100644
index 000000000..b3de3db52
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_brown/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_left.json
new file mode 100644
index 000000000..b58d78734
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_brown/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_left_open.json
new file mode 100644
index 000000000..2cb58cfb8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_brown/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_right.json
new file mode 100644
index 000000000..58efefe47
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_brown/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_right_open.json
new file mode 100644
index 000000000..d9dc57f3e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/brown/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_brown/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_left.json
new file mode 100644
index 000000000..3c5a2c1ce
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_cyan/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_left_open.json
new file mode 100644
index 000000000..2b66eeea8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_cyan/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_right.json
new file mode 100644
index 000000000..831f5af74
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_cyan/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_right_open.json
new file mode 100644
index 000000000..9c8f9f154
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_cyan/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_left.json
new file mode 100644
index 000000000..5fc6a4164
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_cyan/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_left_open.json
new file mode 100644
index 000000000..60f4d33ed
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_cyan/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_right.json
new file mode 100644
index 000000000..4311f58b1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_cyan/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_right_open.json
new file mode 100644
index 000000000..73343a64b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/cyan/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_cyan/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_left.json
new file mode 100644
index 000000000..75ba3707b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_gray/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_left_open.json
new file mode 100644
index 000000000..832bf46e6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_gray/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_right.json
new file mode 100644
index 000000000..750da4220
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_gray/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_right_open.json
new file mode 100644
index 000000000..8df9de405
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_gray/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_left.json
new file mode 100644
index 000000000..c9719a321
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_gray/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_left_open.json
new file mode 100644
index 000000000..02574624b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_gray/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_right.json
new file mode 100644
index 000000000..9d3e3c85d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_gray/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_right_open.json
new file mode 100644
index 000000000..648de41c9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/gray/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_gray/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_left.json
new file mode 100644
index 000000000..aa0a1da32
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_green/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_left_open.json
new file mode 100644
index 000000000..71f23e150
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_green/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_right.json
new file mode 100644
index 000000000..4a471ad41
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_green/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_right_open.json
new file mode 100644
index 000000000..ce29c3941
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_green/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_left.json
new file mode 100644
index 000000000..9b2c313d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_green/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_left_open.json
new file mode 100644
index 000000000..7238034ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_green/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_right.json
new file mode 100644
index 000000000..8e64ed0b8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_green/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_right_open.json
new file mode 100644
index 000000000..f7af6baf3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/green/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_green/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_left.json
new file mode 100644
index 000000000..aed2ca695
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lightblue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_left_open.json
new file mode 100644
index 000000000..95b8ce5dd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lightblue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_right.json
new file mode 100644
index 000000000..4bb96b408
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lightblue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_right_open.json
new file mode 100644
index 000000000..014fce581
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lightblue/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_left.json
new file mode 100644
index 000000000..732b97f77
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_lightblue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_left_open.json
new file mode 100644
index 000000000..9d34b7053
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_lightblue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_right.json
new file mode 100644
index 000000000..ce33ef9b5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_lightblue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_right_open.json
new file mode 100644
index 000000000..f33cb09b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lightblue/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_lightblue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_left.json
new file mode 100644
index 000000000..077700e3e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lime/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_left_open.json
new file mode 100644
index 000000000..596b79d86
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lime/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_right.json
new file mode 100644
index 000000000..323165942
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lime/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_right_open.json
new file mode 100644
index 000000000..d81901378
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_lime/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_left.json
new file mode 100644
index 000000000..d4e033265
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_lime/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_left_open.json
new file mode 100644
index 000000000..7585f490a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_lime/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_right.json
new file mode 100644
index 000000000..1c8068d18
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_lime/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_right_open.json
new file mode 100644
index 000000000..bd356a5f2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/lime/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_lime/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_left.json
new file mode 100644
index 000000000..cbb6f2547
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_magenta/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_left_open.json
new file mode 100644
index 000000000..6c8a02e72
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_magenta/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_right.json
new file mode 100644
index 000000000..878ec9ca3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_magenta/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_right_open.json
new file mode 100644
index 000000000..6156d17a0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_magenta/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_left.json
new file mode 100644
index 000000000..54ccebc25
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_magenta/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_left_open.json
new file mode 100644
index 000000000..82d6ba766
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_magenta/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_right.json
new file mode 100644
index 000000000..5734abb3d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_magenta/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_right_open.json
new file mode 100644
index 000000000..7dc73e54b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/magenta/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_magenta/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_left.json
new file mode 100644
index 000000000..a0207300f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_left_open.json
new file mode 100644
index 000000000..e947d8b3d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_right.json
new file mode 100644
index 000000000..9dbc8bb3b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_right_open.json
new file mode 100644
index 000000000..9924f71b7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_left.json
new file mode 100644
index 000000000..6ff16e0b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_left_open.json
new file mode 100644
index 000000000..4f129eee6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_right.json
new file mode 100644
index 000000000..867958800
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_right_open.json
new file mode 100644
index 000000000..965d373e6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/oak/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_left.json
new file mode 100644
index 000000000..6d2b00720
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_orange/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_left_open.json
new file mode 100644
index 000000000..2e1c90073
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_orange/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_right.json
new file mode 100644
index 000000000..5ec347b34
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_orange/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_right_open.json
new file mode 100644
index 000000000..27240347b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_orange/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_left.json
new file mode 100644
index 000000000..589e1196f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_orange/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_left_open.json
new file mode 100644
index 000000000..0141117f7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_orange/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_right.json
new file mode 100644
index 000000000..2a20bc9a3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_orange/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_right_open.json
new file mode 100644
index 000000000..d8cd17baf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/orange/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_orange/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_left.json
new file mode 100644
index 000000000..a7cc31370
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_pink/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_left_open.json
new file mode 100644
index 000000000..df36ee0d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_pink/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_right.json
new file mode 100644
index 000000000..337b08414
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_pink/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_right_open.json
new file mode 100644
index 000000000..6457802f3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_pink/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_left.json
new file mode 100644
index 000000000..3c507605b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_pink/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_left_open.json
new file mode 100644
index 000000000..97e061d2c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_pink/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_right.json
new file mode 100644
index 000000000..eb8ec8ce7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_pink/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_right_open.json
new file mode 100644
index 000000000..1bb15bbbe
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/pink/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_pink/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_left.json
new file mode 100644
index 000000000..45e5d0e72
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_purple/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_left_open.json
new file mode 100644
index 000000000..9b08ab88e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_purple/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_right.json
new file mode 100644
index 000000000..00dc285df
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_purple/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_right_open.json
new file mode 100644
index 000000000..c019d0a9c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_purple/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_left.json
new file mode 100644
index 000000000..ee2d70b15
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_purple/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_left_open.json
new file mode 100644
index 000000000..22a92f80d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_purple/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_right.json
new file mode 100644
index 000000000..d96675d6a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_purple/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_right_open.json
new file mode 100644
index 000000000..c1086f13f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/purple/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_purple/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_left.json
new file mode 100644
index 000000000..6e4c95b09
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_red/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_left_open.json
new file mode 100644
index 000000000..4039ecaf4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_red/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_right.json
new file mode 100644
index 000000000..4df02fa28
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_red/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_right_open.json
new file mode 100644
index 000000000..1b68de63f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_red/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_left.json
new file mode 100644
index 000000000..0d7b3e001
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_red/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_left_open.json
new file mode 100644
index 000000000..ee265d770
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_red/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_right.json
new file mode 100644
index 000000000..c0ed28cff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_red/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_right_open.json
new file mode 100644
index 000000000..af3ab6914
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/red/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_red/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_left.json
new file mode 100644
index 000000000..f7f16240f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_silver/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_left_open.json
new file mode 100644
index 000000000..a30390824
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_silver/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_right.json
new file mode 100644
index 000000000..5bce07c79
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_silver/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_right_open.json
new file mode 100644
index 000000000..4c1177d02
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_silver/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_left.json
new file mode 100644
index 000000000..86d10a7c8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_silver/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_left_open.json
new file mode 100644
index 000000000..f7b4cd445
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_silver/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_right.json
new file mode 100644
index 000000000..e660bf428
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_silver/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_right_open.json
new file mode 100644
index 000000000..0c7bbc709
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/silver/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_silver/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_left.json
new file mode 100644
index 000000000..9149a0858
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_white/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_left_open.json
new file mode 100644
index 000000000..84bb9c8ac
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_white/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_right.json
new file mode 100644
index 000000000..5427adb0d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_white/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_right_open.json
new file mode 100644
index 000000000..e7117ce48
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_white/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_left.json
new file mode 100644
index 000000000..9d1792c12
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_white/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_left_open.json
new file mode 100644
index 000000000..4b7eff989
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_white/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_right.json
new file mode 100644
index 000000000..bc2e05a44
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_white/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_right_open.json
new file mode 100644
index 000000000..8d0e39cb2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/white/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_white/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_left.json
new file mode 100644
index 000000000..4a49eccf4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_yellow/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_left_open.json
new file mode 100644
index 000000000..069bae1c1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_yellow/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_right.json
new file mode 100644
index 000000000..3f0bab49f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_yellow/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_right_open.json
new file mode 100644
index 000000000..c956e3362
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/planks_yellow/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_left.json
new file mode 100644
index 000000000..db4932eb5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/planks_yellow/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_left_open.json
new file mode 100644
index 000000000..92bd702ef
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_yellow/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_right.json
new file mode 100644
index 000000000..a55e820d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/planks_yellow/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_right_open.json
new file mode 100644
index 000000000..4f8b9849c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/planks/yellow/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/planks_yellow/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_left.json
new file mode 100644
index 000000000..ca76da9e7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left",
+  "textures": {
+    "bottom": "minecraft:block/door/steel/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_left_open.json
new file mode 100644
index 000000000..a1a5f1ea0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_left_open",
+  "textures": {
+    "bottom": "minecraft:block/door/steel/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_right.json
new file mode 100644
index 000000000..ba327ffe6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right",
+  "textures": {
+    "bottom": "minecraft:block/door/steel/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_right_open.json
new file mode 100644
index 000000000..dd0b8f70f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/bottom_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/bottom_right_open",
+  "textures": {
+    "bottom": "minecraft:block/door/steel/bottom"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_left.json
new file mode 100644
index 000000000..a6d9ab6d3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_left.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left",
+  "textures": {
+    "top": "minecraft:block/door/steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_left_open.json
new file mode 100644
index 000000000..24ad286bf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_left_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_left_open",
+  "textures": {
+    "top": "minecraft:block/door/steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_right.json
new file mode 100644
index 000000000..695ea5c00
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_right.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right",
+  "textures": {
+    "top": "minecraft:block/door/steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_right_open.json
new file mode 100644
index 000000000..db6fba254
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/steel/top_right_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/door/top_right_open",
+  "textures": {
+    "top": "minecraft:block/door/steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/top_left.json b/game/client/src/main/resources/assets/minecraft/models/block/door/top_left.json
new file mode 100644
index 000000000..e547d6179
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/top_left.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#top",
+        "particle_north": "#top",
+        "particle_south": "#top",
+        "particle_west": "#top",
+        "particle_east": "#top"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "up":    { "uv": [  0,  3, 16,  0 ], "texture": "#top", "cullface": "up", "rotation": 90 },
+                "north": { "uv": [  3,  0,  0, 16 ], "texture": "#top", "cullface": "north" },
+                "south": { "uv": [  0,  0,  3, 16 ], "texture": "#top", "cullface": "south" },
+                "west":  { "uv": [  0,  0, 16, 16 ], "texture": "#top", "cullface": "west" },
+                "east":  { "uv": [ 16,  0,  0, 16 ], "texture": "#top" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/top_left_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/top_left_open.json
new file mode 100644
index 000000000..5fae31e5e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/top_left_open.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#top",
+        "particle_north": "#top",
+        "particle_south": "#top",
+        "particle_west": "#top",
+        "particle_east": "#top"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "up":    { "uv": [  0,  3, 16,  0 ], "texture": "#top", "cullface": "up", "rotation": 270 },
+                "north": { "uv": [  0,  0,  3, 16 ], "texture": "#top", "cullface": "north" },
+                "south": { "uv": [  0,  0,  3, 16 ], "texture": "#top", "cullface": "south" },
+                "west":  { "uv": [ 16,  0,  0, 16 ], "texture": "#top", "cullface": "west" },
+                "east":  { "uv": [  0,  0, 16, 16 ], "texture": "#top" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/top_right.json b/game/client/src/main/resources/assets/minecraft/models/block/door/top_right.json
new file mode 100644
index 000000000..703b8d31d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/top_right.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#top",
+        "particle_north": "#top",
+        "particle_south": "#top",
+        "particle_west": "#top",
+        "particle_east": "#top"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "up":    { "uv": [  0,  0, 16,  3 ], "texture": "#top", "cullface": "up", "rotation": 270 },
+                "north": { "uv": [  3,  0,  0, 16 ], "texture": "#top", "cullface": "north" },
+                "south": { "uv": [  0,  0,  3, 16 ], "texture": "#top", "cullface": "south" },
+                "west":  { "uv": [ 16,  0,  0, 16 ], "texture": "#top", "cullface": "west" },
+                "east":  { "uv": [  0,  0, 16, 16 ], "texture": "#top" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/door/top_right_open.json b/game/client/src/main/resources/assets/minecraft/models/block/door/top_right_open.json
new file mode 100644
index 000000000..bb5f76549
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/door/top_right_open.json
@@ -0,0 +1,24 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#top",
+        "particle_north": "#top",
+        "particle_south": "#top",
+        "particle_west": "#top",
+        "particle_east": "#top"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 3, 16, 16 ],
+            "faces": {
+                "up":    { "uv": [  0,  0, 16,  3 ], "texture": "#top", "cullface": "up", "rotation": 90 },
+                "north": { "uv": [  3,  0,  0, 16 ], "texture": "#top", "cullface": "north" },
+                "south": { "uv": [  3,  0,  0, 16 ], "texture": "#top", "cullface": "south" },
+                "west":  { "uv": [  0,  0, 16, 16 ], "texture": "#top", "cullface": "west" },
+                "east":  { "uv": [ 16,  0,  0, 16 ], "texture": "#top" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/farmland/dry.json b/game/client/src/main/resources/assets/minecraft/models/block/farmland/dry.json
new file mode 100644
index 000000000..4a8f4ac2b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/farmland/dry.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/farmland/template",
+  "textures": {
+    "top": "minecraft:block/farmland/dry_top",
+    "side": "minecraft:block/dirt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/farmland/dry_fertilized.json b/game/client/src/main/resources/assets/minecraft/models/block/farmland/dry_fertilized.json
new file mode 100644
index 000000000..a46067296
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/farmland/dry_fertilized.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/farmland/template",
+  "textures": {
+    "top": "minecraft:block/farmland/dry_fertilized_top",
+    "side": "minecraft:block/dirt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/farmland/template.json b/game/client/src/main/resources/assets/minecraft/models/block/farmland/template.json
new file mode 100644
index 000000000..b6e631fd6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/farmland/template.json
@@ -0,0 +1,28 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+    "textures": {
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#side",
+        "particle_north": "#side",
+        "particle_south": "#side",
+        "particle_west": "#side",
+        "particle_east": "#side"
+    },
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 15, 16],
+			"faces": {
+				"north": {"uv": [0, 1, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 1, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 1, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 1, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/farmland/wet.json b/game/client/src/main/resources/assets/minecraft/models/block/farmland/wet.json
new file mode 100644
index 000000000..af926ac84
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/farmland/wet.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/farmland/template",
+  "textures": {
+    "top": "minecraft:block/farmland/wet_top",
+    "side": "minecraft:block/mud"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/farmland/wet_fertilized.json b/game/client/src/main/resources/assets/minecraft/models/block/farmland/wet_fertilized.json
new file mode 100644
index 000000000..2b4c5d4e7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/farmland/wet_fertilized.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/farmland/template",
+  "textures": {
+    "top": "minecraft:block/farmland/wet_fertilized_top",
+    "side": "minecraft:block/mud"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/black/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/black/inventory.json
new file mode 100644
index 000000000..130dd13ca
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/black/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/black/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/black/post.json
new file mode 100644
index 000000000..f85f07bbc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/black/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/black/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/black/side.json
new file mode 100644
index 000000000..4b1b1f2df
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/black/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/inventory.json
new file mode 100644
index 000000000..f0da5a703
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/post.json
new file mode 100644
index 000000000..af005b11b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/side.json
new file mode 100644
index 000000000..e35493e44
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/blue/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/inventory.json
new file mode 100644
index 000000000..1dd02bda0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/post.json
new file mode 100644
index 000000000..3482e24bc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/side.json
new file mode 100644
index 000000000..5b4c63218
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/brown/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/inventory.json
new file mode 100644
index 000000000..3b4b9fd8e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/post.json
new file mode 100644
index 000000000..5f0741b29
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/side.json
new file mode 100644
index 000000000..9956bd992
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/cyan/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/inventory.json
new file mode 100644
index 000000000..131aca2ff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/post.json
new file mode 100644
index 000000000..89964e81f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/side.json
new file mode 100644
index 000000000..64aa211bb
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/gray/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/green/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/green/inventory.json
new file mode 100644
index 000000000..c89149c18
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/green/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/green/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/green/post.json
new file mode 100644
index 000000000..7689bd244
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/green/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/green/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/green/side.json
new file mode 100644
index 000000000..74fe989d3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/green/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/inventory.json
new file mode 100644
index 000000000..5c76bda53
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/inventory.json
@@ -0,0 +1,107 @@
+{   "parent": "block/block",
+    "display": {
+        "gui": {
+            "rotation": [ 30, 135, 0 ],
+            "translation": [ 0, 0, 0],
+            "scale":[ 0.625, 0.625, 0.625 ]
+        },
+        "fixed": {
+            "rotation": [ 0, 90, 0 ],
+            "translation": [ 0, 0, 0],
+            "scale":[ 0.5, 0.5, 0.5 ]
+        }
+    },
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "from": [ 6, 0, 0 ],
+            "to": [ 10, 16, 4 ],
+            "faces": {
+                "down":  { "uv": [ 6, 0, 10,  4 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [ 6, 0, 10,  4 ], "texture": "#texture" },
+                "north": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
+                "south": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 0, 0,  4, 16 ], "texture": "#texture" },
+                "east":  { "uv": [ 0, 0,  4, 16 ], "texture": "#texture" }
+            },
+            "__comment": "Left post"
+        },
+        {   "from": [ 6, 0, 12 ],
+            "to": [ 10, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [  6, 12, 10, 16 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [  6, 12, 10, 16 ], "texture": "#texture" },
+                "north": { "uv": [  6,  0, 10, 16 ], "texture": "#texture" },
+                "south": { "uv": [  6,  0, 10, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 12,  0, 16, 16 ], "texture": "#texture" },
+                "east":  { "uv": [ 12,  0, 16, 16 ], "texture": "#texture" }
+            },
+            "__comment": "Right post"
+        },
+        {   "from": [ 7, 12, 0 ],
+            "to": [ 9, 15, 16 ],
+            "faces": {
+                "down":  { "uv": [ 7, 0,  9, 16 ], "texture": "#texture" },
+                "up":    { "uv": [ 7, 0,  9, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 0, 1, 16,  4 ], "texture": "#texture" },
+                "east":  { "uv": [ 0, 1, 16,  4 ], "texture": "#texture" }
+            },
+            "__comment": "Top bar"
+        },
+        {   "from": [ 7, 12, -2 ],
+            "to": [ 9, 15, 0 ],
+            "faces": {
+                "down":  { "uv": [  7,  0,  9,  2 ], "texture": "#texture" },
+                "up":    { "uv": [  7, 14,  9, 16 ], "texture": "#texture" },
+                "north": { "uv": [  7,  1,  9,  4 ], "texture": "#texture" },
+                "west":  { "uv": [ 14,  1, 16,  4 ], "texture": "#texture" },
+                "east":  { "uv": [  0,  1,  2,  4 ], "texture": "#texture" }
+            },
+            "__comment": "Top bar left"
+        },
+        {   "from": [ 7, 12, 16 ],
+            "to": [ 9, 15, 18 ],
+            "faces": {
+                "down":  { "uv": [  7, 14,  9, 16 ], "texture": "#texture" },
+                "up":    { "uv": [  7,  0,  9,  2 ], "texture": "#texture" },
+                "south": { "uv": [  7,  1,  9,  4 ], "texture": "#texture" },
+                "west":  { "uv": [  0,  1,  2,  4 ], "texture": "#texture" },
+                "east":  { "uv": [ 14,  1, 16,  4 ], "texture": "#texture" }
+          },
+            "__comment": "Top bar right"
+        },
+        {   "from": [ 7, 6, 0 ],
+            "to": [ 9, 9, 16 ],
+            "faces": {
+                "down":  { "uv": [ 7, 0,  9, 16 ], "texture": "#texture" },
+                "up":    { "uv": [ 7, 0,  9, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 0, 7, 16, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 0, 7, 16, 10 ], "texture": "#texture" }
+            },
+            "__comment": "Lower bar"
+        },
+        {   "from": [ 7, 6, -2 ],
+            "to": [ 9, 9, 0 ],
+            "faces": {
+                "down":  { "uv": [  7,  0,  9,  2 ], "texture": "#texture" },
+                "up":    { "uv": [  7, 14,  9, 16 ], "texture": "#texture" },
+                "north": { "uv": [  7,  7,  9, 10 ], "texture": "#texture" },
+                "west":  { "uv": [ 14,  7, 16, 10 ], "texture": "#texture" },
+                "east":  { "uv": [  0,  7,  2, 10 ], "texture": "#texture" }
+            },
+            "__comment": "Lower bar left"
+        },
+        {   "from": [ 7, 6, 16 ],
+            "to": [ 9, 9, 18 ],
+            "faces": {
+                "down":  { "uv": [  7, 14,  9, 16 ], "texture": "#texture" },
+                "up":    { "uv": [  7,  0,  9,  2 ], "texture": "#texture" },
+                "south": { "uv": [  7,  7,  9, 10 ], "texture": "#texture" },
+                "west":  { "uv": [  0,  7,  2, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 14,  7, 16, 10 ], "texture": "#texture" }
+            },
+            "__comment": "Lower bar right"
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/inventory.json
new file mode 100644
index 000000000..a01e3bfc2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/post.json
new file mode 100644
index 000000000..a28f706a8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/side.json
new file mode 100644
index 000000000..9313c10ed
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/lightblue/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/inventory.json
new file mode 100644
index 000000000..d4f254182
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/post.json
new file mode 100644
index 000000000..7670fffaa
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/side.json
new file mode 100644
index 000000000..db33acdfd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/lime/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/inventory.json
new file mode 100644
index 000000000..ac0678612
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/post.json
new file mode 100644
index 000000000..4d8e0f6ae
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/side.json
new file mode 100644
index 000000000..2b68c5bb1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/magenta/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/inventory.json
new file mode 100644
index 000000000..94d5aa57e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/post.json
new file mode 100644
index 000000000..2acfeb18a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/side.json
new file mode 100644
index 000000000..723e72e6d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/oak/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/inventory.json
new file mode 100644
index 000000000..63580339b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/post.json
new file mode 100644
index 000000000..5e33cd1c3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/side.json
new file mode 100644
index 000000000..154f26d20
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/orange/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/inventory.json
new file mode 100644
index 000000000..e957efcd4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/post.json
new file mode 100644
index 000000000..98d903ce4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/side.json
new file mode 100644
index 000000000..9fbc54b42
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/pink/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/post.json
new file mode 100644
index 000000000..4f6a74386
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/post.json
@@ -0,0 +1,19 @@
+{
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "from": [ 6, 0, 6 ],
+            "to": [ 10, 16, 10 ],
+            "faces": {
+                "down":  { "uv": [ 6, 6, 10, 10 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [ 6, 6, 10, 10 ], "texture": "#texture", "cullface": "up" },
+                "north": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
+                "south": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
+                "east":  { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" }
+            },
+            "__comment": "Center post"
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/inventory.json
new file mode 100644
index 000000000..5779a0d48
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/post.json
new file mode 100644
index 000000000..700f14aa1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/side.json
new file mode 100644
index 000000000..118c95e2c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/purple/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/red/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/red/inventory.json
new file mode 100644
index 000000000..6d66c373a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/red/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/red/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/red/post.json
new file mode 100644
index 000000000..12da0e31d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/red/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/red/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/red/side.json
new file mode 100644
index 000000000..7bed39170
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/red/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/side.json
new file mode 100644
index 000000000..7145349ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/side.json
@@ -0,0 +1,29 @@
+{
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "from": [ 7, 12, 0 ],
+            "to": [ 9, 15, 9 ],
+            "faces": {
+                "down":  { "uv": [ 7, 0, 9, 9 ], "texture": "#texture" },
+                "up":    { "uv": [ 7, 0, 9, 9 ], "texture": "#texture" },
+                "north": { "uv": [ 7, 1, 9, 4 ], "texture": "#texture", "cullface": "north" },
+                "west":  { "uv": [ 0, 1, 9, 4 ], "texture": "#texture" },
+                "east":  { "uv": [ 0, 1, 9, 4 ], "texture": "#texture" }
+            },
+            "__comment": "top bar"
+        },
+        {   "from": [ 7, 6, 0 ],
+            "to": [ 9, 9, 9 ],
+            "faces": {
+                "down":  { "uv": [ 7, 0, 9,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 7, 0, 9,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 7, 7, 9, 10 ], "texture": "#texture", "cullface": "north" },
+                "west":  { "uv": [ 0, 7, 9, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 0, 7, 9, 10 ], "texture": "#texture" }
+            },
+            "__comment": "lower bar"
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/inventory.json
new file mode 100644
index 000000000..88afc67c4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/post.json
new file mode 100644
index 000000000..5bbc198fd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/side.json
new file mode 100644
index 000000000..892baf9ed
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/silver/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/white/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/white/inventory.json
new file mode 100644
index 000000000..354fa3959
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/white/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/white/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/white/post.json
new file mode 100644
index 000000000..2c255c610
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/white/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/white/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/white/side.json
new file mode 100644
index 000000000..b11be4b4a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/white/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/inventory.json
new file mode 100644
index 000000000..13539e076
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/post.json
new file mode 100644
index 000000000..817ed719b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/post",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/side.json
new file mode 100644
index 000000000..5cbd70f3a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence/yellow/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence/side",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/inventory.json
new file mode 100644
index 000000000..ab0eea1f1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/inventory.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/fence_thin/inventory",
+  "textures": {
+    "column": "minecraft:block/fence_chain/column",
+    "center": "minecraft:block/fence_chain/center"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/post.json
new file mode 100644
index 000000000..01aa7a90b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/post",
+  "textures": {
+    "column": "minecraft:block/fence_chain/column"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/side.json
new file mode 100644
index 000000000..80511c636
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/side",
+  "textures": {
+    "center": "minecraft:block/fence_chain/center"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/side_top.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/side_top.json
new file mode 100644
index 000000000..2a54bdf34
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/chain/side_top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/side",
+  "textures": {
+    "center": "minecraft:block/fence_chain/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/inventory.json
new file mode 100644
index 000000000..5790b26df
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/inventory.json
@@ -0,0 +1,63 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"display": {
+		"gui": {
+			"rotation": [ 30, 135, 0 ],
+			"translation": [ 0, 0, 0],
+			"scale":[ 0.625, 0.625, 0.625 ]
+		},
+		"fixed": {
+			"rotation": [ 0, 90, 0 ],
+			"translation": [ 0, 0, 0],
+			"scale":[ 0.5, 0.5, 0.5 ]
+		}
+	},
+	"textures": {
+		"overlay": "#column",
+		"particle_up": "#column",
+		"particle_down": "#column",
+		"particle_north": "#column",
+		"particle_south": "#column",
+		"particle_west": "#column",
+		"particle_east": "#column"
+	},
+	"elements": [
+		{
+			"from": [7, 0, 14],
+			"to": [9, 16, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 14]},
+			"faces": {
+				"north": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"east": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"south": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"west": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"up": {"uv": [0, 0, 2, 2], "texture": "#column", "cullface": "up"},
+				"down": {"uv": [0, 0, 2, 2], "texture": "#column", "cullface": "down"}
+			}
+		},
+		{
+			"from": [7, 0, 0],
+			"to": [9, 16, 2],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 0]},
+			"faces": {
+				"north": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"east": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"south": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"west": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"up": {"uv": [0, 0, 2, 2], "texture": "#column", "cullface": "up"},
+				"down": {"uv": [0, 0, 2, 2], "texture": "#column", "cullface": "down"}
+			}
+		},
+		{
+			"from": [8, 0, 0],
+			"to": [8, 16, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 0]},
+			"faces": {
+				"east": {"uv": [0, 0, 16, 16], "texture": "#center"},
+				"west": {"uv": [16, 0, 0, 16], "texture": "#center"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/inventory.json
new file mode 100644
index 000000000..42f8d4e6a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/inventory.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/fence_thin/inventory",
+  "textures": {
+    "column": "minecraft:block/fence_paper/column",
+    "center": "minecraft:block/fence_paper/center"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/post.json
new file mode 100644
index 000000000..01d66d481
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/post",
+  "textures": {
+    "column": "minecraft:block/fence_paper/column"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/side.json
new file mode 100644
index 000000000..57220fe4c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/side",
+  "textures": {
+    "center": "minecraft:block/fence_paper/center"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/side_top.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/side_top.json
new file mode 100644
index 000000000..57220fe4c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/paper/side_top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/side",
+  "textures": {
+    "center": "minecraft:block/fence_paper/center"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/post.json
new file mode 100644
index 000000000..61683f798
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/post.json
@@ -0,0 +1,28 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#column",
+		"particle_up": "#column",
+		"particle_down": "#column",
+		"particle_north": "#column",
+		"particle_south": "#column",
+		"particle_west": "#column",
+		"particle_east": "#column"
+	},
+	"elements": [
+		{
+			"from": [7, 0, 7],
+			"to": [9, 16, 9],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 7]},
+			"faces": {
+				"north": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"east": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"south": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"west": {"uv": [0, 0, 2, 16], "texture": "#column"},
+				"up": {"uv": [0, 0, 2, 2], "texture": "#column", "cullface": "up"},
+				"down": {"uv": [0, 0, 2, 2], "texture": "#column", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/side.json
new file mode 100644
index 000000000..0a3721b43
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/side.json
@@ -0,0 +1,24 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#center",
+		"particle_up": "#center",
+		"particle_down": "#center",
+		"particle_north": "#center",
+		"particle_south": "#center",
+		"particle_west": "#center",
+		"particle_east": "#center"
+	},
+	"elements": [
+		{
+			"from": [8, 0, 0],
+			"to": [8, 16, 8],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]},
+			"faces": {
+				"west": {"uv": [8, 0, 16, 16], "texture": "#center"},
+				"east": {"uv": [0, 0, 8, 16], "texture": "#center"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/inventory.json
new file mode 100644
index 000000000..179cc2633
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/inventory.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/fence_thin/inventory",
+  "textures": {
+    "column": "minecraft:block/fence_steel/column",
+    "center": "minecraft:block/fence_steel/center"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/post.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/post.json
new file mode 100644
index 000000000..9aee76724
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/post.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/post",
+  "textures": {
+    "column": "minecraft:block/fence_steel/column"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/side.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/side.json
new file mode 100644
index 000000000..45dd6030c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/side.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/side",
+  "textures": {
+    "center": "minecraft:block/fence_steel/center"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/side_top.json b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/side_top.json
new file mode 100644
index 000000000..eb690a539
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fence_thin/steel/side_top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fence_thin/side",
+  "textures": {
+    "center": "minecraft:block/fence_steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/black_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/black_closed.json
new file mode 100644
index 000000000..88f937602
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/black_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/black_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/black_open.json
new file mode 100644
index 000000000..2bb00c711
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/black_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/blue_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/blue_closed.json
new file mode 100644
index 000000000..4213499a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/blue_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/blue_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/blue_open.json
new file mode 100644
index 000000000..5a3dcd395
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/blue_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/brown_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/brown_closed.json
new file mode 100644
index 000000000..c09ffdee6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/brown_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/brown_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/brown_open.json
new file mode 100644
index 000000000..a17c9b80b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/brown_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/cyan_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/cyan_closed.json
new file mode 100644
index 000000000..d1d382d68
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/cyan_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/cyan_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/cyan_open.json
new file mode 100644
index 000000000..e628bb1f1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/cyan_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/gray_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/gray_closed.json
new file mode 100644
index 000000000..93b72b03a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/gray_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/gray_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/gray_open.json
new file mode 100644
index 000000000..1f8a48111
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/gray_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/green_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/green_closed.json
new file mode 100644
index 000000000..9894dce0a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/green_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/green_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/green_open.json
new file mode 100644
index 000000000..4233cdabe
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/green_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lightblue_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lightblue_closed.json
new file mode 100644
index 000000000..737137d69
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lightblue_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lightblue_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lightblue_open.json
new file mode 100644
index 000000000..fe9186809
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lightblue_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lime_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lime_closed.json
new file mode 100644
index 000000000..0543776f6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lime_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lime_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lime_open.json
new file mode 100644
index 000000000..27091f44b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/lime_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/magenta_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/magenta_closed.json
new file mode 100644
index 000000000..78f69954b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/magenta_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/magenta_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/magenta_open.json
new file mode 100644
index 000000000..0202d7926
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/magenta_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/oak_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/oak_closed.json
new file mode 100644
index 000000000..1dacc82c9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/oak_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/oak_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/oak_open.json
new file mode 100644
index 000000000..7916cd060
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/oak_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/orange_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/orange_closed.json
new file mode 100644
index 000000000..4a41716b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/orange_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/orange_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/orange_open.json
new file mode 100644
index 000000000..f7b9e8f6c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/orange_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/pink_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/pink_closed.json
new file mode 100644
index 000000000..b81f2ee12
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/pink_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/pink_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/pink_open.json
new file mode 100644
index 000000000..cb96896aa
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/pink_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/purple_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/purple_closed.json
new file mode 100644
index 000000000..24321de62
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/purple_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/purple_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/purple_open.json
new file mode 100644
index 000000000..eb7690378
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/purple_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/red_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/red_closed.json
new file mode 100644
index 000000000..ee2b3dd30
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/red_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/red_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/red_open.json
new file mode 100644
index 000000000..124faf800
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/red_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/silver_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/silver_closed.json
new file mode 100644
index 000000000..bc1266e2a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/silver_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/silver_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/silver_open.json
new file mode 100644
index 000000000..c10b6fc83
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/silver_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_closed.json
new file mode 100644
index 000000000..b1a090fa3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_closed.json
@@ -0,0 +1,107 @@
+{   "parent": "block/block",
+    "display": {
+        "gui": {
+            "rotation": [ 30, 45, 0 ],
+            "translation": [ 0, -1, 0],
+            "scale":[ 0.8, 0.8, 0.8 ]
+        },
+        "head": {
+            "rotation": [ 0, 0, 0 ],
+            "translation": [ 0, -3, -6],
+            "scale":[ 1, 1, 1]
+        }
+    },
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "__comment": "Left-hand post",
+            "from": [ 0, 5, 7 ],
+            "to": [ 2, 16, 9 ],
+            "faces": {
+                "down":  { "uv": [ 0, 7, 2,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 0, 7, 2,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" },
+                "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" },
+                "west":  { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" },
+                "east":  { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Right-hand post",
+            "from": [ 14, 5, 7 ],
+            "to": [ 16, 16, 9 ],
+            "faces": {
+                "down":  { "uv": [ 14, 7, 16,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 14, 7, 16,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" },
+                "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" },
+                "west":  { "uv": [  7, 0,  9, 11 ], "texture": "#texture" },
+                "east":  { "uv": [  7, 0,  9, 11 ], "texture": "#texture", "cullface": "east" }
+            }
+        },
+        {   "__comment": "Inner vertical post of left-hand gate door",
+            "from": [ 6, 6, 7 ],
+            "to": [ 8, 15, 9 ],
+            "faces": {
+                "down":  { "uv": [ 6, 7, 8,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 6, 7, 8,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" },
+                "south": { "uv": [ 6, 1, 8, 10 ], "texture": "#texture" },
+                "west":  { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 7, 1, 9, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Inner vertical post of right-hand gate door",
+            "from": [ 8, 6, 7 ],
+            "to": [ 10, 15, 9 ],
+            "faces": {
+                "down":  { "uv": [ 8, 7, 10,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 8, 7, 10,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" },
+                "south": { "uv": [ 8, 1, 10, 10 ], "texture": "#texture" },
+                "west":  { "uv": [ 7, 1,  9, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 7, 1,  9, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Lower horizontal bar of left-hand gate door",
+            "from": [ 2, 6, 7 ],
+            "to": [ 6, 9, 9 ],
+            "faces": {
+                "down":  { "uv": [ 2, 7, 6,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 2, 7, 6,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" },
+                "south": { "uv": [ 2, 7, 6, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Upper horizontal bar of left-hand gate door",
+            "from": [ 2, 12, 7 ],
+            "to": [ 6, 15, 9 ],
+            "faces": {
+                "down":  { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" },
+                "up":    { "uv": [ 2, 7, 6, 9 ], "texture": "#texture" },
+                "north": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" },
+                "south": { "uv": [ 2, 1, 6, 4 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Lower horizontal bar of right-hand gate door",
+            "from": [ 10, 6, 7 ],
+            "to": [ 14, 9, 9 ],
+            "faces": {
+                "down":  { "uv": [ 10, 7, 14,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 10, 7, 14,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" },
+                "south": { "uv": [ 10, 7, 14, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Upper horizontal bar of right-hand gate door",
+            "from": [ 10, 12, 7 ],
+            "to": [ 14, 15, 9 ],
+            "faces": {
+                "down":  { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" },
+                "up":    { "uv": [ 10, 7, 14, 9 ], "texture": "#texture" },
+                "north": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" },
+                "south": { "uv": [ 10, 1, 14, 4 ], "texture": "#texture" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_open.json
new file mode 100644
index 000000000..af2062a11
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/template_open.json
@@ -0,0 +1,95 @@
+{
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "__comment": "Left-hand post",
+            "from": [ 0, 5, 7 ],
+            "to": [ 2, 16, 9 ],
+            "faces": {
+                "down":  { "uv": [ 0, 7, 2,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 0, 7, 2,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" },
+                "south": { "uv": [ 0, 0, 2, 11 ], "texture": "#texture" },
+                "west":  { "uv": [ 7, 0, 9, 11 ], "texture": "#texture", "cullface": "west" },
+                "east":  { "uv": [ 7, 0, 9, 11 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Right-hand post",
+            "from": [ 14, 5, 7 ],
+            "to": [ 16, 16, 9 ],
+            "faces": {
+                "down":  { "uv": [ 14, 7, 16,  9 ], "texture": "#texture" },
+                "up":    { "uv": [ 14, 7, 16,  9 ], "texture": "#texture" },
+                "north": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" },
+                "south": { "uv": [ 14, 0, 16, 11 ], "texture": "#texture" },
+                "west":  { "uv": [  7, 0,  9, 11 ], "texture": "#texture" },
+                "east":  { "uv": [  7, 0,  9, 11 ], "texture": "#texture", "cullface": "east" }
+            }
+        },
+        {   "__comment": "Inner vertical post of left-hand gate door",
+            "from": [ 0, 6, 13 ],
+            "to": [ 2, 15, 15 ],
+            "faces": {
+                "down":  { "uv": [  0, 13,  2, 15 ], "texture": "#texture" },
+                "up":    { "uv": [  0, 13,  2, 15 ], "texture": "#texture" },
+                "north": { "uv": [  0,  1,  2, 10 ], "texture": "#texture" },
+                "south": { "uv": [  0,  1,  2, 10 ], "texture": "#texture" },
+                "west":  { "uv": [ 13,  1, 15, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 13,  1, 15, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Inner vertical post of right-hand gate door",
+            "from": [ 14, 6, 13 ],
+            "to": [ 16, 15, 15 ],
+            "faces": {
+                "down":  { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" },
+                "up":    { "uv": [ 14, 13, 16, 15 ], "texture": "#texture" },
+                "north": { "uv": [ 14,  1, 16, 10 ], "texture": "#texture" },
+                "south": { "uv": [ 14,  1, 16, 10 ], "texture": "#texture" },
+                "west":  { "uv": [ 13,  1, 15, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 13,  1, 15, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Lower horizontal bar of left-hand gate door",
+            "from": [ 0, 6, 9 ],
+            "to": [ 2, 9, 13 ],
+            "faces": {
+                "down":  { "uv": [  0, 9,  2, 13 ], "texture": "#texture" },
+                "up":    { "uv": [  0, 9,  2, 13 ], "texture": "#texture" },
+                "west":  { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Upper horizontal bar of left-hand gate door",
+            "from": [ 0, 12, 9 ],
+            "to": [ 2, 15, 13 ],
+            "faces": {
+                "down":  { "uv": [  0, 9,  2, 13 ], "texture": "#texture" },
+                "up":    { "uv": [  0, 9,  2, 13 ], "texture": "#texture" },
+                "west":  { "uv": [ 13, 1, 15,  4 ], "texture": "#texture" },
+                "east":  { "uv": [ 13, 1, 15,  4 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Lower horizontal bar of left-hand gate door",
+            "from": [ 14, 6, 9 ],
+            "to": [ 16, 9, 13 ],
+            "faces": {
+                "down":  { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" },
+                "up":    { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" },
+                "west":  { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" },
+                "east":  { "uv": [ 13, 7, 15, 10 ], "texture": "#texture" }
+            }
+        },
+        {   "__comment": "Upper horizontal bar of left-hand gate door",
+            "from": [ 14, 12, 9 ],
+            "to": [ 16, 15, 13 ],
+            "faces": {
+                "down":  { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" },
+                "up":    { "uv": [ 14, 9, 16, 13 ], "texture": "#texture" },
+                "west":  { "uv": [ 13, 1, 15,  4 ], "texture": "#texture" },
+                "east":  { "uv": [ 13, 1, 15,  4 ], "texture": "#texture" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/white_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/white_closed.json
new file mode 100644
index 000000000..e9cf30223
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/white_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/white_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/white_open.json
new file mode 100644
index 000000000..9ca2cdca6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/white_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/yellow_closed.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/yellow_closed.json
new file mode 100644
index 000000000..cc473704b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/yellow_closed.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_closed",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fencegate/yellow_open.json b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/yellow_open.json
new file mode 100644
index 000000000..5815fd8cc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fencegate/yellow_open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/fencegate/template_open",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/fern.json b/game/client/src/main/resources/assets/minecraft/models/block/fern.json
new file mode 100644
index 000000000..69449f649
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/fern.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/fern"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/0.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/0.json
new file mode 100644
index 000000000..5d01ec20c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_lightblue/0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/1.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/1.json
new file mode 100644
index 000000000..add0ed314
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_lightblue/1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/2.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/2.json
new file mode 100644
index 000000000..a2763546d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_lightblue/2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/3.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/3.json
new file mode 100644
index 000000000..a45e7a876
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_lightblue/3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_lightblue/3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/0.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/0.json
new file mode 100644
index 000000000..33ccafb14
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_orange/0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/1.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/1.json
new file mode 100644
index 000000000..5aa6321b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_orange/1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/2.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/2.json
new file mode 100644
index 000000000..f37b7247e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_orange/2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/3.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/3.json
new file mode 100644
index 000000000..e29b0ba9f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_orange/3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_orange/3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/0.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/0.json
new file mode 100644
index 000000000..583f936c1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_pink/0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/1.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/1.json
new file mode 100644
index 000000000..64eb7df86
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_pink/1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/2.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/2.json
new file mode 100644
index 000000000..d9619d59d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_pink/2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/3.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/3.json
new file mode 100644
index 000000000..8fe6d3340
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_pink/3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_pink/3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/0.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/0.json
new file mode 100644
index 000000000..fa102849a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_purple/0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/1.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/1.json
new file mode 100644
index 000000000..3827562e1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_purple/1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/2.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/2.json
new file mode 100644
index 000000000..a7a7cbf3b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_purple/2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/3.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/3.json
new file mode 100644
index 000000000..f6bffe8dd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_purple/3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_purple/3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_red/0.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/0.json
new file mode 100644
index 000000000..960c9843b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_red/0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_red/1.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/1.json
new file mode 100644
index 000000000..a8ed3fca1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_red/1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_red/2.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/2.json
new file mode 100644
index 000000000..5ea588882
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_red/2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_red/3.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/3.json
new file mode 100644
index 000000000..57b13a352
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_red/3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_red/3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/0.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/0.json
new file mode 100644
index 000000000..277656700
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_yellow/0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/1.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/1.json
new file mode 100644
index 000000000..cf8f52d0c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_yellow/1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/2.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/2.json
new file mode 100644
index 000000000..6f2f116b4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_yellow/2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/3.json b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/3.json
new file mode 100644
index 000000000..cd4c60e5f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/flower_yellow/3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/flower_yellow/3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active.json
new file mode 100644
index 000000000..f76da7d24
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_blast/top",
+    "down": "minecraft:block/furnace_blast/bottom",
+    "south": "minecraft:block/furnace_blast/side",
+    "north": "minecraft:block/furnace_blast/active_front",
+    "west": "minecraft:block/furnace_blast/side",
+    "east": "minecraft:block/furnace_blast/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active_filled.json
new file mode 100644
index 000000000..0f54ae353
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/active_filled.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_blast/top",
+    "down": "minecraft:block/furnace_blast/bottom",
+    "south": "minecraft:block/furnace_blast/side",
+    "north": "minecraft:block/furnace_blast/active_front_filled",
+    "west": "minecraft:block/furnace_blast/side",
+    "east": "minecraft:block/furnace_blast/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle.json
new file mode 100644
index 000000000..88cf9c1c9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_blast/top",
+    "down": "minecraft:block/furnace_blast/bottom",
+    "south": "minecraft:block/furnace_blast/side",
+    "north": "minecraft:block/furnace_blast/idle_front",
+    "west": "minecraft:block/furnace_blast/side",
+    "east": "minecraft:block/furnace_blast/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle_filled.json
new file mode 100644
index 000000000..a97a89097
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_blast/idle_filled.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_blast/top",
+    "down": "minecraft:block/furnace_blast/bottom",
+    "south": "minecraft:block/furnace_blast/side",
+    "north": "minecraft:block/furnace_blast/idle_front_filled",
+    "west": "minecraft:block/furnace_blast/side",
+    "east": "minecraft:block/furnace_blast/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active.json
new file mode 100644
index 000000000..9ac40ef37
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_stone/top",
+    "down": "minecraft:block/furnace_stone/bottom",
+    "south": "minecraft:block/furnace_stone/side",
+    "north": "minecraft:block/furnace_stone/active_front",
+    "west": "minecraft:block/furnace_stone/side",
+    "east": "minecraft:block/furnace_stone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active_filled.json
new file mode 100644
index 000000000..c0b1fef32
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/active_filled.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_stone/top",
+    "down": "minecraft:block/furnace_stone/bottom",
+    "south": "minecraft:block/furnace_stone/side",
+    "north": "minecraft:block/furnace_stone/active_front_filled",
+    "west": "minecraft:block/furnace_stone/side",
+    "east": "minecraft:block/furnace_stone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle.json
new file mode 100644
index 000000000..6e35ed373
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_stone/top",
+    "down": "minecraft:block/furnace_stone/bottom",
+    "south": "minecraft:block/furnace_stone/side",
+    "north": "minecraft:block/furnace_stone/idle_front",
+    "west": "minecraft:block/furnace_stone/side",
+    "east": "minecraft:block/furnace_stone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle_filled.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle_filled.json
new file mode 100644
index 000000000..4c234def2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone/idle_filled.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/furnace_stone/top",
+    "down": "minecraft:block/furnace_stone/bottom",
+    "south": "minecraft:block/furnace_stone/side",
+    "north": "minecraft:block/furnace_stone/idle_front_filled",
+    "west": "minecraft:block/furnace_stone/side",
+    "east": "minecraft:block/furnace_stone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone_idle.json b/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone_idle.json
deleted file mode 100644
index 6ac0b1d4e..000000000
--- a/game/client/src/main/resources/assets/minecraft/models/block/furnace_stone_idle.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "parent": "minecraft:block/orientable",
-  "textures": {
-    "front": "minecraft:block/furnace_stone/idle_front",
-    "side": "minecraft:block/furnace_stone/side",
-    "top": "minecraft:block/furnace_stone/top"
-  }
-}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/glass_steel.json b/game/client/src/main/resources/assets/minecraft/models/block/glass_steel.json
new file mode 100644
index 000000000..de3090a64
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/glass_steel.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/glass_steel"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/glowstone.json b/game/client/src/main/resources/assets/minecraft/models/block/glowstone.json
new file mode 100644
index 000000000..64b05023d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/glowstone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/glowstone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/granite.json b/game/client/src/main/resources/assets/minecraft/models/block/granite.json
new file mode 100644
index 000000000..def59d00c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/granite_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/granite_mossy.json
new file mode 100644
index 000000000..3c41b87a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/granite_mossy.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/template_mossy",
+  "textures": {
+    "base": "minecraft:block/granite",
+    "overlay": "minecraft:block/moss_overlay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/grass.json b/game/client/src/main/resources/assets/minecraft/models/block/grass.json
index ba0297669..ca93bf227 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/grass.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/grass.json
@@ -1,44 +1,48 @@
-{   "parent": "block/block",
-    "textures": {
-        "overlay": "#side",
-        "particle_up": "#top",
-        "particle_down": "#bottom",
-        "particle_north": "#side",
-        "particle_south": "#side",
-        "particle_west": "#side",
-        "particle_east": "#side",
-        "bottom": "block/dirt",
-        "top": "block/grass/top",
-        "side": "block/grass/side",
-        "render_overlay": "block/grass/side_overlay"
-    },
-    "particles": {
-        "down": -1,
-        "north": -1,
-        "south": -1,
-        "west": -1,
-        "east": -1
-    },
-    "elements": [
-        {   "from": [ 0, 0, 0 ],
-            "to": [ 16, 16, 16 ],
-            "faces": {
-                "down":  { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" },
-                "up":    { "uv": [ 0, 0, 16, 16 ], "texture": "#top",    "cullface": "up", "tintindex": 0 },
-                "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#side",   "cullface": "north" },
-                "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#side",   "cullface": "south" },
-                "west":  { "uv": [ 0, 0, 16, 16 ], "texture": "#side",   "cullface": "west" },
-                "east":  { "uv": [ 0, 0, 16, 16 ], "texture": "#side",   "cullface": "east" }
-            }
-        },
-        {   "from": [ 0, 0, 0 ],
-            "to": [ 16, 16, 16 ],
-            "faces": {
-                "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#render_overlay", "tintindex": 0, "cullface": "north" },
-                "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#render_overlay", "tintindex": 0, "cullface": "south" },
-                "west":  { "uv": [ 0, 0, 16, 16 ], "texture": "#render_overlay", "tintindex": 0, "cullface": "west" },
-                "east":  { "uv": [ 0, 0, 16, 16 ], "texture": "#render_overlay", "tintindex": 0, "cullface": "east" }
-            }
-        }
-    ]
-}
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/cube",
+	"textures": {
+		"down": "#bottom",
+		"up": "#top",
+		"north": "#side",
+		"east": "#side",
+		"south": "#side",
+		"west": "#side",
+		"bottom": "block/dirt",
+		"top": "block/grass/top",
+		"side": "block/grass/side",
+		"render_overlay": "block/grass/side_overlay"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "cullface": "up", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		},
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#render_overlay", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#render_overlay", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#render_overlay", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#render_overlay", "cullface": "west", "tintindex": 0}
+			}
+		}
+	],
+	"particles": {
+		"down": -1,
+		"north": -1,
+		"south": -1,
+		"west": -1,
+		"east": -1
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/grass_path.json b/game/client/src/main/resources/assets/minecraft/models/block/grass_path.json
new file mode 100644
index 000000000..56c4ea4a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/grass_path.json
@@ -0,0 +1,30 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/cube",
+	"textures": {
+      "down": "#bottom",
+      "up": "#top",
+      "north": "#side",
+      "east": "#side",
+      "south": "#side",
+      "west": "#side",
+      "bottom": "minecraft:block/grass_path/bottom",
+      "top": "minecraft:block/grass_path/top",
+      "side": "minecraft:block/grass_path/side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 15, 16],
+			"faces": {
+				"north": {"uv": [0, 1, 16, 16], "texture": "#side"},
+				"east": {"uv": [0, 1, 16, 16], "texture": "#side"},
+				"south": {"uv": [0, 1, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 1, 16, 16], "texture": "#side"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/grass_retro.json b/game/client/src/main/resources/assets/minecraft/models/block/grass_retro.json
new file mode 100644
index 000000000..e63c62803
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/grass_retro.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/grass_retro/top",
+    "bottom": "minecraft:block/grass_retro/bottom",
+    "side": "minecraft:block/grass_retro/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/grass_scorched.json b/game/client/src/main/resources/assets/minecraft/models/block/grass_scorched.json
new file mode 100644
index 000000000..72b47bf28
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/grass_scorched.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/grass_scorched/top",
+    "bottom": "minecraft:block/grass_scorched/bottom",
+    "side": "minecraft:block/grass_scorched/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/gravel.json b/game/client/src/main/resources/assets/minecraft/models/block/gravel.json
new file mode 100644
index 000000000..ed35aa8b9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/gravel.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/gravel"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ice.json b/game/client/src/main/resources/assets/minecraft/models/block/ice.json
new file mode 100644
index 000000000..af70344da
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ice.json
@@ -0,0 +1,7 @@
+{
+  "renderlayer": 1,
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ice"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/jar.json b/game/client/src/main/resources/assets/minecraft/models/block/jar.json
new file mode 100644
index 000000000..31c547a6c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/jar.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_jar",
+  "textures": {
+    "all": "minecraft:block/jar"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/jar_butterfly.json b/game/client/src/main/resources/assets/minecraft/models/block/jar_butterfly.json
new file mode 100644
index 000000000..b4a11045c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/jar_butterfly.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern",
+  "textures": {
+    "all": "minecraft:block/jar_butterfly"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/jar_butterfly_hanging.json b/game/client/src/main/resources/assets/minecraft/models/block/jar_butterfly_hanging.json
new file mode 100644
index 000000000..da525763f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/jar_butterfly_hanging.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern_hanging",
+  "textures": {
+    "all": "minecraft:block/jar_butterfly"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/jar_dirt.json b/game/client/src/main/resources/assets/minecraft/models/block/jar_dirt.json
new file mode 100644
index 000000000..37d4a55b2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/jar_dirt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_jar",
+  "textures": {
+    "all": "minecraft:block/jar_dirt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/jukebox.json b/game/client/src/main/resources/assets/minecraft/models/block/jukebox.json
new file mode 100644
index 000000000..283f06831
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/jukebox.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_top",
+	"textures": {
+		"top": "minecraft:block/jukebox",
+		"side": "minecraft:block/noteblock"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ladder.json b/game/client/src/main/resources/assets/minecraft/models/block/ladder.json
new file mode 100644
index 000000000..16408e498
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ladder.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"ambientocclusion": false,
+	"textures": {
+		"ladder": "block/ladder",
+		"overlay": "#ladder",
+		"particle_up": "#ladder",
+		"particle_down": "#ladder",
+		"particle_north": "#ladder",
+		"particle_south": "#ladder",
+		"particle_west": "#ladder",
+		"particle_east": "#ladder"
+	},
+	"elements": [
+		{
+			"shade": false,
+			"from": [0, 0, 1],
+			"to": [16, 16, 1],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 1]},
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#ladder"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#ladder"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/black.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/black.json
new file mode 100644
index 000000000..59ecd8f95
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/black_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/blue.json
new file mode 100644
index 000000000..54e80ee1a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/blue_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/brown.json
new file mode 100644
index 000000000..c8bca46ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/brown_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/cyan.json
new file mode 100644
index 000000000..cc3cbc1fe
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/cyan_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/gray.json
new file mode 100644
index 000000000..0117404d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/gray_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/green.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/green.json
new file mode 100644
index 000000000..4cf59ad9e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/green_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/lightblue.json
new file mode 100644
index 000000000..5bd09d21e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lightblue_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/lime.json
new file mode 100644
index 000000000..6d2bcdf46
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lime_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/magenta.json
new file mode 100644
index 000000000..687949c1f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/magenta_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/orange.json
new file mode 100644
index 000000000..258dcabd7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/orange_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/pink.json
new file mode 100644
index 000000000..fb9494a3d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/pink_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/purple.json
new file mode 100644
index 000000000..e26cf943e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/purple_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/red.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/red.json
new file mode 100644
index 000000000..c5ddd68c3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/red_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/silver.json
new file mode 100644
index 000000000..b76c188c9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/silver_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/white.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/white.json
new file mode 100644
index 000000000..9c5d8ff91
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/white_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/yellow.json
new file mode 100644
index 000000000..846dbbe52
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/yellow_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/black.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/black.json
new file mode 100644
index 000000000..59ecd8f95
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/black_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/blue.json
new file mode 100644
index 000000000..54e80ee1a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/blue_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/brown.json
new file mode 100644
index 000000000..c8bca46ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/brown_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/cyan.json
new file mode 100644
index 000000000..cc3cbc1fe
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/cyan_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/gray.json
new file mode 100644
index 000000000..0117404d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/gray_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/green.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/green.json
new file mode 100644
index 000000000..4cf59ad9e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/green_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/lightblue.json
new file mode 100644
index 000000000..5bd09d21e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lightblue_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/lime.json
new file mode 100644
index 000000000..6d2bcdf46
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lime_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/magenta.json
new file mode 100644
index 000000000..687949c1f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/magenta_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/orange.json
new file mode 100644
index 000000000..258dcabd7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/orange_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/pink.json
new file mode 100644
index 000000000..fb9494a3d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/pink_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/purple.json
new file mode 100644
index 000000000..e26cf943e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/purple_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/red.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/red.json
new file mode 100644
index 000000000..c5ddd68c3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/red_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/silver.json
new file mode 100644
index 000000000..b76c188c9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/silver_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/white.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/white.json
new file mode 100644
index 000000000..9c5d8ff91
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/white_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/yellow.json
new file mode 100644
index 000000000..846dbbe52
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/active_inverted/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/yellow_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/black.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/black.json
new file mode 100644
index 000000000..e54f4ae4c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/black_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/blue.json
new file mode 100644
index 000000000..8c5206fe7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/blue_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/brown.json
new file mode 100644
index 000000000..dc28763d0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/brown_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/cyan.json
new file mode 100644
index 000000000..2ab69e0a3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/cyan_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/gray.json
new file mode 100644
index 000000000..16e857862
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/gray_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/green.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/green.json
new file mode 100644
index 000000000..5ce23a83a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/green_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/lightblue.json
new file mode 100644
index 000000000..834028415
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lightblue_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/lime.json
new file mode 100644
index 000000000..525b97d45
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lime_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/magenta.json
new file mode 100644
index 000000000..72176d5ff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/magenta_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/orange.json
new file mode 100644
index 000000000..d91482922
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/orange_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/pink.json
new file mode 100644
index 000000000..b7434426f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/pink_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/purple.json
new file mode 100644
index 000000000..8f9ee4701
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/purple_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/red.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/red.json
new file mode 100644
index 000000000..c0ad41458
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/red_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/silver.json
new file mode 100644
index 000000000..cecd65907
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/silver_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/white.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/white.json
new file mode 100644
index 000000000..39d517613
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/white_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/yellow.json
new file mode 100644
index 000000000..225f3aa41
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/yellow_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/black.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/black.json
new file mode 100644
index 000000000..e54f4ae4c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/black_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/blue.json
new file mode 100644
index 000000000..8c5206fe7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/blue_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/brown.json
new file mode 100644
index 000000000..dc28763d0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/brown_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/cyan.json
new file mode 100644
index 000000000..2ab69e0a3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/cyan_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/gray.json
new file mode 100644
index 000000000..16e857862
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/gray_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/green.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/green.json
new file mode 100644
index 000000000..5ce23a83a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/green_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/lightblue.json
new file mode 100644
index 000000000..834028415
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lightblue_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/lime.json
new file mode 100644
index 000000000..525b97d45
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/lime_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/magenta.json
new file mode 100644
index 000000000..72176d5ff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/magenta_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/orange.json
new file mode 100644
index 000000000..d91482922
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/orange_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/pink.json
new file mode 100644
index 000000000..b7434426f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/pink_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/purple.json
new file mode 100644
index 000000000..8f9ee4701
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/purple_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/red.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/red.json
new file mode 100644
index 000000000..c0ad41458
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/red_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/silver.json
new file mode 100644
index 000000000..cecd65907
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/silver_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/white.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/white.json
new file mode 100644
index 000000000..39d517613
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/white_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/yellow.json
new file mode 100644
index 000000000..225f3aa41
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lamp/idle_inverted/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/lamp/yellow_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/blue.json
new file mode 100644
index 000000000..6f70e2533
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/blue_hanging.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/blue_hanging.json
new file mode 100644
index 000000000..33b8e424a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/blue_hanging.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern_hanging",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/green.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/green.json
new file mode 100644
index 000000000..b02fc017c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/green_hanging.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/green_hanging.json
new file mode 100644
index 000000000..a84694c1a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/green_hanging.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern_hanging",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/orange.json
new file mode 100644
index 000000000..2a1b27d14
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/orange_hanging.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/orange_hanging.json
new file mode 100644
index 000000000..1dcdc0fbf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/orange_hanging.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern_hanging",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/red.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/red.json
new file mode 100644
index 000000000..c597299a2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern_hanging",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/red_hanging.json b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/red_hanging.json
new file mode 100644
index 000000000..c597299a2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lantern_firefly/red_hanging.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_lantern_hanging",
+  "textures": {
+    "all": "minecraft:block/lantern_firefly/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/0.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/0.json
new file mode 100644
index 000000000..9869f16e3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/0.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height0",
+  "textures": {
+    "top": "minecraft:block/block_ash",
+    "bottom": "minecraft:block/block_ash",
+    "side": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/1.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/1.json
new file mode 100644
index 000000000..ee9feda70
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/1.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height1",
+  "textures": {
+    "top": "minecraft:block/block_ash",
+    "bottom": "minecraft:block/block_ash",
+    "side": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/2.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/2.json
new file mode 100644
index 000000000..a7dcd28be
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/2.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height2",
+  "textures": {
+    "top": "minecraft:block/block_ash",
+    "bottom": "minecraft:block/block_ash",
+    "side": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/3.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/3.json
new file mode 100644
index 000000000..092d2286b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/3.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height3",
+  "textures": {
+    "top": "minecraft:block/block_ash",
+    "bottom": "minecraft:block/block_ash",
+    "side": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/4.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/4.json
new file mode 100644
index 000000000..b547274f4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/4.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height4",
+  "textures": {
+    "top": "minecraft:block/block_ash",
+    "bottom": "minecraft:block/block_ash",
+    "side": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/5.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/5.json
new file mode 100644
index 000000000..d97db721c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/5.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height5",
+  "textures": {
+    "top": "minecraft:block/block_ash",
+    "bottom": "minecraft:block/block_ash",
+    "side": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/6.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/6.json
new file mode 100644
index 000000000..446c6a56c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/ash/6.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height6",
+  "textures": {
+    "top": "minecraft:block/block_ash",
+    "bottom": "minecraft:block/block_ash",
+    "side": "minecraft:block/block_ash"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height0.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height0.json
new file mode 100644
index 000000000..7ec21461c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height0.json
@@ -0,0 +1,28 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block_thin",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 2, 16],
+			"faces": {
+				"north": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height1.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height1.json
new file mode 100644
index 000000000..a1f14a3e4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height1.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 4, 16],
+			"faces": {
+				"north": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height2.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height2.json
new file mode 100644
index 000000000..295813254
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height2.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 6, 16],
+			"faces": {
+				"north": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height3.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height3.json
new file mode 100644
index 000000000..c70e1c9c0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height3.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 8, 16],
+			"faces": {
+				"north": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height4.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height4.json
new file mode 100644
index 000000000..9b7b0e7ac
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height4.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 10, 16],
+			"faces": {
+				"north": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height5.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height5.json
new file mode 100644
index 000000000..1c993e583
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height5.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 12, 16],
+			"faces": {
+				"north": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/height6.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/height6.json
new file mode 100644
index 000000000..f1f0632ec
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/height6.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 14, 16],
+			"faces": {
+				"north": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/0.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/0.json
new file mode 100644
index 000000000..dd98fd4d1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/0.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/tinted_height0",
+  "textures": {
+    "top": "minecraft:block/leaves/oak_fancy",
+    "bottom": "minecraft:block/leaves/oak_fancy",
+    "side": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/1.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/1.json
new file mode 100644
index 000000000..8468c274e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/1.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/tinted_height1",
+  "textures": {
+    "top": "minecraft:block/leaves/oak_fancy",
+    "bottom": "minecraft:block/leaves/oak_fancy",
+    "side": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/2.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/2.json
new file mode 100644
index 000000000..85cfa598e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/2.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/tinted_height2",
+  "textures": {
+    "top": "minecraft:block/leaves/oak_fancy",
+    "bottom": "minecraft:block/leaves/oak_fancy",
+    "side": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/3.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/3.json
new file mode 100644
index 000000000..2ebba1665
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/3.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/tinted_height3",
+  "textures": {
+    "top": "minecraft:block/leaves/oak_fancy",
+    "bottom": "minecraft:block/leaves/oak_fancy",
+    "side": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/4.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/4.json
new file mode 100644
index 000000000..3bb6dc209
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/4.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/tinted_height4",
+  "textures": {
+    "top": "minecraft:block/leaves/oak_fancy",
+    "bottom": "minecraft:block/leaves/oak_fancy",
+    "side": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/5.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/5.json
new file mode 100644
index 000000000..84e5ef80e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/5.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/tinted_height5",
+  "textures": {
+    "top": "minecraft:block/leaves/oak_fancy",
+    "bottom": "minecraft:block/leaves/oak_fancy",
+    "side": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/6.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/6.json
new file mode 100644
index 000000000..76914fd1d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/leaves_oak/6.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/tinted_height6",
+  "textures": {
+    "top": "minecraft:block/leaves/oak_fancy",
+    "bottom": "minecraft:block/leaves/oak_fancy",
+    "side": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/0.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/0.json
new file mode 100644
index 000000000..615e0f31b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/0.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height0",
+  "textures": {
+    "top": "minecraft:block/slate_top",
+    "bottom": "minecraft:block/slate_top",
+    "side": "minecraft:block/slate_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/1.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/1.json
new file mode 100644
index 000000000..fa9dc6ded
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/1.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height1",
+  "textures": {
+    "top": "minecraft:block/slate_top",
+    "bottom": "minecraft:block/slate_top",
+    "side": "minecraft:block/slate_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/2.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/2.json
new file mode 100644
index 000000000..39ddc58d5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/2.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height2",
+  "textures": {
+    "top": "minecraft:block/slate_top",
+    "bottom": "minecraft:block/slate_top",
+    "side": "minecraft:block/slate_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/3.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/3.json
new file mode 100644
index 000000000..75030018a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/3.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height3",
+  "textures": {
+    "top": "minecraft:block/slate_top",
+    "bottom": "minecraft:block/slate_top",
+    "side": "minecraft:block/slate_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/4.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/4.json
new file mode 100644
index 000000000..0e5ae1d7b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/4.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height4",
+  "textures": {
+    "top": "minecraft:block/slate_top",
+    "bottom": "minecraft:block/slate_top",
+    "side": "minecraft:block/slate_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/5.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/5.json
new file mode 100644
index 000000000..e3dfa54b3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/5.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height5",
+  "textures": {
+    "top": "minecraft:block/slate_top",
+    "bottom": "minecraft:block/slate_top",
+    "side": "minecraft:block/slate_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/6.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/6.json
new file mode 100644
index 000000000..a46bc094b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/slate/6.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height6",
+  "textures": {
+    "top": "minecraft:block/slate_top",
+    "bottom": "minecraft:block/slate_top",
+    "side": "minecraft:block/slate_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/0.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/0.json
new file mode 100644
index 000000000..97700b07e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/0.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height0",
+  "textures": {
+    "top": "minecraft:block/block_snow",
+    "bottom": "minecraft:block/block_snow",
+    "side": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/1.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/1.json
new file mode 100644
index 000000000..2b7c1e3f0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/1.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height1",
+  "textures": {
+    "top": "minecraft:block/block_snow",
+    "bottom": "minecraft:block/block_snow",
+    "side": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/2.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/2.json
new file mode 100644
index 000000000..41ee1c15c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/2.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height2",
+  "textures": {
+    "top": "minecraft:block/block_snow",
+    "bottom": "minecraft:block/block_snow",
+    "side": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/3.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/3.json
new file mode 100644
index 000000000..285e5950c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/3.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height3",
+  "textures": {
+    "top": "minecraft:block/block_snow",
+    "bottom": "minecraft:block/block_snow",
+    "side": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/4.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/4.json
new file mode 100644
index 000000000..dc7309bfc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/4.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height4",
+  "textures": {
+    "top": "minecraft:block/block_snow",
+    "bottom": "minecraft:block/block_snow",
+    "side": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/5.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/5.json
new file mode 100644
index 000000000..eeea241b5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/5.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height5",
+  "textures": {
+    "top": "minecraft:block/block_snow",
+    "bottom": "minecraft:block/block_snow",
+    "side": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/6.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/6.json
new file mode 100644
index 000000000..f6e3e3007
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/snow/6.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/layer/height6",
+  "textures": {
+    "top": "minecraft:block/block_snow",
+    "bottom": "minecraft:block/block_snow",
+    "side": "minecraft:block/block_snow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height0.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height0.json
new file mode 100644
index 000000000..5d3acbaff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height0.json
@@ -0,0 +1,28 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block_thin",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 2, 16],
+			"faces": {
+				"north": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height1.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height1.json
new file mode 100644
index 000000000..d0ba670df
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height1.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 4, 16],
+			"faces": {
+				"north": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height2.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height2.json
new file mode 100644
index 000000000..e94a3f0be
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height2.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 6, 16],
+			"faces": {
+				"north": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height3.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height3.json
new file mode 100644
index 000000000..cb6a9c4c7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height3.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 8, 16],
+			"faces": {
+				"north": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height4.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height4.json
new file mode 100644
index 000000000..789f93428
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height4.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 10, 16],
+			"faces": {
+				"north": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height5.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height5.json
new file mode 100644
index 000000000..6931e8e41
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height5.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 12, 16],
+			"faces": {
+				"north": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height6.json b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height6.json
new file mode 100644
index 000000000..ca097253e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/layer/tinted_height6.json
@@ -0,0 +1,27 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 14, 16],
+			"faces": {
+				"north": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fancy.json
new file mode 100644
index 000000000..b24281f8f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/birch_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fast.json
new file mode 100644
index 000000000..cd5b905f9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/birch"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fancy.json
new file mode 100644
index 000000000..fb03bbde3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/cacao_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fast.json
new file mode 100644
index 000000000..e921a3911
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/cacao"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage0.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage0.json
new file mode 100644
index 000000000..9172cbda7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/template_cacao_overlay",
+  "textures": {
+    "all": "minecraft:block/leaves/cacao_bean_stage0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage1.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage1.json
new file mode 100644
index 000000000..c624ab42d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/template_cacao_overlay",
+  "textures": {
+    "all": "minecraft:block/leaves/cacao_bean_stage1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage2.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage2.json
new file mode 100644
index 000000000..2020779ff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/template_cacao_overlay",
+  "textures": {
+    "all": "minecraft:block/leaves/cacao_bean_stage2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage3.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage3.json
new file mode 100644
index 000000000..6f8c5e68a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_overlay_stage3.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/template_cacao_overlay",
+  "textures": {
+    "all": "minecraft:block/leaves/cacao_bean_stage3"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fancy.json
new file mode 100644
index 000000000..15705f881
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/cherry_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fast.json
new file mode 100644
index 000000000..1ac0b79bf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/cherry"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_overlay.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_overlay.json
new file mode 100644
index 000000000..bf893fa79
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_overlay.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/leaves/cherry_overlay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_overlay_flowering.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_overlay_flowering.json
new file mode 100644
index 000000000..91ea6dec7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_overlay_flowering.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/leaves/cherry_flowering_overlay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fancy.json
new file mode 100644
index 000000000..d4be1165a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/eucalyptus_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fast.json
new file mode 100644
index 000000000..2d66169f1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/eucalyptus"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fancy.json
new file mode 100644
index 000000000..4dfb1ebfe
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fast.json
new file mode 100644
index 000000000..0840288e8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fancy.json
new file mode 100644
index 000000000..2399897f0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/oak_retro_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fast.json
new file mode 100644
index 000000000..821046f69
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/oak_retro"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fancy.json
new file mode 100644
index 000000000..e7ae1fb33
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/palm_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fast.json
new file mode 100644
index 000000000..01858cd52
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/palm"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fancy.json
new file mode 100644
index 000000000..55901ddae
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/pine_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fast.json
new file mode 100644
index 000000000..aed11efb9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/pine"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fancy.json
new file mode 100644
index 000000000..7d5794ee8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/shrub_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fast.json
new file mode 100644
index 000000000..0d034e480
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/shrub"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/template_cacao_overlay.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/template_cacao_overlay.json
new file mode 100644
index 000000000..d753f6bc9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/template_cacao_overlay.json
@@ -0,0 +1,33 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"overlay": "#all",
+		"particle_up": "#up",
+		"particle_down": "#down",
+		"particle_north": "#north",
+		"particle_south": "#south",
+		"particle_west": "#west",
+		"particle_east": "#east",
+		"down": "#all",
+		"up": "#all",
+		"north": "#all",
+		"east": "#all",
+		"south": "#all",
+		"west": "#all"
+	},
+	"elements": [
+		{
+			"name": "base",
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"color": 2,
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#all"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#all"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#all"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#all"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fancy.json
new file mode 100644
index 000000000..4a8ff6be2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fancy.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/caatinga_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fast.json
new file mode 100644
index 000000000..830da6934
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fast.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_leaves",
+  "textures": {
+    "all": "minecraft:block/leaves/caatinga"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lever_active.json b/game/client/src/main/resources/assets/minecraft/models/block/lever_active.json
new file mode 100644
index 000000000..78500aa2b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lever_active.json
@@ -0,0 +1,38 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "base": "block/cobbled_stone",
+        "lever": "block/lever_cobbled_stone",
+        "overlay": "#lever",
+        "particle_up": "#lever",
+        "particle_down": "#lever",
+        "particle_north": "#lever",
+        "particle_south": "#lever",
+        "particle_west": "#lever",
+        "particle_east": "#lever"
+    },
+    "elements": [
+        {   "from": [ 5, -0.02, 4 ],
+            "to": [ 11, 2.98, 12 ],
+            "faces": {
+                "down":  { "uv": [ 5, 4, 11, 12 ], "texture": "#base", "cullface": "down" },
+                "up":    { "uv": [ 5, 4, 11, 12 ], "texture": "#base" },
+                "north": { "uv": [ 5, 0, 11,  3 ], "texture": "#base" },
+                "south": { "uv": [ 5, 0, 11,  3 ], "texture": "#base" },
+                "west":  { "uv": [ 4, 0, 12,  3 ], "texture": "#base" },
+                "east":  { "uv": [ 4, 0, 12,  3 ], "texture": "#base" }
+            }
+        },
+        {   "from": [ 7, 1, 7 ],
+            "to": [ 9, 11, 9 ],
+            "rotation": { "origin": [ 8, 1, 8 ], "axis": "x", "angle": 45 },
+            "faces": {
+                "up":    { "uv": [ 7, 6, 9,  8 ], "texture": "#lever" },
+                "north": { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" },
+                "south": { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" },
+                "west":  { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" },
+                "east":  { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/lever_idle.json b/game/client/src/main/resources/assets/minecraft/models/block/lever_idle.json
new file mode 100644
index 000000000..80fa2945c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/lever_idle.json
@@ -0,0 +1,38 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "base": "block/cobbled_stone",
+        "lever": "block/lever_cobbled_stone",
+        "overlay": "#lever",
+        "particle_up": "#lever",
+        "particle_down": "#lever",
+        "particle_north": "#lever",
+        "particle_south": "#lever",
+        "particle_west": "#lever",
+        "particle_east": "#lever"
+    },
+    "elements": [
+        {   "from": [ 5, -0.02, 4 ],
+            "to": [ 11, 2.98, 12 ],
+            "faces": {
+                "down":  { "uv": [ 5, 4, 11, 12 ], "texture": "#base", "cullface": "down" },
+                "up":    { "uv": [ 5, 4, 11, 12 ], "texture": "#base" },
+                "north": { "uv": [ 5, 0, 11,  3 ], "texture": "#base" },
+                "south": { "uv": [ 5, 0, 11,  3 ], "texture": "#base" },
+                "west":  { "uv": [ 4, 0, 12,  3 ], "texture": "#base" },
+                "east":  { "uv": [ 4, 0, 12,  3 ], "texture": "#base" }
+            }
+        },
+        {   "from": [ 7, 1, 7 ],
+            "to": [ 9, 11, 9 ],
+            "rotation": { "origin": [ 8, 1, 8 ], "axis": "x", "angle": -45 },
+            "faces": {
+                "up":    { "uv": [ 7, 6, 9,  8 ], "texture": "#lever" },
+                "north": { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" },
+                "south": { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" },
+                "west":  { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" },
+                "east":  { "uv": [ 7, 6, 9, 16 ], "texture": "#lever" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/limestone.json
new file mode 100644
index 000000000..87f39b01d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/limestone_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/limestone_mossy.json
new file mode 100644
index 000000000..044694ead
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/limestone_mossy.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/template_mossy",
+  "textures": {
+    "base": "minecraft:block/limestone",
+    "overlay": "minecraft:block/moss_overlay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/birch.json b/game/client/src/main/resources/assets/minecraft/models/block/log/birch.json
new file mode 100644
index 000000000..187584ca6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/birch.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/birch_top",
+		"side": "minecraft:block/log/birch_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/cherry.json b/game/client/src/main/resources/assets/minecraft/models/block/log/cherry.json
new file mode 100644
index 000000000..652308e5f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/cherry.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/cherry_top",
+		"side": "minecraft:block/log/cherry_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/eucalyptus.json b/game/client/src/main/resources/assets/minecraft/models/block/log/eucalyptus.json
new file mode 100644
index 000000000..a1d3ba674
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/eucalyptus.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/eucalyptus_top",
+		"side": "minecraft:block/log/eucalyptus_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/oak.json b/game/client/src/main/resources/assets/minecraft/models/block/log/oak.json
new file mode 100644
index 000000000..118becdce
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/oak.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/oak_top",
+		"side": "minecraft:block/log/oak_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/oak_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/log/oak_mossy.json
new file mode 100644
index 000000000..0532936be
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/oak_mossy.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/oak_mossy_top",
+		"side": "minecraft:block/log/oak_mossy_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/palm.json b/game/client/src/main/resources/assets/minecraft/models/block/log/palm.json
new file mode 100644
index 000000000..e9e54603b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/palm.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/palm_top",
+		"side": "minecraft:block/log/palm_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/pine.json b/game/client/src/main/resources/assets/minecraft/models/block/log/pine.json
new file mode 100644
index 000000000..cd13fafc3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/pine.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/pine_top",
+		"side": "minecraft:block/log/pine_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/log/thorn.json b/game/client/src/main/resources/assets/minecraft/models/block/log/thorn.json
new file mode 100644
index 000000000..7cdef853c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/log/thorn.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/log/thorn_top",
+		"side": "minecraft:block/log/thorn_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/marble.json b/game/client/src/main/resources/assets/minecraft/models/block/marble.json
new file mode 100644
index 000000000..1ef081136
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/marble.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/marble"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/0.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/0.json
new file mode 100644
index 000000000..16603af3b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/0.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front0",
+		"side": "minecraft:block/matcher/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/1.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/1.json
new file mode 100644
index 000000000..4701d728a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/1.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front1",
+		"side": "minecraft:block/matcher/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/2.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/2.json
new file mode 100644
index 000000000..c27a25f77
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/2.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front2",
+		"side": "minecraft:block/matcher/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/3.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/3.json
new file mode 100644
index 000000000..5f4bc623d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/3.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front3",
+		"side": "minecraft:block/matcher/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/active0.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active0.json
new file mode 100644
index 000000000..914b3e633
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active0.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front_active0",
+		"side": "minecraft:block/matcher/side_active"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/active1.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active1.json
new file mode 100644
index 000000000..d25fad9bc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active1.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front_active1",
+		"side": "minecraft:block/matcher/side_active"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/active2.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active2.json
new file mode 100644
index 000000000..068806ee2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active2.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front_active2",
+		"side": "minecraft:block/matcher/side_active"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/matcher/active3.json b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active3.json
new file mode 100644
index 000000000..fb754ba60
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/matcher/active3.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/matcher/front_active3",
+		"side": "minecraft:block/matcher/side_active"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mesh.json b/game/client/src/main/resources/assets/minecraft/models/block/mesh.json
new file mode 100644
index 000000000..6135777b3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mesh.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/mesh"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mesh_gold.json b/game/client/src/main/resources/assets/minecraft/models/block/mesh_gold.json
new file mode 100644
index 000000000..8e69905b5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mesh_gold.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/mesh_gold"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mobspawner.json b/game/client/src/main/resources/assets/minecraft/models/block/mobspawner.json
new file mode 100644
index 000000000..489a459c1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mobspawner.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/mobspawner"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mobspawner_deactivated.json b/game/client/src/main/resources/assets/minecraft/models/block/mobspawner_deactivated.json
new file mode 100644
index 000000000..489a459c1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mobspawner_deactivated.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/mobspawner"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_active.json b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_active.json
new file mode 100644
index 000000000..688c988cd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_active.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/motion_sensor/side",
+    "down": "minecraft:block/motion_sensor/side",
+    "south": "minecraft:block/motion_sensor/side",
+    "north": "minecraft:block/motion_sensor/active_front",
+    "west": "minecraft:block/motion_sensor/side",
+    "east": "minecraft:block/motion_sensor/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_idle.json b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_idle.json
new file mode 100644
index 000000000..9923dee13
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/motion_sensor_idle.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/motion_sensor/side",
+    "down": "minecraft:block/motion_sensor/side",
+    "south": "minecraft:block/motion_sensor/side",
+    "north": "minecraft:block/motion_sensor/idle_front",
+    "west": "minecraft:block/motion_sensor/side",
+    "east": "minecraft:block/motion_sensor/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mud.json b/game/client/src/main/resources/assets/minecraft/models/block/mud.json
new file mode 100644
index 000000000..5cfbb594d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mud.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/mud"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mud_baked.json b/game/client/src/main/resources/assets/minecraft/models/block/mud_baked.json
new file mode 100644
index 000000000..fe0f1c7a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mud_baked.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/mud_baked"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mushroom_brown.json b/game/client/src/main/resources/assets/minecraft/models/block/mushroom_brown.json
new file mode 100644
index 000000000..a2e4837fa
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mushroom_brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/mushroom_brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/mushroom_red.json b/game/client/src/main/resources/assets/minecraft/models/block/mushroom_red.json
new file mode 100644
index 000000000..843acc630
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/mushroom_red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/mushroom_red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/crystal.json b/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/crystal.json
new file mode 100644
index 000000000..f54a7d0c0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/crystal.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cube_all",
+  "textures": {
+    "all": "minecraft:block/nether_crystal/crystal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/crystal_netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/crystal_netherrack.json
new file mode 100644
index 000000000..f7f55a363
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/crystal_netherrack.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/cube",
+	"textures": {
+		"base": "minecraft:block/nether_crystal/crystal_netherrack",
+		"overlay": "minecraft:block/nether_crystal/overlay",
+		"down": "#overlay",
+		"up": "#overlay",
+		"north": "#overlay",
+		"east": "#overlay",
+		"south": "#overlay",
+		"west": "#overlay"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#base", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#base", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#base", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#base", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#base", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#base", "cullface": "down"}
+			}
+		},
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#overlay", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#overlay", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#overlay", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#overlay", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#overlay", "cullface": "up", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#overlay", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/stalk.json b/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/stalk.json
new file mode 100644
index 000000000..7da83b822
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/nether_crystal/stalk.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/nether_crystal/stalk"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/netherrack.json
new file mode 100644
index 000000000..11cebf7ad
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/netherrack.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/noteblock.json b/game/client/src/main/resources/assets/minecraft/models/block/noteblock.json
new file mode 100644
index 000000000..a2cea71c6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/noteblock.json
@@ -0,0 +1,6 @@
+{
+	"parent": "minecraft:block/cube_all",
+	"textures": {
+		"all": "minecraft:block/noteblock"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/obsidian.json b/game/client/src/main/resources/assets/minecraft/models/block/obsidian.json
new file mode 100644
index 000000000..104a19940
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/obsidian.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/obsidian"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/basalt.json
new file mode 100644
index 000000000..17545d885
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/coal/basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/granite.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/granite.json
new file mode 100644
index 000000000..5e58597d5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/coal/granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/limestone.json
new file mode 100644
index 000000000..96b6254ad
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/coal/limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/permafrost.json
new file mode 100644
index 000000000..e579383d5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/coal/permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/stone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/stone.json
new file mode 100644
index 000000000..933cb8630
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/coal/stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/coal/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/basalt.json
new file mode 100644
index 000000000..d72aabdf2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/diamond/basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/granite.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/granite.json
new file mode 100644
index 000000000..3f394b3fd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/diamond/granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/limestone.json
new file mode 100644
index 000000000..526cbfa6b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/diamond/limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/permafrost.json
new file mode 100644
index 000000000..3d648bfe2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/diamond/permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/stone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/stone.json
new file mode 100644
index 000000000..2f473aa4c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/diamond/stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/diamond/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/basalt.json
new file mode 100644
index 000000000..aa20931d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/gold/basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/granite.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/granite.json
new file mode 100644
index 000000000..bebaf8e35
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/gold/granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/limestone.json
new file mode 100644
index 000000000..abcba53f0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/gold/limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/permafrost.json
new file mode 100644
index 000000000..8bfae4eb0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/gold/permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/stone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/stone.json
new file mode 100644
index 000000000..250b72868
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/gold/stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/gold/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/basalt.json
new file mode 100644
index 000000000..89d91c89f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/iron/basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/granite.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/granite.json
new file mode 100644
index 000000000..c318017fe
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/iron/granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/limestone.json
new file mode 100644
index 000000000..38ca76627
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/iron/limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/permafrost.json
new file mode 100644
index 000000000..9fd8d786a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/iron/permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/stone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/stone.json
new file mode 100644
index 000000000..1be795629
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/iron/stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/iron/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/basalt.json
new file mode 100644
index 000000000..fa46e969a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/lapis/basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/granite.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/granite.json
new file mode 100644
index 000000000..45a057055
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/lapis/granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/limestone.json
new file mode 100644
index 000000000..571f46a46
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/lapis/limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/permafrost.json
new file mode 100644
index 000000000..43fbee1f2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/lapis/permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/stone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/stone.json
new file mode 100644
index 000000000..540c4e45b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/lapis/stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/lapis/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/nethercoal/netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/nethercoal/netherrack.json
new file mode 100644
index 000000000..8c34c3d8e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/nethercoal/netherrack.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/nethercoal/netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/basalt.json
new file mode 100644
index 000000000..cd2bdfa18
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/basalt.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/basalt_active.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/basalt_active.json
new file mode 100644
index 000000000..2d50a7202
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/basalt_active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/basalt_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/granite.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/granite.json
new file mode 100644
index 000000000..4bb109934
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/granite.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/granite_active.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/granite_active.json
new file mode 100644
index 000000000..6ec011fb3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/granite_active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/granite_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/limestone.json
new file mode 100644
index 000000000..e9a6d2d0d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/limestone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/limestone_active.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/limestone_active.json
new file mode 100644
index 000000000..06be2edc3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/limestone_active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/limestone_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/permafrost.json
new file mode 100644
index 000000000..cc051462c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/permafrost_active.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/permafrost_active.json
new file mode 100644
index 000000000..92df3a48d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/permafrost_active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/permafrost_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/stone.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/stone.json
new file mode 100644
index 000000000..694ef1964
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/stone.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/stone_active.json b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/stone_active.json
new file mode 100644
index 000000000..7c4b3ec1e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/ore/redstone/stone_active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/ore/redstone/stone_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/ore_nethercoal_netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/ore_nethercoal_netherrack.json
deleted file mode 100644
index 2ac6d7672..000000000
--- a/game/client/src/main/resources/assets/minecraft/models/block/ore_nethercoal_netherrack.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "parent": "minecraft:block/cube_emissive_all",
-  "textures": {
-    "all": "minecraft:block/ore/nethercoal/netherrack",
-    "all_emissive": "minecraft:block/ore/nethercoal/netherrack_overlay"
-  }
-}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/overlay.json b/game/client/src/main/resources/assets/minecraft/models/block/overlay.json
new file mode 100644
index 000000000..f9778ee9a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/overlay.json
@@ -0,0 +1,21 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"particle_up": "#overlay",
+		"particle_down": "#overlay",
+		"particle_north": "#overlay",
+		"particle_south": "#overlay",
+		"particle_west": "#overlay",
+		"particle_east": "#overlay"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 1, 16],
+			"faces": {
+				"up": {"uv": [0, 0, 16, 16], "texture": "#overlay"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/paperwall.json b/game/client/src/main/resources/assets/minecraft/models/block/paperwall.json
new file mode 100644
index 000000000..05de83ecd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/paperwall.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/paperwall"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pebbles/0.json b/game/client/src/main/resources/assets/minecraft/models/block/pebbles/0.json
new file mode 100644
index 000000000..599e9616f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pebbles/0.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/overlay",
+  "textures": {
+    "overlay": "minecraft:block/pebbles/0"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pebbles/1.json b/game/client/src/main/resources/assets/minecraft/models/block/pebbles/1.json
new file mode 100644
index 000000000..d1de714a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pebbles/1.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/overlay",
+  "textures": {
+    "overlay": "minecraft:block/pebbles/1"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pebbles/2.json b/game/client/src/main/resources/assets/minecraft/models/block/pebbles/2.json
new file mode 100644
index 000000000..94bca3642
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pebbles/2.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/overlay",
+  "textures": {
+    "overlay": "minecraft:block/pebbles/2"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/permafrost.json
new file mode 100644
index 000000000..9167087aa
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/permafrost.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/permaice.json b/game/client/src/main/resources/assets/minecraft/models/block/permaice.json
new file mode 100644
index 000000000..b57cfbd32
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/permaice.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/permaice"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pillar_marble.json b/game/client/src/main/resources/assets/minecraft/models/block/pillar_marble.json
new file mode 100644
index 000000000..d7924121d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pillar_marble.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/pillar_marble/top",
+		"side": "minecraft:block/pillar_marble/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston/base.json b/game/client/src/main/resources/assets/minecraft/models/block/piston/base.json
new file mode 100644
index 000000000..00ec48e02
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston/base.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"display": {
+		"firstperson_righthand": {
+			"rotation": [0, 135, 0],
+			"scale": [0.4, 0.4, 0.4]
+		},
+		"firstperson_lefthand": {
+			"rotation": [0, 135, 0],
+			"scale": [0.4, 0.4, 0.4]
+		}
+	},
+	"textures": {
+		"bottom": "block/piston/bottom",
+		"side": "block/piston/side",
+		"face": "block/piston/face",
+		"overlay": "#face",
+		"particle_up": "#side",
+		"particle_down": "#side",
+		"particle_north": "#face",
+		"particle_south": "#bottom",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 16], "rotation": 180, "texture": "#side", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston/extended.json b/game/client/src/main/resources/assets/minecraft/models/block/piston/extended.json
new file mode 100644
index 000000000..a24ad77cc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston/extended.json
@@ -0,0 +1,30 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/piston/bottom",
+		"side": "block/piston/side",
+		"top": "block/piston/top",
+		"overlay": "#top",
+		"particle_up": "#side",
+		"particle_down": "#side",
+		"particle_north": "#top",
+		"particle_south": "#bottom",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 4],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"east": {"uv": [0, 4, 16, 16], "rotation": 90, "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "south"},
+				"west": {"uv": [0, 4, 16, 16], "rotation": 270, "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "up"},
+				"down": {"uv": [0, 4, 16, 16], "rotation": 180, "texture": "#side", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston/head.json b/game/client/src/main/resources/assets/minecraft/models/block/piston/head.json
new file mode 100644
index 000000000..b1107d71b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston/head.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"face": "block/piston/face",
+		"head": "block/piston/head",
+		"shaft": "block/piston/shaft",
+		"overlay": "#face",
+		"particle_up": "#head",
+		"particle_down": "#head",
+		"particle_north": "#face",
+		"particle_south": "#face",
+		"particle_west": "#head",
+		"particle_east": "#head"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 4],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"}
+			}
+		},
+		{
+			"from": [6, 6, 4],
+			"to": [10, 10, 20],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]},
+			"faces": {
+				"east": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#shaft"},
+				"west": {"uv": [10, 0, 6, 16], "rotation": 90, "texture": "#shaft"},
+				"up": {"uv": [6, 0, 10, 16], "texture": "#shaft"},
+				"down": {"uv": [10, 0, 6, 16], "texture": "#shaft"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston/head_half.json b/game/client/src/main/resources/assets/minecraft/models/block/piston/head_half.json
new file mode 100644
index 000000000..e638ca51f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston/head_half.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"face": "block/piston/face",
+		"head": "block/piston/head",
+		"shaft": "block/piston/shaft",
+		"overlay": "#face",
+		"particle_up": "#head",
+		"particle_down": "#head",
+		"particle_north": "#face",
+		"particle_south": "#face",
+		"particle_west": "#head",
+		"particle_east": "#head"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 4],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"}
+			}
+		},
+		{
+			"from": [6, 6, 4],
+			"to": [10, 10, 12],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]},
+			"faces": {
+				"east": {"uv": [6, 0, 10, 8], "rotation": 90, "texture": "#shaft"},
+				"west": {"uv": [10, 0, 6, 8], "rotation": 90, "texture": "#shaft"},
+				"up": {"uv": [6, 0, 10, 8], "texture": "#shaft"},
+				"down": {"uv": [10, 0, 6, 8], "texture": "#shaft"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/base.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/base.json
new file mode 100644
index 000000000..56cbb88b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/base.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"display": {
+		"firstperson_righthand": {
+			"rotation": [0, 135, 0],
+			"scale": [0.4, 0.4, 0.4]
+		},
+		"firstperson_lefthand": {
+			"rotation": [0, 135, 0],
+			"scale": [0.4, 0.4, 0.4]
+		}
+	},
+	"textures": {
+		"bottom": "block/piston_steel/bottom",
+		"side": "block/piston_steel/side",
+		"face": "block/piston_steel/face",
+		"overlay": "#face",
+		"particle_up": "#side",
+		"particle_down": "#side",
+		"particle_north": "#face",
+		"particle_south": "#bottom",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 16], "rotation": 180, "texture": "#side", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/extended.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/extended.json
new file mode 100644
index 000000000..6c857cdae
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/extended.json
@@ -0,0 +1,31 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"textures": {
+		"bottom": "block/piston_steel/bottom",
+		"side": "block/piston_steel/side",
+		"top": "block/piston_steel/top",
+		"overlay": "#top",
+		"particle_up": "#side",
+		"particle_down": "#side",
+		"particle_north": "#top",
+		"particle_south": "#bottom",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 6],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"east": {"uv": [0, 6, 16, 16], "rotation": 90, "texture": "#side"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom"},
+				"west": {"uv": [0, 6, 16, 16], "rotation": 270, "texture": "#side"},
+				"up": {"uv": [0, 6, 16, 16], "texture": "#side"},
+				"down": {"uv": [0, 6, 16, 16], "rotation": 180, "texture": "#side"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head.json
new file mode 100644
index 000000000..1678b1f46
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"face": "block/piston_steel/face",
+		"head": "block/piston_steel/head",
+		"shaft": "block/piston_steel/shaft",
+		"overlay": "#face",
+		"particle_up": "#head",
+		"particle_down": "#head",
+		"particle_north": "#face",
+		"particle_south": "#face",
+		"particle_west": "#head",
+		"particle_east": "#head"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 6],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 6], "rotation": 90, "texture": "#head"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 6], "rotation": 270, "texture": "#head", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 6], "texture": "#head", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#head", "cullface": "down"}
+			}
+		},
+		{
+			"from": [4, 4, 6],
+			"to": [12, 12, 22],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]},
+			"faces": {
+				"east": {"uv": [4, 0, 12, 16], "rotation": 90, "texture": "#shaft"},
+				"west": {"uv": [12, 0, 4, 16], "rotation": 90, "texture": "#shaft"},
+				"up": {"uv": [4, 0, 12, 16], "texture": "#shaft"},
+				"down": {"uv": [12, 0, 4, 16], "texture": "#shaft"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_half.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_half.json
new file mode 100644
index 000000000..bf91915d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_steel/head_half.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"face": "block/piston_steel/face",
+		"head": "block/piston_steel/head",
+		"shaft": "block/piston_steel/shaft",
+		"overlay": "#face",
+		"particle_up": "#head",
+		"particle_down": "#head",
+		"particle_north": "#face",
+		"particle_south": "#face",
+		"particle_west": "#head",
+		"particle_east": "#head"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 6],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 6], "rotation": 90, "texture": "#head"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 6], "rotation": 270, "texture": "#head", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 6], "texture": "#head", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#head", "cullface": "down"}
+			}
+		},
+		{
+			"from": [4, 4, 6],
+			"to": [12, 12, 14],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]},
+			"faces": {
+				"east": {"uv": [4, 0, 12, 8], "rotation": 90, "texture": "#shaft"},
+				"west": {"uv": [12, 0, 4, 8], "rotation": 90, "texture": "#shaft"},
+				"up": {"uv": [4, 0, 12, 8], "texture": "#shaft"},
+				"down": {"uv": [12, 0, 4, 8], "texture": "#shaft"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/base.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/base.json
new file mode 100644
index 000000000..ee2662224
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/base.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"display": {
+		"firstperson_righthand": {
+			"rotation": [0, 135, 0],
+			"scale": [0.4, 0.4, 0.4]
+		},
+		"firstperson_lefthand": {
+			"rotation": [0, 135, 0],
+			"scale": [0.4, 0.4, 0.4]
+		}
+	},
+	"textures": {
+		"bottom": "block/piston_sticky/bottom",
+		"side": "block/piston_sticky/side",
+		"face": "block/piston_sticky/face",
+		"overlay": "#face",
+		"particle_up": "#side",
+		"particle_down": "#side",
+		"particle_north": "#face",
+		"particle_south": "#bottom",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 16], "rotation": 180, "texture": "#side", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/extended.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/extended.json
new file mode 100644
index 000000000..1d2517713
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/extended.json
@@ -0,0 +1,30 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/piston_sticky/bottom",
+		"side": "block/piston_sticky/side",
+		"top": "block/piston_sticky/top",
+		"overlay": "#top",
+		"particle_up": "#side",
+		"particle_down": "#side",
+		"particle_north": "#top",
+		"particle_south": "#bottom",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 4],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"east": {"uv": [0, 4, 16, 16], "rotation": 90, "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "south"},
+				"west": {"uv": [0, 4, 16, 16], "rotation": 270, "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "up"},
+				"down": {"uv": [0, 4, 16, 16], "rotation": 180, "texture": "#side", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head.json
new file mode 100644
index 000000000..425d0cabe
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head.json
@@ -0,0 +1,42 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"face": "block/piston_sticky/face",
+		"back": "block/piston/face",
+		"head": "block/piston/head",
+		"shaft": "block/piston/shaft",
+		"overlay": "#face",
+		"particle_up": "#head",
+		"particle_down": "#head",
+		"particle_north": "#face",
+		"particle_south": "#back",
+		"particle_west": "#head",
+		"particle_east": "#head"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 4],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#back", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"}
+			}
+		},
+		{
+			"from": [6, 6, 4],
+			"to": [10, 10, 20],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]},
+			"faces": {
+				"east": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#shaft"},
+				"west": {"uv": [10, 0, 6, 16], "rotation": 90, "texture": "#shaft"},
+				"up": {"uv": [6, 0, 10, 16], "texture": "#shaft"},
+				"down": {"uv": [10, 0, 6, 16], "texture": "#shaft"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_half.json b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_half.json
new file mode 100644
index 000000000..fe345b6c1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/piston_sticky/head_half.json
@@ -0,0 +1,42 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"face": "block/piston_sticky/face",
+		"back": "block/piston/face",
+		"head": "block/piston/head",
+		"shaft": "block/piston/shaft",
+		"overlay": "#face",
+		"particle_up": "#head",
+		"particle_down": "#head",
+		"particle_north": "#face",
+		"particle_south": "#back",
+		"particle_west": "#head",
+		"particle_east": "#head"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 4],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#face", "cullface": "north"},
+				"east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#head"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#back", "cullface": "south"},
+				"west": {"uv": [0, 0, 16, 4], "rotation": 270, "texture": "#head", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 4], "texture": "#head", "cullface": "up"},
+				"down": {"uv": [0, 0, 16, 4], "rotation": 180, "texture": "#head", "cullface": "down"}
+			}
+		},
+		{
+			"from": [6, 6, 4],
+			"to": [10, 10, 12],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]},
+			"faces": {
+				"east": {"uv": [6, 0, 10, 8], "rotation": 90, "texture": "#shaft"},
+				"west": {"uv": [10, 0, 6, 8], "rotation": 90, "texture": "#shaft"},
+				"up": {"uv": [6, 0, 10, 8], "texture": "#shaft"},
+				"down": {"uv": [10, 0, 6, 8], "texture": "#shaft"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/black.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/black.json
new file mode 100644
index 000000000..5e22cb1d0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/blue.json
new file mode 100644
index 000000000..24b7e6ba7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/brown.json
new file mode 100644
index 000000000..81a06fd9b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/cyan.json
new file mode 100644
index 000000000..0fe3cc7a4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/gray.json
new file mode 100644
index 000000000..8b5f8f8ee
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/green.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/green.json
new file mode 100644
index 000000000..92cc5b80a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/lightblue.json
new file mode 100644
index 000000000..09ac96c1b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/lime.json
new file mode 100644
index 000000000..9b4b7d2cd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/magenta.json
new file mode 100644
index 000000000..bfc2bae5a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/oak.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/oak.json
new file mode 100644
index 000000000..8d1e69157
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/oak.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/orange.json
new file mode 100644
index 000000000..21a3d52b6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/pink.json
new file mode 100644
index 000000000..0073ad1ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/purple.json
new file mode 100644
index 000000000..828997683
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/red.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/red.json
new file mode 100644
index 000000000..5cfc462ec
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/silver.json
new file mode 100644
index 000000000..0e57db551
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/white.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/white.json
new file mode 100644
index 000000000..e330849ea
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/planks/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/planks/yellow.json
new file mode 100644
index 000000000..1228cae3a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/planks/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/polished_basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/polished_basalt.json
new file mode 100644
index 000000000..7718b9229
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/polished_basalt.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_basalt_top",
+		"side": "minecraft:block/polished_basalt_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/polished_granite.json b/game/client/src/main/resources/assets/minecraft/models/block/polished_granite.json
new file mode 100644
index 000000000..00e9bc706
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/polished_granite.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_granite_top",
+    "side": "minecraft:block/polished_granite_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/polished_limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/polished_limestone.json
new file mode 100644
index 000000000..bb7364c57
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/polished_limestone.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_limestone_top",
+    "side": "minecraft:block/polished_limestone_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/polished_netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/polished_netherrack.json
new file mode 100644
index 000000000..887dfbf84
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/polished_netherrack.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_netherrack_top",
+		"side": "minecraft:block/polished_netherrack_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/polished_permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/polished_permafrost.json
new file mode 100644
index 000000000..bf2494ab6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/polished_permafrost.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_permafrost_top",
+		"side": "minecraft:block/polished_permafrost_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/polished_slate.json b/game/client/src/main/resources/assets/minecraft/models/block/polished_slate.json
new file mode 100644
index 000000000..97066ada3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/polished_slate.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/polished_slate_top",
+		"side": "minecraft:block/polished_slate_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/polished_stone.json b/game/client/src/main/resources/assets/minecraft/models/block/polished_stone.json
new file mode 100644
index 000000000..ebbbb72cf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/polished_stone.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_stone_top",
+    "side": "minecraft:block/polished_stone_side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/black.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/black.json
new file mode 100644
index 000000000..68cd5fbba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/blue.json
new file mode 100644
index 000000000..8c9ec442e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/brown.json
new file mode 100644
index 000000000..9dc67c84c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/cyan.json
new file mode 100644
index 000000000..d6c7282ff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/gray.json
new file mode 100644
index 000000000..a0b6e5817
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/green.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/green.json
new file mode 100644
index 000000000..989b55bdf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/lightblue.json
new file mode 100644
index 000000000..591d843b6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/lime.json
new file mode 100644
index 000000000..a42d649d5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/magenta.json
new file mode 100644
index 000000000..adc044aa7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/orange.json
new file mode 100644
index 000000000..037c302aa
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/pink.json
new file mode 100644
index 000000000..386e0d566
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/purple.json
new file mode 100644
index 000000000..95b1a20e1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/red.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/red.json
new file mode 100644
index 000000000..e38fde283
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/silver.json
new file mode 100644
index 000000000..fd9be7f09
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/white.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/white.json
new file mode 100644
index 000000000..5e175fbdb
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/yellow.json
new file mode 100644
index 000000000..5b483e7e8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_drift/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_drift/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/black.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/black.json
new file mode 100644
index 000000000..629cda6ec
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/blue.json
new file mode 100644
index 000000000..a466e358d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/brown.json
new file mode 100644
index 000000000..4bb5938e9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/cyan.json
new file mode 100644
index 000000000..61ed48d21
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/gray.json
new file mode 100644
index 000000000..ee9fb3ca7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/green.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/green.json
new file mode 100644
index 000000000..35d432c95
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/lightblue.json
new file mode 100644
index 000000000..712d8dfa0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/lime.json
new file mode 100644
index 000000000..1e706605d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/magenta.json
new file mode 100644
index 000000000..48cafab81
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/orange.json
new file mode 100644
index 000000000..0197cee09
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/pink.json
new file mode 100644
index 000000000..8a1049681
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/purple.json
new file mode 100644
index 000000000..614f2cae7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/red.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/red.json
new file mode 100644
index 000000000..b4a1a4e21
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/silver.json
new file mode 100644
index 000000000..8d10f36a3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/white.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/white.json
new file mode 100644
index 000000000..59d838625
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/yellow.json
new file mode 100644
index 000000000..35ae8ba84
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/portal_nether/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_portal",
+  "textures": {
+    "all": "minecraft:block/portal_nether/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/active.json
new file mode 100644
index 000000000..d341072f2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/active.json
@@ -0,0 +1,24 @@
+{
+    "textures": {
+        "overlay": "#texture",
+        "particle_up": "#texture",
+        "particle_down": "#texture",
+        "particle_north": "#texture",
+        "particle_south": "#texture",
+        "particle_west": "#texture",
+        "particle_east": "#texture"
+    },
+    "elements": [
+        {   "from": [ 1, 0, 1 ],
+            "to": [ 15, 0.5, 15 ],
+            "faces": {
+                "down":  { "uv": [ 1,    1, 15, 15 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [ 1,    1, 15, 15 ], "texture": "#texture" },
+                "north": { "uv": [ 1, 15, 15, 15.5 ], "texture": "#texture" },
+                "south": { "uv": [ 1, 15, 15, 15.5 ], "texture": "#texture" },
+                "west":  { "uv": [ 1, 15, 15, 15.5 ], "texture": "#texture" },
+                "east":  { "uv": [ 1, 15, 15, 15.5 ], "texture": "#texture" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/active.json
new file mode 100644
index 000000000..7ed36a8a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/cobbled_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/idle.json
new file mode 100644
index 000000000..c96cb8243
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/cobbled_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/inventory.json
new file mode 100644
index 000000000..f4ca08538
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/cobbled_stone/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/cobbled_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/idle.json
new file mode 100644
index 000000000..4cf799ac0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/idle.json
@@ -0,0 +1,24 @@
+{   "parent": "block/block_thin",
+    "textures": {
+        "overlay": "#texture",
+        "particle_up": "#texture",
+        "particle_down": "#texture",
+        "particle_north": "#texture",
+        "particle_south": "#texture",
+        "particle_west": "#texture",
+        "particle_east": "#texture"
+    },
+    "elements": [
+        {   "from": [ 1, 0, 1 ],
+            "to": [ 15, 1, 15 ],
+            "faces": {
+                "down":  { "uv": [ 1,  1, 15, 15 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [ 1,  1, 15, 15 ], "texture": "#texture" },
+                "north": { "uv": [ 1, 15, 15, 16 ], "texture": "#texture" },
+                "south": { "uv": [ 1, 15, 15, 16 ], "texture": "#texture" },
+                "west":  { "uv": [ 1, 15, 15, 16 ], "texture": "#texture" },
+                "east":  { "uv": [ 1, 15, 15, 16 ], "texture": "#texture" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/inventory.json
new file mode 100644
index 000000000..f6884679f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/inventory.json
@@ -0,0 +1,51 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"display": {
+		"gui": {
+			"rotation": [ 30, 225, 0 ],
+			"translation": [ 0, 2, 0],
+			"scale":[ 0.625, 0.625, 0.625 ]
+		},
+		"thirdperson_righthand": {
+			"rotation": [ 75, 45, 0 ],
+			"translation": [ 0, 0.5, 2],
+			"scale": [ 0.375, 0.375, 0.375 ]
+		},
+		"firstperson_righthand": {
+			"rotation": [ 0, 45, 0 ],
+			"translation": [ 0, 2.2, 0 ],
+			"scale": [ 0.40, 0.40, 0.40 ]
+		},
+		"firstperson_lefthand": {
+			"rotation": [ 0, 225, 0 ],
+			"translation": [ 0, 2.2, 0 ],
+			"scale": [ 0.40, 0.40, 0.40 ]
+		}
+	},
+	"textures": {
+		"overlay": "#texture",
+		"particle_up": "#texture",
+		"particle_down": "#texture",
+		"particle_north": "#texture",
+		"particle_south": "#texture",
+		"particle_west": "#texture",
+		"particle_east": "#texture"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 4, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, -1]},
+			"faces": {
+				"north": {"uv": [0, 12, 16, 16], "texture": "#texture"},
+				"east": {"uv": [0, 12, 16, 16], "texture": "#texture"},
+				"south": {"uv": [0, 12, 16, 16], "texture": "#texture"},
+				"west": {"uv": [0, 12, 16, 16], "texture": "#texture"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#texture"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#texture", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/active.json
new file mode 100644
index 000000000..0d24aa009
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/idle.json
new file mode 100644
index 000000000..3f17a8dc5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/inventory.json
new file mode 100644
index 000000000..1e70a5256
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/black/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/active.json
new file mode 100644
index 000000000..09e7e213b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/idle.json
new file mode 100644
index 000000000..61e2f25da
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/inventory.json
new file mode 100644
index 000000000..1198db51e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/blue/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/active.json
new file mode 100644
index 000000000..44d5376d6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/idle.json
new file mode 100644
index 000000000..ebdd2ed08
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/inventory.json
new file mode 100644
index 000000000..3cbe3c6a7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/brown/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/active.json
new file mode 100644
index 000000000..ead39b82f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/idle.json
new file mode 100644
index 000000000..0382034d9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/inventory.json
new file mode 100644
index 000000000..d85ad423d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/cyan/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/active.json
new file mode 100644
index 000000000..eb7219f0a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/idle.json
new file mode 100644
index 000000000..b30f12ed2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/inventory.json
new file mode 100644
index 000000000..6dd55a046
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/gray/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/active.json
new file mode 100644
index 000000000..b0113714e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/idle.json
new file mode 100644
index 000000000..985cb6aee
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/inventory.json
new file mode 100644
index 000000000..7da09b699
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/green/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/active.json
new file mode 100644
index 000000000..850776f81
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/idle.json
new file mode 100644
index 000000000..aae5b7bee
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/inventory.json
new file mode 100644
index 000000000..3dd46ebdc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lightblue/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/active.json
new file mode 100644
index 000000000..c3e5f7b75
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/idle.json
new file mode 100644
index 000000000..b4501f1aa
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/inventory.json
new file mode 100644
index 000000000..761fed26a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/lime/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/active.json
new file mode 100644
index 000000000..53908962c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/idle.json
new file mode 100644
index 000000000..20a05f39b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/inventory.json
new file mode 100644
index 000000000..6e562b3b6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/magenta/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/active.json
new file mode 100644
index 000000000..97882376e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/idle.json
new file mode 100644
index 000000000..99fbe016b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/inventory.json
new file mode 100644
index 000000000..a464db055
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/oak/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/active.json
new file mode 100644
index 000000000..bf92f16b4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/idle.json
new file mode 100644
index 000000000..12ef1659f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/inventory.json
new file mode 100644
index 000000000..48421ec37
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/orange/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/active.json
new file mode 100644
index 000000000..8e0dcef9c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/idle.json
new file mode 100644
index 000000000..35fe11438
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/inventory.json
new file mode 100644
index 000000000..ed9617cb4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/pink/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/active.json
new file mode 100644
index 000000000..111590e55
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/idle.json
new file mode 100644
index 000000000..6f76e164b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/inventory.json
new file mode 100644
index 000000000..66a917e67
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/purple/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/active.json
new file mode 100644
index 000000000..5c9456f6f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/idle.json
new file mode 100644
index 000000000..025682513
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/inventory.json
new file mode 100644
index 000000000..c23288ab2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/red/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/active.json
new file mode 100644
index 000000000..8f0b3dc6a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/idle.json
new file mode 100644
index 000000000..4aa01d1a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/inventory.json
new file mode 100644
index 000000000..910b47769
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/silver/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/active.json
new file mode 100644
index 000000000..3bc134e17
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/idle.json
new file mode 100644
index 000000000..3828c7267
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/inventory.json
new file mode 100644
index 000000000..b4b59e38f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/white/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/active.json
new file mode 100644
index 000000000..ae815488b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/idle.json
new file mode 100644
index 000000000..61f7204f2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/inventory.json
new file mode 100644
index 000000000..63328a206
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/planks/yellow/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/active.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/active.json
new file mode 100644
index 000000000..03f11e23b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/active",
+  "textures": {
+    "texture": "minecraft:block/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/idle.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/idle.json
new file mode 100644
index 000000000..c620f1ff4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/idle",
+  "textures": {
+    "texture": "minecraft:block/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/inventory.json b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/inventory.json
new file mode 100644
index 000000000..991c2f371
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pressure_plate/stone/inventory.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/pressure_plate/inventory",
+  "textures": {
+    "texture": "minecraft:block/stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumice.json b/game/client/src/main/resources/assets/minecraft/models/block/pumice.json
new file mode 100644
index 000000000..f86a9eb35
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumice.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/pumice"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumice_wet.json b/game/client/src/main/resources/assets/minecraft/models/block/pumice_wet.json
new file mode 100644
index 000000000..9f8aa67c1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumice_wet.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/cube",
+	"textures": {
+		"base": "minecraft:block/lava_still",
+		"overlay": "minecraft:block/pumice_overlay",
+		"down": "#overlay",
+		"up": "#overlay",
+		"north": "#overlay",
+		"east": "#overlay",
+		"south": "#overlay",
+		"west": "#overlay"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#base"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#base"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#base"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#base"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#base"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#base"}
+			}
+		},
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#overlay"},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#overlay"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#overlay"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#overlay"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#overlay"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#overlay"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin.json
new file mode 100644
index 000000000..ceae1d97f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/pumpkin/top",
+    "bottom": "minecraft:block/pumpkin/bottom",
+    "side": "minecraft:block/pumpkin/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved.json
new file mode 100644
index 000000000..4aec1b871
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/pumpkin_carved/top",
+    "down": "minecraft:block/pumpkin_carved/bottom",
+    "south": "minecraft:block/pumpkin_carved/side",
+    "north": "minecraft:block/pumpkin_carved/front",
+    "west": "minecraft:block/pumpkin_carved/side",
+    "east": "minecraft:block/pumpkin_carved/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved_lit.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved_lit.json
new file mode 100644
index 000000000..512ca88b7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_carved_lit.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/pumpkin_carved_lit/top",
+    "down": "minecraft:block/pumpkin_carved_lit/bottom",
+    "south": "minecraft:block/pumpkin_carved_lit/side",
+    "north": "minecraft:block/pumpkin_carved_lit/front",
+    "west": "minecraft:block/pumpkin_carved_lit/side",
+    "east": "minecraft:block/pumpkin_carved_lit/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/0.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/0.json
new file mode 100644
index 000000000..6b22a2eb5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/0.json
@@ -0,0 +1,30 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/pumpkin_pie/bottom",
+		"side": "block/pumpkin_pie/side",
+		"top": "block/pumpkin_pie/top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [1, 0, 1],
+			"to": [15, 6, 15],
+			"faces": {
+				"north": {"uv": [1, 10, 15, 16], "texture": "#side"},
+				"east": {"uv": [1, 10, 15, 16], "texture": "#side"},
+				"south": {"uv": [1, 10, 15, 16], "texture": "#side"},
+				"west": {"uv": [1, 10, 15, 16], "texture": "#side"},
+				"up": {"uv": [1, 1, 15, 15], "texture": "#top"},
+				"down": {"uv": [1, 1, 15, 15], "texture": "#bottom"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/1.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/1.json
new file mode 100644
index 000000000..f7c409119
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/1.json
@@ -0,0 +1,43 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/pumpkin_pie/bottom",
+		"inner": "block/pumpkin_pie/inner",
+		"side": "block/pumpkin_pie/side",
+		"top": "block/pumpkin_pie/top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [1, 0, 8],
+			"to": [8, 6, 15],
+			"faces": {
+				"north": {"uv": [8, 10, 15, 16], "texture": "#inner"},
+				"south": {"uv": [1, 10, 8, 16], "texture": "#side"},
+				"west": {"uv": [8, 10, 15, 16], "texture": "#side"},
+				"up": {"uv": [1, 8, 8, 15], "texture": "#top"},
+				"down": {"uv": [1, 1, 8, 8], "texture": "#bottom", "cullface": "down"}
+			}
+		},
+		{
+			"from": [8, 0, 1],
+			"to": [15, 6, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 0]},
+			"faces": {
+				"north": {"uv": [1, 10, 8, 16], "texture": "#side"},
+				"east": {"uv": [1, 10, 15, 16], "texture": "#side"},
+				"south": {"uv": [8, 10, 15, 16], "texture": "#side"},
+				"west": {"uv": [15, 10, 1, 16], "texture": "#inner"},
+				"up": {"uv": [8, 1, 15, 15], "texture": "#top"},
+				"down": {"uv": [8, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/2.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/2.json
new file mode 100644
index 000000000..121aef025
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/2.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/pumpkin_pie/bottom",
+		"inner": "block/pumpkin_pie/inner",
+		"side": "block/pumpkin_pie/side",
+		"top": "block/pumpkin_pie/top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#inner",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [8, 0, 1],
+			"to": [15, 6, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 0]},
+			"faces": {
+				"north": {"uv": [1, 10, 8, 16], "texture": "#side"},
+				"east": {"uv": [1, 10, 15, 16], "texture": "#side"},
+				"south": {"uv": [8, 10, 15, 16], "texture": "#side"},
+				"west": {"uv": [15, 10, 1, 16], "texture": "#inner"},
+				"up": {"uv": [8, 1, 15, 15], "texture": "#top"},
+				"down": {"uv": [8, 1, 15, 15], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/3.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/3.json
new file mode 100644
index 000000000..abcac12f9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_pie/3.json
@@ -0,0 +1,32 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/pumpkin_pie/bottom",
+		"inner": "block/pumpkin_pie/inner",
+		"side": "block/pumpkin_pie/side",
+		"top": "block/pumpkin_pie/top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#inner",
+		"particle_south": "#side",
+		"particle_west": "#inner",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [8, 0, 8],
+			"to": [15, 6, 15],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 0, 0]},
+			"faces": {
+				"north": {"uv": [1, 10, 8, 16], "texture": "#inner"},
+				"east": {"uv": [1, 10, 8, 16], "texture": "#side"},
+				"south": {"uv": [8, 10, 15, 16], "texture": "#side"},
+				"west": {"uv": [8, 10, 1, 16], "texture": "#inner"},
+				"up": {"uv": [8, 8, 15, 15], "texture": "#top"},
+				"down": {"uv": [8, 1, 15, 8], "texture": "#bottom", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_redstone.json b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_redstone.json
new file mode 100644
index 000000000..3322c8129
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/pumpkin_redstone.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube",
+  "textures": {
+    "up": "minecraft:block/pumpkin_redstone/top",
+    "down": "minecraft:block/pumpkin_redstone/bottom",
+    "south": "minecraft:block/pumpkin_redstone/side",
+    "north": "minecraft:block/pumpkin_redstone/front",
+    "west": "minecraft:block/pumpkin_redstone/side",
+    "east": "minecraft:block/pumpkin_redstone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/0.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/0.json
new file mode 100644
index 000000000..de2831390
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/0.json
@@ -0,0 +1,50 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/idle_top",
+        "unlit": "minecraft:block/torch_redstone_idle",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 2, 6 ],
+            "to": [ 9, 7, 8 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        },
+        {   "from": [ 7, 2, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/1.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/1.json
new file mode 100644
index 000000000..4663ef360
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/1.json
@@ -0,0 +1,50 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/idle_top",
+        "unlit": "minecraft:block/torch_redstone_idle",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 2, 8 ],
+            "to": [ 9, 7, 10 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        },
+        {   "from": [ 7, 2, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/2.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/2.json
new file mode 100644
index 000000000..4fccda6c1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/2.json
@@ -0,0 +1,50 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/idle_top",
+        "unlit": "minecraft:block/torch_redstone_idle",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 2, 10 ],
+            "to": [ 9, 7, 12 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        },
+        {   "from": [ 7, 2, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/3.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/3.json
new file mode 100644
index 000000000..d51e72e03
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/3.json
@@ -0,0 +1,50 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/idle_top",
+        "unlit": "minecraft:block/torch_redstone_idle",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 2, 12 ],
+            "to": [ 9, 7, 14 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        },
+        {   "from": [ 7, 2, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#unlit" },
+                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#unlit" },
+                "north": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "south": { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "west":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" },
+                "east":  { "uv": [ 7,  6, 9, 11 ], "texture": "#unlit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/active0.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active0.json
new file mode 100644
index 000000000..a0f6e2256
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active0.json
@@ -0,0 +1,68 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/active_top",
+        "lit": "minecraft:block/torch_redstone_active",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 7, 6 ],
+            "to": [ 9, 7, 8 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 5 ],
+            "to": [ 9, 8, 9 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 6 ],
+            "to": [ 10, 8, 8 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 7, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 1 ],
+            "to": [ 9, 8, 5 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 2 ],
+            "to": [ 10, 8, 4 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/active1.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active1.json
new file mode 100644
index 000000000..93065aae3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active1.json
@@ -0,0 +1,68 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/active_top",
+        "lit": "minecraft:block/torch_redstone_active",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 7, 8 ],
+            "to": [ 9, 7, 10 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 7 ],
+            "to": [ 9, 8, 11 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 8 ],
+            "to": [ 10, 8, 10 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 7, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 1 ],
+            "to": [ 9, 8, 5 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 2 ],
+            "to": [ 10, 8, 4 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/active2.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active2.json
new file mode 100644
index 000000000..917a4a74b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active2.json
@@ -0,0 +1,68 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/active_top",
+        "lit": "minecraft:block/torch_redstone_active",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 7, 10 ],
+            "to": [ 9, 7, 12 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 9 ],
+            "to": [ 9, 8, 13 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 10 ],
+            "to": [ 10, 8, 12 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 7, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 1 ],
+            "to": [ 9, 8, 5 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 2 ],
+            "to": [ 10, 8, 4 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/repeater/active3.json b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active3.json
new file mode 100644
index 000000000..3bcbad1ea
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/repeater/active3.json
@@ -0,0 +1,68 @@
+{
+    "ambientocclusion": false,
+    "textures": {
+        "slab": "minecraft:block/polished_stone_top",
+        "top": "minecraft:block/repeater/active_top",
+        "lit": "minecraft:block/torch_redstone_active",
+        "overlay": "#top",
+        "particle_up": "#top",
+        "particle_down": "#slab",
+        "particle_north": "#slab",
+        "particle_south": "#slab",
+        "particle_west": "#slab",
+        "particle_east": "#slab"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 2, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#slab", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "north" },
+                "south": { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "south" },
+                "west":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "west" },
+                "east":  { "uv": [ 0, 14, 16, 16 ], "texture": "#slab", "cullface": "east" }
+            }
+        },
+        {   "from": [ 7, 7, 12 ],
+            "to": [ 9, 7, 14 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 11 ],
+            "to": [ 9, 8, 15 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 12 ],
+            "to": [ 10, 8, 14 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 7, 2 ],
+            "to": [ 9, 7, 4 ],
+            "faces": {
+                "up":   { "uv": [ 7, 6, 9, 8 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 7, 2, 1 ],
+            "to": [ 9, 8, 5 ],
+            "faces": {
+                "west": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "east": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        },
+        {   "from": [ 6, 2, 2 ],
+            "to": [ 10, 8, 4 ],
+            "faces": {
+                "north": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" },
+                "south": { "uv": [ 6, 5, 10, 11 ], "texture": "#lit" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/rope/knot.json b/game/client/src/main/resources/assets/minecraft/models/block/rope/knot.json
new file mode 100644
index 000000000..4cbfbabff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/rope/knot.json
@@ -0,0 +1,29 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"rope": "block/rope",
+		"overlay": "#rope",
+		"particle_up": "#rope",
+		"particle_down": "#rope",
+		"particle_north": "#rope",
+		"particle_south": "#rope",
+		"particle_west": "#rope",
+		"particle_east": "#rope"
+	},
+	"elements": [
+		{
+			"from": [6, 6, 6],
+			"to": [10, 10, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 3, 6]},
+			"faces": {
+				"north": {"uv": [6, 6, 10, 10], "texture": "#rope"},
+				"east": {"uv": [6, 6, 10, 10], "texture": "#rope"},
+				"south": {"uv": [6, 6, 10, 10], "texture": "#rope"},
+				"west": {"uv": [6, 6, 10, 10], "texture": "#rope"},
+				"up": {"uv": [6, 6, 10, 10], "texture": "#rope"},
+				"down": {"uv": [6, 6, 10, 10], "texture": "#rope"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/rope/line.json b/game/client/src/main/resources/assets/minecraft/models/block/rope/line.json
new file mode 100644
index 000000000..fdb47da94
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/rope/line.json
@@ -0,0 +1,28 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"rope": "block/rope",
+		"overlay": "#rope",
+		"particle_up": "#rope",
+		"particle_down": "#rope",
+		"particle_north": "#rope",
+		"particle_south": "#rope",
+		"particle_west": "#rope",
+		"particle_east": "#rope"
+	},
+	"elements": [
+		{
+			"from": [7, 7, 0],
+			"to": [9, 9, 8],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 0]},
+			"faces": {
+				"north": {"uv": [7, 7, 9, 9], "texture": "#rope", "cullface": "north"},
+				"east": {"uv": [8, 7, 16, 9], "texture": "#rope"},
+				"west": {"uv": [0, 7, 8, 9], "texture": "#rope"},
+				"up": {"uv": [7, 8, 9, 16], "texture": "#rope"},
+				"down": {"uv": [7, 0, 9, 8], "texture": "#rope"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/rope/pile.json b/game/client/src/main/resources/assets/minecraft/models/block/rope/pile.json
new file mode 100644
index 000000000..016274680
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/rope/pile.json
@@ -0,0 +1,52 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"rope": "block/rope",
+		"overlay": "#rope",
+		"particle_up": "#rope",
+		"particle_down": "#rope",
+		"particle_north": "#rope",
+		"particle_south": "#rope",
+		"particle_west": "#rope",
+		"particle_east": "#rope"
+	},
+	"elements": [
+		{
+			"from": [7, 3, 7],
+			"to": [9, 8, 9],
+			"rotation": {"angle": 0, "axis": "y", "origin": [7, 3, 7]},
+			"faces": {
+				"north": {"uv": [7, 8, 9, 13], "texture": "#rope"},
+				"east": {"uv": [7, 8, 9, 13], "texture": "#rope"},
+				"south": {"uv": [7, 8, 9, 13], "texture": "#rope"},
+				"west": {"uv": [7, 8, 9, 13], "texture": "#rope"}
+			}
+		},
+		{
+			"from": [5, 0, 5],
+			"to": [11, 2, 11],
+			"rotation": {"angle": 0, "axis": "y", "origin": [5, 0, 5]},
+			"faces": {
+				"north": {"uv": [5, 14, 11, 16], "texture": "#rope"},
+				"east": {"uv": [5, 14, 11, 16], "texture": "#rope"},
+				"south": {"uv": [5, 14, 11, 16], "texture": "#rope"},
+				"west": {"uv": [5, 14, 11, 16], "texture": "#rope"},
+				"up": {"uv": [5, 5, 11, 11], "texture": "#rope"},
+				"down": {"uv": [5, 5, 11, 11], "texture": "#rope", "cullface": "down"}
+			}
+		},
+		{
+			"from": [6, 2, 6],
+			"to": [10, 3, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 2, 6]},
+			"faces": {
+				"north": {"uv": [6, 13, 10, 14], "texture": "#rope"},
+				"east": {"uv": [6, 13, 10, 14], "texture": "#rope"},
+				"south": {"uv": [6, 13, 10, 14], "texture": "#rope"},
+				"west": {"uv": [6, 13, 10, 14], "texture": "#rope"},
+				"up": {"uv": [6, 6, 10, 10], "texture": "#rope"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sand.json b/game/client/src/main/resources/assets/minecraft/models/block/sand.json
new file mode 100644
index 000000000..b73935a3e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sand.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/sand"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sandstone.json b/game/client/src/main/resources/assets/minecraft/models/block/sandstone.json
new file mode 100644
index 000000000..e55e8c2c4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sandstone.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/sandstone/top",
+    "bottom": "minecraft:block/sandstone/bottom",
+    "side": "minecraft:block/sandstone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/birch.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/birch.json
new file mode 100644
index 000000000..e36eaa80a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/birch.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/birch"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/cacao.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/cacao.json
new file mode 100644
index 000000000..fc6fb4b8c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/cacao.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/cacao"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/cherry.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/cherry.json
new file mode 100644
index 000000000..aa258832d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/cherry.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/cherry"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/eucalyptus.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/eucalyptus.json
new file mode 100644
index 000000000..e75651b61
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/eucalyptus.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/eucalyptus"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling_oak.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/oak.json
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/models/block/sapling_oak.json
rename to game/client/src/main/resources/assets/minecraft/models/block/sapling/oak.json
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/oak_retro.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/oak_retro.json
new file mode 100644
index 000000000..796af5fb5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/oak_retro.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/oak_retro"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/palm.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/palm.json
new file mode 100644
index 000000000..00e187d7e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/palm.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/palm"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/pine.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/pine.json
new file mode 100644
index 000000000..69fb09110
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/pine.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/pine"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/shrub.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/shrub.json
new file mode 100644
index 000000000..858cd41cb
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/shrub.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/shrub"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sapling/thorn.json b/game/client/src/main/resources/assets/minecraft/models/block/sapling/thorn.json
new file mode 100644
index 000000000..e028aa654
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sapling/thorn.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sapling/thorn"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/seat.json b/game/client/src/main/resources/assets/minecraft/models/block/seat.json
new file mode 100644
index 000000000..aab9593ec
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/seat.json
@@ -0,0 +1,47 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "minecraft:block/block",
+	"textures": {
+		"bottom": "block/seat/bottom",
+		"side": "block/seat/side",
+		"top": "block/seat/top",
+		"overlay": "#top",
+		"particle_up": "#top",
+		"particle_down": "#bottom",
+		"particle_north": "#side",
+		"particle_south": "#side",
+		"particle_west": "#side",
+		"particle_east": "#side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 9, 16],
+			"faces": {
+				"north": {"uv": [0, 7, 16, 16], "texture": "#side", "cullface": "north"},
+				"east": {"uv": [0, 7, 16, 16], "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 7, 16, 16], "texture": "#side", "cullface": "south"},
+				"west": {"uv": [0, 7, 16, 16], "texture": "#side", "cullface": "west"},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"}
+			}
+		},
+		{
+			"from": [15.95, 0, 0.05],
+			"to": [0.05, 9, 15.95],
+			"faces": {
+				"north": {"uv": [0, 7, 16, 16], "texture": "#side"},
+				"east": {"uv": [0, 7, 16, 16], "texture": "#side"},
+				"south": {"uv": [0, 7, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 7, 16, 16], "texture": "#side"}
+			}
+		},
+		{
+			"from": [0, 3, 0],
+			"to": [16, 9, 16],
+			"faces": {
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/full.json
new file mode 100644
index 000000000..740e8547d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/lower.json
new file mode 100644
index 000000000..3a6dd03a2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_basalt",
+    "bottom": "minecraft:block/brick_basalt",
+    "side": "minecraft:block/brick_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/upper.json
new file mode 100644
index 000000000..5abb1a567
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_basalt/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_basalt",
+    "bottom": "minecraft:block/brick_basalt",
+    "side": "minecraft:block/brick_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/full.json
new file mode 100644
index 000000000..342a0456f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_clay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/lower.json
new file mode 100644
index 000000000..df8e6f159
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_clay",
+    "bottom": "minecraft:block/brick_clay",
+    "side": "minecraft:block/brick_clay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/upper.json
new file mode 100644
index 000000000..7cf210e98
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_clay/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_clay",
+    "bottom": "minecraft:block/brick_clay",
+    "side": "minecraft:block/brick_clay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/full.json
new file mode 100644
index 000000000..f6a01a742
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_gold"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/lower.json
new file mode 100644
index 000000000..1ff4964ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_gold",
+    "bottom": "minecraft:block/brick_gold",
+    "side": "minecraft:block/brick_gold"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/upper.json
new file mode 100644
index 000000000..7d5807782
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_gold/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_gold",
+    "bottom": "minecraft:block/brick_gold",
+    "side": "minecraft:block/brick_gold"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/full.json
new file mode 100644
index 000000000..58e416df9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/lower.json
new file mode 100644
index 000000000..7324a0bed
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_granite",
+    "bottom": "minecraft:block/brick_granite",
+    "side": "minecraft:block/brick_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/upper.json
new file mode 100644
index 000000000..eb59f7421
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_granite/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_granite",
+    "bottom": "minecraft:block/brick_granite",
+    "side": "minecraft:block/brick_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/full.json
new file mode 100644
index 000000000..31af403e6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_iron"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/lower.json
new file mode 100644
index 000000000..323bcda55
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_iron",
+    "bottom": "minecraft:block/brick_iron",
+    "side": "minecraft:block/brick_iron"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/upper.json
new file mode 100644
index 000000000..632b9854e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_iron/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_iron",
+    "bottom": "minecraft:block/brick_iron",
+    "side": "minecraft:block/brick_iron"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/full.json
new file mode 100644
index 000000000..dc2e8d6f8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_lapis"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/lower.json
new file mode 100644
index 000000000..ad532ceb9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_lapis",
+    "bottom": "minecraft:block/brick_lapis",
+    "side": "minecraft:block/brick_lapis"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/upper.json
new file mode 100644
index 000000000..c260d152c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_lapis/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_lapis",
+    "bottom": "minecraft:block/brick_lapis",
+    "side": "minecraft:block/brick_lapis"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/full.json
new file mode 100644
index 000000000..77da88fc4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/lower.json
new file mode 100644
index 000000000..42b1859a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_limestone",
+    "bottom": "minecraft:block/brick_limestone",
+    "side": "minecraft:block/brick_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/upper.json
new file mode 100644
index 000000000..9063c04bb
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_limestone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_limestone",
+    "bottom": "minecraft:block/brick_limestone",
+    "side": "minecraft:block/brick_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/full.json
new file mode 100644
index 000000000..e20a29bc5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_marble"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/lower.json
new file mode 100644
index 000000000..de3f9d492
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_marble",
+    "bottom": "minecraft:block/brick_marble",
+    "side": "minecraft:block/brick_marble"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/upper.json
new file mode 100644
index 000000000..5cde51714
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_marble/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_marble",
+    "bottom": "minecraft:block/brick_marble",
+    "side": "minecraft:block/brick_marble"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/full.json
new file mode 100644
index 000000000..41397e21d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/lower.json
new file mode 100644
index 000000000..cf89f9aac
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_netherrack",
+    "bottom": "minecraft:block/brick_netherrack",
+    "side": "minecraft:block/brick_netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/upper.json
new file mode 100644
index 000000000..e236148a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_netherrack/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_netherrack",
+    "bottom": "minecraft:block/brick_netherrack",
+    "side": "minecraft:block/brick_netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/full.json
new file mode 100644
index 000000000..7c490b424
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/lower.json
new file mode 100644
index 000000000..543e74523
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_permafrost",
+    "bottom": "minecraft:block/brick_permafrost",
+    "side": "minecraft:block/brick_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/upper.json
new file mode 100644
index 000000000..efd2e2218
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_permafrost/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_permafrost",
+    "bottom": "minecraft:block/brick_permafrost",
+    "side": "minecraft:block/brick_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/full.json
new file mode 100644
index 000000000..259b18fd4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_sandstone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/lower.json
new file mode 100644
index 000000000..6bebf6693
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_sandstone",
+    "bottom": "minecraft:block/brick_sandstone",
+    "side": "minecraft:block/brick_sandstone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/upper.json
new file mode 100644
index 000000000..fa02ce88b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_sandstone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_sandstone",
+    "bottom": "minecraft:block/brick_sandstone",
+    "side": "minecraft:block/brick_sandstone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/full.json
new file mode 100644
index 000000000..635bc75fd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_slate"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/lower.json
new file mode 100644
index 000000000..cc87fd155
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_slate",
+    "bottom": "minecraft:block/brick_slate",
+    "side": "minecraft:block/brick_slate"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/upper.json
new file mode 100644
index 000000000..be14a9a1d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_slate/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_slate",
+    "bottom": "minecraft:block/brick_slate",
+    "side": "minecraft:block/brick_slate"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/full.json
new file mode 100644
index 000000000..f9ce539d2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_steel"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/lower.json
new file mode 100644
index 000000000..b3c5c8523
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_steel",
+    "bottom": "minecraft:block/brick_steel",
+    "side": "minecraft:block/brick_steel"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/upper.json
new file mode 100644
index 000000000..ebce947d8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_steel/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_steel",
+    "bottom": "minecraft:block/brick_steel",
+    "side": "minecraft:block/brick_steel"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/full.json
new file mode 100644
index 000000000..7e8ecab87
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/lower.json
new file mode 100644
index 000000000..ca2b815f6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_stone",
+    "bottom": "minecraft:block/brick_stone",
+    "side": "minecraft:block/brick_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/upper.json
new file mode 100644
index 000000000..2f542c643
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_stone",
+    "bottom": "minecraft:block/brick_stone",
+    "side": "minecraft:block/brick_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/full.json
new file mode 100644
index 000000000..ba9091549
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/brick_polished_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/lower.json
new file mode 100644
index 000000000..bb8d1ad3a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/brick_polished_stone",
+    "bottom": "minecraft:block/brick_polished_stone",
+    "side": "minecraft:block/brick_polished_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/upper.json
new file mode 100644
index 000000000..f7aec9358
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/brick_stone_polished/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/brick_polished_stone",
+    "bottom": "minecraft:block/brick_polished_stone",
+    "side": "minecraft:block/brick_polished_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/full.json
new file mode 100644
index 000000000..6373ab6ae
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/full.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/capstone_marble/top",
+    "side": "minecraft:block/capstone_marble/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/lower.json
new file mode 100644
index 000000000..383d2e7dc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/capstone_marble/top",
+    "bottom": "minecraft:block/capstone_marble/top",
+    "side": "minecraft:block/carved_marble"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/upper.json
new file mode 100644
index 000000000..94174f8c6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/capstone_marble/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/capstone_marble/top",
+    "bottom": "minecraft:block/capstone_marble/top",
+    "side": "minecraft:block/carved_marble"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/full.json
new file mode 100644
index 000000000..9cf099869
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/lower.json
new file mode 100644
index 000000000..817b04e6b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/cobbled_basalt",
+    "bottom": "minecraft:block/cobbled_basalt",
+    "side": "minecraft:block/cobbled_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/upper.json
new file mode 100644
index 000000000..2d0098e14
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_basalt/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/cobbled_basalt",
+    "bottom": "minecraft:block/cobbled_basalt",
+    "side": "minecraft:block/cobbled_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/full.json
new file mode 100644
index 000000000..f421362b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/lower.json
new file mode 100644
index 000000000..f5cd976a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/cobbled_granite",
+    "bottom": "minecraft:block/cobbled_granite",
+    "side": "minecraft:block/cobbled_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/upper.json
new file mode 100644
index 000000000..4a49cd29c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_granite/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/cobbled_granite",
+    "bottom": "minecraft:block/cobbled_granite",
+    "side": "minecraft:block/cobbled_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/full.json
new file mode 100644
index 000000000..e83e25a08
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/lower.json
new file mode 100644
index 000000000..5c7538944
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/cobbled_limestone",
+    "bottom": "minecraft:block/cobbled_limestone",
+    "side": "minecraft:block/cobbled_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/upper.json
new file mode 100644
index 000000000..2991bd644
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_limestone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/cobbled_limestone",
+    "bottom": "minecraft:block/cobbled_limestone",
+    "side": "minecraft:block/cobbled_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/full.json
new file mode 100644
index 000000000..def591e4c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_netherrack/normal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/lower.json
new file mode 100644
index 000000000..730e476f1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/cobbled_netherrack/normal",
+    "bottom": "minecraft:block/cobbled_netherrack/normal",
+    "side": "minecraft:block/cobbled_netherrack/normal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/upper.json
new file mode 100644
index 000000000..62732fbd0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_netherrack/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/cobbled_netherrack/normal",
+    "bottom": "minecraft:block/cobbled_netherrack/normal",
+    "side": "minecraft:block/cobbled_netherrack/normal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/full.json
new file mode 100644
index 000000000..6b20443b7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/lower.json
new file mode 100644
index 000000000..e329b95f7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/cobbled_permafrost",
+    "bottom": "minecraft:block/cobbled_permafrost",
+    "side": "minecraft:block/cobbled_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/upper.json
new file mode 100644
index 000000000..112dc8ef4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_permafrost/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/cobbled_permafrost",
+    "bottom": "minecraft:block/cobbled_permafrost",
+    "side": "minecraft:block/cobbled_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/full.json
new file mode 100644
index 000000000..199549004
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/cobbled_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/lower.json
new file mode 100644
index 000000000..28993aa7e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/cobbled_stone",
+    "bottom": "minecraft:block/cobbled_stone",
+    "side": "minecraft:block/cobbled_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/upper.json
new file mode 100644
index 000000000..413f3e6b1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/cobbled_stone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/cobbled_stone",
+    "bottom": "minecraft:block/cobbled_stone",
+    "side": "minecraft:block/cobbled_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/lower.json
new file mode 100644
index 000000000..a82c7460b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/lower.json
@@ -0,0 +1,24 @@
+{   "parent": "block/block",
+    "textures": {
+        "overlay": "#side",
+        "particle_up": "#top",
+        "particle_down": "#bottom",
+        "particle_north": "#side",
+        "particle_south": "#side",
+        "particle_west": "#side",
+        "particle_east": "#side"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 8, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" },
+                "up":    { "uv": [ 0, 0, 16, 16 ], "texture": "#top" },
+                "north": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "north" },
+                "south": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "south" },
+                "west":  { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "west" },
+                "east":  { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "east" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/full.json
new file mode 100644
index 000000000..5e22cb1d0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/lower.json
new file mode 100644
index 000000000..b9b5c76e8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/black",
+    "bottom": "minecraft:block/planks/black",
+    "side": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/upper.json
new file mode 100644
index 000000000..8323a1803
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/black/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/black",
+    "bottom": "minecraft:block/planks/black",
+    "side": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/full.json
new file mode 100644
index 000000000..24b7e6ba7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/lower.json
new file mode 100644
index 000000000..6a6f56fd5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/blue",
+    "bottom": "minecraft:block/planks/blue",
+    "side": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/upper.json
new file mode 100644
index 000000000..e3623e023
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/blue/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/blue",
+    "bottom": "minecraft:block/planks/blue",
+    "side": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/full.json
new file mode 100644
index 000000000..81a06fd9b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/lower.json
new file mode 100644
index 000000000..bbee034ca
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/brown",
+    "bottom": "minecraft:block/planks/brown",
+    "side": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/upper.json
new file mode 100644
index 000000000..037da9e36
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/brown/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/brown",
+    "bottom": "minecraft:block/planks/brown",
+    "side": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/full.json
new file mode 100644
index 000000000..0fe3cc7a4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/lower.json
new file mode 100644
index 000000000..4affe7fc0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/cyan",
+    "bottom": "minecraft:block/planks/cyan",
+    "side": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/upper.json
new file mode 100644
index 000000000..85f5b4d24
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/cyan/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/cyan",
+    "bottom": "minecraft:block/planks/cyan",
+    "side": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/full.json
new file mode 100644
index 000000000..8b5f8f8ee
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/lower.json
new file mode 100644
index 000000000..47e06f8e9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/gray",
+    "bottom": "minecraft:block/planks/gray",
+    "side": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/upper.json
new file mode 100644
index 000000000..ecbd42055
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/gray/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/gray",
+    "bottom": "minecraft:block/planks/gray",
+    "side": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/full.json
new file mode 100644
index 000000000..92cc5b80a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/lower.json
new file mode 100644
index 000000000..2fa8844b6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/green",
+    "bottom": "minecraft:block/planks/green",
+    "side": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/upper.json
new file mode 100644
index 000000000..cd9661c2e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/green/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/green",
+    "bottom": "minecraft:block/planks/green",
+    "side": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/full.json
new file mode 100644
index 000000000..09ac96c1b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/lower.json
new file mode 100644
index 000000000..7c817abc6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/lightblue",
+    "bottom": "minecraft:block/planks/lightblue",
+    "side": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/upper.json
new file mode 100644
index 000000000..04b245f0a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lightblue/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/lightblue",
+    "bottom": "minecraft:block/planks/lightblue",
+    "side": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/full.json
new file mode 100644
index 000000000..9b4b7d2cd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/lower.json
new file mode 100644
index 000000000..e16e933e3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/lime",
+    "bottom": "minecraft:block/planks/lime",
+    "side": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/upper.json
new file mode 100644
index 000000000..928da3ac5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/lime/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/lime",
+    "bottom": "minecraft:block/planks/lime",
+    "side": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/full.json
new file mode 100644
index 000000000..bfc2bae5a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/lower.json
new file mode 100644
index 000000000..ace39d4b4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/magenta",
+    "bottom": "minecraft:block/planks/magenta",
+    "side": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/upper.json
new file mode 100644
index 000000000..11a2f38a7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/magenta/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/magenta",
+    "bottom": "minecraft:block/planks/magenta",
+    "side": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/full.json
new file mode 100644
index 000000000..8d1e69157
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/lower.json
new file mode 100644
index 000000000..f89410757
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/oak",
+    "bottom": "minecraft:block/planks/oak",
+    "side": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/upper.json
new file mode 100644
index 000000000..6fd333605
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/oak/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/oak",
+    "bottom": "minecraft:block/planks/oak",
+    "side": "minecraft:block/planks/oak"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/full.json
new file mode 100644
index 000000000..21a3d52b6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/lower.json
new file mode 100644
index 000000000..6208f2bc6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/orange",
+    "bottom": "minecraft:block/planks/orange",
+    "side": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/upper.json
new file mode 100644
index 000000000..30974cfeb
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/orange/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/orange",
+    "bottom": "minecraft:block/planks/orange",
+    "side": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/full.json
new file mode 100644
index 000000000..0073ad1ba
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/lower.json
new file mode 100644
index 000000000..aaf1f60c8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/pink",
+    "bottom": "minecraft:block/planks/pink",
+    "side": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/upper.json
new file mode 100644
index 000000000..c4ca9b69e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/pink/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/pink",
+    "bottom": "minecraft:block/planks/pink",
+    "side": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/full.json
new file mode 100644
index 000000000..828997683
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/lower.json
new file mode 100644
index 000000000..2b61f8412
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/purple",
+    "bottom": "minecraft:block/planks/purple",
+    "side": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/upper.json
new file mode 100644
index 000000000..6398f7591
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/purple/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/purple",
+    "bottom": "minecraft:block/planks/purple",
+    "side": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/full.json
new file mode 100644
index 000000000..5cfc462ec
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/lower.json
new file mode 100644
index 000000000..43680c797
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/red",
+    "bottom": "minecraft:block/planks/red",
+    "side": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/upper.json
new file mode 100644
index 000000000..9ae871660
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/red/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/red",
+    "bottom": "minecraft:block/planks/red",
+    "side": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/full.json
new file mode 100644
index 000000000..0e57db551
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/lower.json
new file mode 100644
index 000000000..612975b53
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/silver",
+    "bottom": "minecraft:block/planks/silver",
+    "side": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/upper.json
new file mode 100644
index 000000000..10515848c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/silver/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/silver",
+    "bottom": "minecraft:block/planks/silver",
+    "side": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/full.json
new file mode 100644
index 000000000..e330849ea
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/lower.json
new file mode 100644
index 000000000..a6cf24137
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/white",
+    "bottom": "minecraft:block/planks/white",
+    "side": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/upper.json
new file mode 100644
index 000000000..a824aab83
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/white/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/white",
+    "bottom": "minecraft:block/planks/white",
+    "side": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/full.json
new file mode 100644
index 000000000..1228cae3a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/full.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/lower.json
new file mode 100644
index 000000000..c3f72aeb3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/planks/yellow",
+    "bottom": "minecraft:block/planks/yellow",
+    "side": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/upper.json
new file mode 100644
index 000000000..1f5b9783e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/planks/yellow/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/planks/yellow",
+    "bottom": "minecraft:block/planks/yellow",
+    "side": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/full.json
new file mode 100644
index 000000000..6ed772886
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/full.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_basalt_top",
+    "side": "minecraft:block/carved_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/lower.json
new file mode 100644
index 000000000..6d60c619f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/polished_basalt_top",
+    "bottom": "minecraft:block/polished_basalt_top",
+    "side": "minecraft:block/carved_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/upper.json
new file mode 100644
index 000000000..2671a9c9f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_basalt/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/polished_basalt_top",
+    "bottom": "minecraft:block/polished_basalt_top",
+    "side": "minecraft:block/carved_basalt"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/full.json
new file mode 100644
index 000000000..73495bdd7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/full.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_granite_top",
+    "side": "minecraft:block/carved_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/lower.json
new file mode 100644
index 000000000..d150ac581
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/polished_granite_top",
+    "bottom": "minecraft:block/polished_granite_top",
+    "side": "minecraft:block/carved_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/upper.json
new file mode 100644
index 000000000..f0d6d5536
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_granite/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/polished_granite_top",
+    "bottom": "minecraft:block/polished_granite_top",
+    "side": "minecraft:block/carved_granite"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/full.json
new file mode 100644
index 000000000..bfc52afbd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/full.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_limestone_top",
+    "side": "minecraft:block/carved_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/lower.json
new file mode 100644
index 000000000..4c7eeece8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/polished_limestone_top",
+    "bottom": "minecraft:block/polished_limestone_top",
+    "side": "minecraft:block/carved_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/upper.json
new file mode 100644
index 000000000..f7177eb3c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_limestone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/polished_limestone_top",
+    "bottom": "minecraft:block/polished_limestone_top",
+    "side": "minecraft:block/carved_limestone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/full.json
new file mode 100644
index 000000000..3e1ef63af
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/full.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_netherrack_top",
+    "side": "minecraft:block/carved_netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/lower.json
new file mode 100644
index 000000000..2ac6cec61
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/polished_netherrack_top",
+    "bottom": "minecraft:block/polished_netherrack_top",
+    "side": "minecraft:block/carved_netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/upper.json
new file mode 100644
index 000000000..c842f8ad1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_netherrack/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/polished_netherrack_top",
+    "bottom": "minecraft:block/polished_netherrack_top",
+    "side": "minecraft:block/carved_netherrack"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/full.json
new file mode 100644
index 000000000..9cdf02e77
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/full.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_permafrost_top",
+    "side": "minecraft:block/carved_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/lower.json
new file mode 100644
index 000000000..fdfc674dd
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/polished_permafrost_top",
+    "bottom": "minecraft:block/polished_permafrost_top",
+    "side": "minecraft:block/carved_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/upper.json
new file mode 100644
index 000000000..7939d0a70
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_permafrost/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/polished_permafrost_top",
+    "bottom": "minecraft:block/polished_permafrost_top",
+    "side": "minecraft:block/carved_permafrost"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/full.json
new file mode 100644
index 000000000..2574297c3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/full.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/cube_column",
+  "textures": {
+    "end": "minecraft:block/polished_stone_top",
+    "side": "minecraft:block/carved_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/lower.json
new file mode 100644
index 000000000..2cd67273d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/polished_stone_top",
+    "bottom": "minecraft:block/polished_stone_top",
+    "side": "minecraft:block/carved_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/upper.json
new file mode 100644
index 000000000..ea0f9b321
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/polished_stone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/polished_stone_top",
+    "bottom": "minecraft:block/polished_stone_top",
+    "side": "minecraft:block/carved_stone"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/full.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/full.json
new file mode 100644
index 000000000..e55e8c2c4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/full.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/sandstone/top",
+    "bottom": "minecraft:block/sandstone/bottom",
+    "side": "minecraft:block/sandstone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/lower.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/lower.json
new file mode 100644
index 000000000..c88a56b69
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/lower.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/lower",
+  "textures": {
+    "top": "minecraft:block/sandstone/top",
+    "bottom": "minecraft:block/sandstone/bottom",
+    "side": "minecraft:block/sandstone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/upper.json
new file mode 100644
index 000000000..ed3143f2c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/sandstone/upper.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/slab/upper",
+  "textures": {
+    "top": "minecraft:block/sandstone/top",
+    "bottom": "minecraft:block/sandstone/bottom",
+    "side": "minecraft:block/sandstone/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slab/upper.json b/game/client/src/main/resources/assets/minecraft/models/block/slab/upper.json
new file mode 100644
index 000000000..a29e33a13
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slab/upper.json
@@ -0,0 +1,24 @@
+{
+    "textures": {
+        "overlay": "#side",
+        "particle_up": "#top",
+        "particle_down": "#bottom",
+        "particle_north": "#side",
+        "particle_south": "#side",
+        "particle_west": "#side",
+        "particle_east": "#side"
+    },
+    "elements": [
+        {   "from": [ 0, 8, 0 ],
+            "to": [ 16, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom" },
+                "up":    { "uv": [ 0, 0, 16, 16 ], "texture": "#top", "cullface": "up" },
+                "north": { "uv": [ 0, 0, 16,  8 ], "texture": "#side", "cullface": "north" },
+                "south": { "uv": [ 0, 0, 16,  8 ], "texture": "#side", "cullface": "south" },
+                "west":  { "uv": [ 0, 0, 16,  8 ], "texture": "#side", "cullface": "west" },
+                "east":  { "uv": [ 0, 0, 16,  8 ], "texture": "#side", "cullface": "east" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/slate.json b/game/client/src/main/resources/assets/minecraft/models/block/slate.json
new file mode 100644
index 000000000..e2881b040
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/slate.json
@@ -0,0 +1,7 @@
+{
+	"parent": "minecraft:block/cube_column",
+	"textures": {
+		"end": "minecraft:block/slate_top",
+		"side": "minecraft:block/slate_side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/soulsand.json b/game/client/src/main/resources/assets/minecraft/models/block/soulsand.json
new file mode 100644
index 000000000..1025674ff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/soulsand.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/soulsand"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/soulschist.json b/game/client/src/main/resources/assets/minecraft/models/block/soulschist.json
new file mode 100644
index 000000000..eecd8bd3f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/soulschist.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/soulschist"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/spikes.json b/game/client/src/main/resources/assets/minecraft/models/block/spikes.json
new file mode 100644
index 000000000..4c58c7acc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/spikes.json
@@ -0,0 +1,91 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"ambientocclusion": false,
+	"textures": {
+		"bottom": "block/spikes/bottom",
+		"side": "block/spikes/side",
+		"top": "block/spikes/top",
+		"overlay": "#side",
+		"particle_up": "#up",
+		"particle_down": "#down",
+		"particle_north": "#north",
+		"particle_south": "#south",
+		"particle_west": "#west",
+		"particle_east": "#east",
+		"down": "#bottom",
+		"up": "#top",
+		"north": "#side",
+		"east": "#side",
+		"south": "#side",
+		"west": "#side"
+	},
+	"elements": [
+		{
+			"name": "spike0",
+			"from": [3, 0, 0],
+			"to": [3, 16, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [3, 0, 0]},
+			"shade": false,
+			"faces": {
+				"east": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		},
+		{
+			"name": "spike1",
+			"from": [8, 0, 0],
+			"to": [8, 16, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 0]},
+			"shade": false,
+			"faces": {
+				"east": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		},
+		{
+			"name": "spike2",
+			"from": [13, 0, 0],
+			"to": [13, 16, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [13, 0, 0]},
+			"shade": false,
+			"faces": {
+				"east": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		},
+		{
+			"name": "spike3",
+			"from": [0, 0, 3],
+			"to": [16, 16, 3],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 3]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		},
+		{
+			"name": "spike4",
+			"from": [0, 0, 8],
+			"to": [16, 16, 8],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 8]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		},
+		{
+			"name": "spike5",
+			"from": [0, 0, 13],
+			"to": [16, 16, 13],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 13]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#side"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#side"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/spikes_base.json b/game/client/src/main/resources/assets/minecraft/models/block/spikes_base.json
new file mode 100644
index 000000000..16faef746
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/spikes_base.json
@@ -0,0 +1,37 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"bottom": "block/spikes/bottom",
+		"side": "block/spikes/side",
+		"top": "block/spikes/top",
+		"overlay": "#side",
+		"particle_up": "#up",
+		"particle_down": "#down",
+		"particle_north": "#north",
+		"particle_south": "#south",
+		"particle_west": "#west",
+		"particle_east": "#east",
+		"down": "#bottom",
+		"up": "#top",
+		"north": "#side",
+		"east": "#side",
+		"south": "#side",
+		"west": "#side"
+	},
+	"elements": [
+		{
+			"name": "base",
+			"from": [0, 0, 0],
+			"to": [16, 3, 16],
+			"faces": {
+				"north": {"uv": [0, 13, 16, 16], "texture": "#side", "cullface": "north" },
+				"east": {"uv": [0, 13, 16, 16], "texture": "#side", "cullface": "east" },
+				"south": {"uv": [0, 13, 16, 16], "texture": "#side", "cullface": "south" },
+				"west": {"uv": [0, 13, 16, 16], "texture": "#side", "cullface": "west" },
+				"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down" }
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/spinifex.json b/game/client/src/main/resources/assets/minecraft/models/block/spinifex.json
new file mode 100644
index 000000000..442c41d98
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/spinifex.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/spinifex"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sponge.json b/game/client/src/main/resources/assets/minecraft/models/block/sponge.json
new file mode 100644
index 000000000..93acf8854
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sponge.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/sponge"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sponge_wet.json b/game/client/src/main/resources/assets/minecraft/models/block/sponge_wet.json
new file mode 100644
index 000000000..70b9a7c2a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sponge_wet.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/sponge_wet"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs.json
index 986ce9c6e..886682db1 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/stairs.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs.json
@@ -17,7 +17,14 @@
         }
     },
     "textures": {
-        "particle": "#side"
+        "particle": "#side",
+        "overlay": "#side",
+        "particle_up": "#side",
+        "particle_down": "#side",
+        "particle_north": "#side",
+        "particle_south": "#side",
+        "particle_west": "#side",
+        "particle_east": "#side"
     },
     "elements": [
         {   "from": [ 0, 0, 0 ],
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_basalt.json
new file mode 100644
index 000000000..48796574e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_basalt.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_basalt",
+		"bottom": "minecraft:block/brick_basalt",
+		"side": "minecraft:block/brick_basalt"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_clay.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_clay.json
new file mode 100644
index 000000000..c3efc5259
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_clay.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_clay",
+		"bottom": "minecraft:block/brick_clay",
+		"side": "minecraft:block/brick_clay"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_gold.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_gold.json
new file mode 100644
index 000000000..0518a8c73
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_gold.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_gold",
+		"bottom": "minecraft:block/brick_gold",
+		"side": "minecraft:block/brick_gold"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_granite.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_granite.json
new file mode 100644
index 000000000..26121dff7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_granite.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_granite",
+		"bottom": "minecraft:block/brick_granite",
+		"side": "minecraft:block/brick_granite"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_iron.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_iron.json
new file mode 100644
index 000000000..80f83b476
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_iron.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_iron",
+		"bottom": "minecraft:block/brick_iron",
+		"side": "minecraft:block/brick_iron"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_lapis.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_lapis.json
new file mode 100644
index 000000000..7b917da7b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_lapis.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_lapis",
+		"bottom": "minecraft:block/brick_lapis",
+		"side": "minecraft:block/brick_lapis"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_limestone.json
new file mode 100644
index 000000000..21d43d205
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_limestone.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_limestone",
+		"bottom": "minecraft:block/brick_limestone",
+		"side": "minecraft:block/brick_limestone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_marble.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_marble.json
new file mode 100644
index 000000000..23f5f0c67
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_marble.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_marble",
+		"bottom": "minecraft:block/brick_marble",
+		"side": "minecraft:block/brick_marble"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_netherrack.json
new file mode 100644
index 000000000..46a599e0a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_netherrack.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_netherrack",
+		"bottom": "minecraft:block/brick_netherrack",
+		"side": "minecraft:block/brick_netherrack"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_permafrost.json
new file mode 100644
index 000000000..eb36e6f7e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_permafrost.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_permafrost",
+		"bottom": "minecraft:block/brick_permafrost",
+		"side": "minecraft:block/brick_permafrost"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_sandstone.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_sandstone.json
new file mode 100644
index 000000000..ab25c6148
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_sandstone.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_sandstone",
+		"bottom": "minecraft:block/brick_sandstone",
+		"side": "minecraft:block/brick_sandstone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_slate.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_slate.json
new file mode 100644
index 000000000..74b8b68f4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_slate.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_slate",
+		"bottom": "minecraft:block/brick_slate",
+		"side": "minecraft:block/brick_slate"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_steel.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_steel.json
new file mode 100644
index 000000000..389dc0271
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_steel.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_steel",
+		"bottom": "minecraft:block/brick_steel",
+		"side": "minecraft:block/brick_steel"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_stone.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_stone.json
new file mode 100644
index 000000000..5513c924c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_stone.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_stone",
+		"bottom": "minecraft:block/brick_stone",
+		"side": "minecraft:block/brick_stone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_stone_polished.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_stone_polished.json
new file mode 100644
index 000000000..de1c31d6a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/brick_stone_polished.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/brick_polished_stone",
+		"bottom": "minecraft:block/brick_polished_stone",
+		"side": "minecraft:block/brick_polished_stone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_basalt.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_basalt.json
new file mode 100644
index 000000000..0aa759ba4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_basalt.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/cobbled_basalt",
+		"bottom": "minecraft:block/cobbled_basalt",
+		"side": "minecraft:block/cobbled_basalt"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_granite.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_granite.json
new file mode 100644
index 000000000..8a358d735
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_granite.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/cobbled_granite",
+		"bottom": "minecraft:block/cobbled_granite",
+		"side": "minecraft:block/cobbled_granite"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_limestone.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_limestone.json
new file mode 100644
index 000000000..d4319abf7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_limestone.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/cobbled_limestone",
+		"bottom": "minecraft:block/cobbled_limestone",
+		"side": "minecraft:block/cobbled_limestone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_netherrack.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_netherrack.json
new file mode 100644
index 000000000..01f0c1d88
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_netherrack.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/cobbled_netherrack/normal",
+		"bottom": "minecraft:block/cobbled_netherrack/normal",
+		"side": "minecraft:block/cobbled_netherrack/normal"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_permafrost.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_permafrost.json
new file mode 100644
index 000000000..7d5d6fee5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_permafrost.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/cobbled_permafrost",
+		"bottom": "minecraft:block/cobbled_permafrost",
+		"side": "minecraft:block/cobbled_permafrost"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_stone.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_stone.json
new file mode 100644
index 000000000..87bbab322
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/cobbled_stone.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/cobbled_stone",
+		"bottom": "minecraft:block/cobbled_stone",
+		"side": "minecraft:block/cobbled_stone"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/black.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/black.json
new file mode 100644
index 000000000..eb6afc1a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/black.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/black",
+    "top": "minecraft:block/planks/black",
+    "side": "minecraft:block/planks/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/blue.json
new file mode 100644
index 000000000..c10a07a65
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/blue.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/blue",
+    "top": "minecraft:block/planks/blue",
+    "side": "minecraft:block/planks/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/brown.json
new file mode 100644
index 000000000..536fd2761
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/brown.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/brown",
+    "top": "minecraft:block/planks/brown",
+    "side": "minecraft:block/planks/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/cyan.json
new file mode 100644
index 000000000..c62f3c797
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/cyan.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/cyan",
+    "top": "minecraft:block/planks/cyan",
+    "side": "minecraft:block/planks/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/gray.json
new file mode 100644
index 000000000..3ba9e7a35
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/gray.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/gray",
+    "top": "minecraft:block/planks/gray",
+    "side": "minecraft:block/planks/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/green.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/green.json
new file mode 100644
index 000000000..34380cc1d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/green.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/green",
+    "top": "minecraft:block/planks/green",
+    "side": "minecraft:block/planks/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/lightblue.json
new file mode 100644
index 000000000..1e908a919
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/lightblue.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/lightblue",
+    "top": "minecraft:block/planks/lightblue",
+    "side": "minecraft:block/planks/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/lime.json
new file mode 100644
index 000000000..48e0be8b2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/lime.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/lime",
+    "top": "minecraft:block/planks/lime",
+    "side": "minecraft:block/planks/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/magenta.json
new file mode 100644
index 000000000..0ff37c887
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/magenta.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/magenta",
+    "top": "minecraft:block/planks/magenta",
+    "side": "minecraft:block/planks/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/oak.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/oak.json
new file mode 100644
index 000000000..3f60c7f88
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/oak.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"bottom": "minecraft:block/planks/oak",
+		"top": "minecraft:block/planks/oak",
+		"side": "minecraft:block/planks/oak"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/orange.json
new file mode 100644
index 000000000..43d62f4ea
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/orange.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/orange",
+    "top": "minecraft:block/planks/orange",
+    "side": "minecraft:block/planks/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/pink.json
new file mode 100644
index 000000000..de01c2b64
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/pink.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/pink",
+    "top": "minecraft:block/planks/pink",
+    "side": "minecraft:block/planks/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/purple.json
new file mode 100644
index 000000000..db98c03d2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/purple.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/purple",
+    "top": "minecraft:block/planks/purple",
+    "side": "minecraft:block/planks/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/red.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/red.json
new file mode 100644
index 000000000..89f7a995f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/red.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/red",
+    "top": "minecraft:block/planks/red",
+    "side": "minecraft:block/planks/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/silver.json
new file mode 100644
index 000000000..6ec203dd7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/silver.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/silver",
+    "top": "minecraft:block/planks/silver",
+    "side": "minecraft:block/planks/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/white.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/white.json
new file mode 100644
index 000000000..f12ab89a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/white.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/white",
+    "top": "minecraft:block/planks/white",
+    "side": "minecraft:block/planks/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/yellow.json
new file mode 100644
index 000000000..5109d7a9c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/planks/yellow.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/stairs",
+  "textures": {
+    "bottom": "minecraft:block/planks/yellow",
+    "top": "minecraft:block/planks/yellow",
+    "side": "minecraft:block/planks/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs/sandstone.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs/sandstone.json
new file mode 100644
index 000000000..4caecb1e4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stairs/sandstone.json
@@ -0,0 +1,8 @@
+{
+	"parent": "minecraft:block/stairs",
+	"textures": {
+		"top": "minecraft:block/sandstone/top",
+		"bottom": "minecraft:block/sandstone/bottom",
+		"side": "minecraft:block/sandstone/side"
+	}
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stairs_oak.json b/game/client/src/main/resources/assets/minecraft/models/block/stairs_oak.json
deleted file mode 100644
index 27542819e..000000000
--- a/game/client/src/main/resources/assets/minecraft/models/block/stairs_oak.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "parent": "minecraft:block/stairs",
-  "textures": {
-    "bottom": "minecraft:block/planks/oak",
-    "side": "minecraft:block/planks/oak",
-    "top": "minecraft:block/planks/oak"
-  }
-}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/stone_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/stone_mossy.json
new file mode 100644
index 000000000..d94248c1d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/stone_mossy.json
@@ -0,0 +1,7 @@
+{
+  "parent": "minecraft:block/template_mossy",
+  "textures": {
+    "base": "minecraft:block/stone",
+    "overlay": "minecraft:block/moss_overlay"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sugarcane.json b/game/client/src/main/resources/assets/minecraft/models/block/sugarcane.json
new file mode 100644
index 000000000..0ab036bd2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sugarcane.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cross",
+  "textures": {
+    "cross": "minecraft:block/sugarcane"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/sulfur.json b/game/client/src/main/resources/assets/minecraft/models/block/sulfur.json
new file mode 100644
index 000000000..e8dd88ba5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/sulfur.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/sulfur"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/tallgrass.json b/game/client/src/main/resources/assets/minecraft/models/block/tallgrass.json
new file mode 100644
index 000000000..533f92bc8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/tallgrass.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cross",
+  "textures": {
+    "cross": "minecraft:block/tallgrass"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_jar.json b/game/client/src/main/resources/assets/minecraft/models/block/template_jar.json
new file mode 100644
index 000000000..df2e732bc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_jar.json
@@ -0,0 +1,48 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"ambientocclusion": false,
+	"parent": "block/cube",
+	"textures": {
+		"down": "#all",
+		"up": "#all",
+		"north": "#all",
+		"east": "#all",
+		"south": "#all",
+		"west": "#all"
+	},
+	"elements": [
+		{
+			"from": [5, 0, 5],
+			"to": [11, 6, 11],
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"east": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"south": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"west": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"down": {"uv": [6, 0, 12, 6], "texture": "#all", "cullface": "down"}
+			}
+		},
+		{
+			"from": [11, 0.05, 5],
+			"to": [5, 6, 11],
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"east": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"south": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"west": {"uv": [0, 8, 6, 14], "texture": "#all"},
+				"down": {"uv": [6, 0, 12, 6], "texture": "#all"}
+			}
+		},
+		{
+			"from": [5, 0, 5],
+			"to": [11, 4, 11],
+			"shade": false,
+			"faces": {
+				"up": {"uv": [0, 0, 6, 6], "texture": "#all"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_lantern.json b/game/client/src/main/resources/assets/minecraft/models/block/template_lantern.json
new file mode 100644
index 000000000..72054f7a8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_lantern.json
@@ -0,0 +1,78 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"ambientocclusion": false,
+	"parent": "block/cube",
+	"textures": {
+		"down": "#all",
+		"up": "#all",
+		"north": "#all",
+		"east": "#all",
+		"south": "#all",
+		"west": "#all"
+	},
+	"elements": [
+		{
+			"from": [5, 0, 5],
+			"to": [11, 8, 11],
+			"rotation": {"angle": 0, "axis": "y", "origin": [5, 0, 5]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"east": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"south": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"west": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"up": {"uv": [0, 0, 6, 6], "texture": "#all"},
+				"down": {"uv": [6, 0, 12, 6], "texture": "#all", "cullface": "down"}
+			}
+		},
+		{
+			"from": [11, 0.05, 5],
+			"to": [5, 8, 11],
+			"rotation": {"angle": 0, "axis": "y", "origin": [11, 0, 5]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"east": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"south": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"west": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"up": {"uv": [0, 0, 6, 6], "texture": "#all"},
+				"down": {"uv": [6, 0, 12, 6], "texture": "#all"}
+			}
+		},
+		{
+			"from": [6, 1, 6],
+			"to": [10, 7, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 1, 6]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"east": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"south": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"west": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"up": {"uv": [6, 6, 10, 10], "texture": "#all"},
+				"down": {"uv": [6, 6, 10, 10], "texture": "#all"}
+			}
+		},
+		{
+			"from": [8, 8, 6],
+			"to": [8, 10, 10],
+			"rotation": {"angle": -45, "axis": "y", "origin": [8, 9, 8]},
+			"shade": false,
+			"faces": {
+				"east": {"uv": [11, 7, 15, 9], "texture": "#all"},
+				"west": {"uv": [11, 7, 15, 9], "texture": "#all"}
+			}
+		},
+		{
+			"from": [6, 8, 8],
+			"to": [10, 10, 8],
+			"rotation": {"angle": -45, "axis": "y", "origin": [8, 9, 8]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [11, 7, 15, 9], "texture": "#all"},
+				"south": {"uv": [11, 7, 15, 9], "texture": "#all"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_lantern_hanging.json b/game/client/src/main/resources/assets/minecraft/models/block/template_lantern_hanging.json
new file mode 100644
index 000000000..2ec7551c8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_lantern_hanging.json
@@ -0,0 +1,78 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"ambientocclusion": false,
+	"parent": "block/cube",
+	"textures": {
+		"down": "#all",
+		"up": "#all",
+		"north": "#all",
+		"east": "#all",
+		"south": "#all",
+		"west": "#all"
+	},
+	"elements": [
+		{
+			"from": [5, 6, 5],
+			"to": [11, 14, 11],
+			"rotation": {"angle": 0, "axis": "y", "origin": [5, 0, 5]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"east": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"south": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"west": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"up": {"uv": [0, 0, 6, 6], "texture": "#all"},
+				"down": {"uv": [6, 0, 12, 6], "texture": "#all", "cullface": "down"}
+			}
+		},
+		{
+			"from": [11, 6, 5],
+			"to": [5, 14, 11],
+			"rotation": {"angle": 0, "axis": "y", "origin": [11, 0, 5]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"east": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"south": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"west": {"uv": [0, 6, 6, 14], "texture": "#all"},
+				"up": {"uv": [0, 0, 6, 6], "texture": "#all"},
+				"down": {"uv": [6, 0, 12, 6], "texture": "#all"}
+			}
+		},
+		{
+			"from": [6, 7, 6],
+			"to": [10, 15, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [6, 1, 6]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"east": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"south": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"west": {"uv": [6, 10, 10, 16], "texture": "#all"},
+				"up": {"uv": [6, 6, 10, 10], "texture": "#all"},
+				"down": {"uv": [6, 6, 10, 10], "texture": "#all"}
+			}
+		},
+		{
+			"from": [8, 14, 6],
+			"to": [8, 16, 10],
+			"rotation": {"angle": -45, "axis": "y", "origin": [8, 9, 8]},
+			"shade": false,
+			"faces": {
+				"east": {"uv": [11, 7, 15, 9], "texture": "#all"},
+				"west": {"uv": [11, 7, 15, 9], "texture": "#all"}
+			}
+		},
+		{
+			"from": [6, 14, 8],
+			"to": [10, 16, 8],
+			"rotation": {"angle": -45, "axis": "y", "origin": [8, 9, 8]},
+			"shade": false,
+			"faces": {
+				"north": {"uv": [11, 7, 15, 9], "texture": "#all"},
+				"south": {"uv": [11, 7, 15, 9], "texture": "#all"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_leaves.json b/game/client/src/main/resources/assets/minecraft/models/block/template_leaves.json
new file mode 100644
index 000000000..953fd919b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_leaves.json
@@ -0,0 +1,25 @@
+{
+    "parent": "block/block",
+    "textures": {
+        "overlay": "#all",
+        "particle_up": "#all",
+        "particle_down": "#all",
+        "particle_north": "#all",
+        "particle_south": "#all",
+        "particle_west": "#all",
+        "particle_east": "#all"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 16, 16 ],
+            "faces": {
+                "down":  { "texture": "#all", "cullface": "down", "tintindex": 0 },
+                "up":    { "texture": "#all", "cullface": "up", "tintindex": 0 },
+                "north": { "texture": "#all", "cullface": "north", "tintindex": 0 },
+                "south": { "texture": "#all", "cullface": "south", "tintindex": 0 },
+                "west":  { "texture": "#all", "cullface": "west", "tintindex": 0 },
+                "east":  { "texture": "#all", "cullface": "east", "tintindex": 0 }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_mossy.json b/game/client/src/main/resources/assets/minecraft/models/block/template_mossy.json
new file mode 100644
index 000000000..1b7dbbff3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_mossy.json
@@ -0,0 +1,39 @@
+{
+  "format_version": "1.21.6",
+  "credit": "Made with Blockbench",
+  "parent": "block/cube",
+  "textures": {
+    "down": "#overlay",
+    "up": "#overlay",
+    "north": "#overlay",
+    "east": "#overlay",
+    "south": "#overlay",
+    "west": "#overlay"
+  },
+  "elements": [
+    {
+      "from": [0, 0, 0],
+      "to": [16, 16, 16],
+      "faces": {
+        "north": {"uv": [0, 0, 16, 16], "texture": "#base"},
+        "east": {"uv": [0, 0, 16, 16], "texture": "#base"},
+        "south": {"uv": [0, 0, 16, 16], "texture": "#base"},
+        "west": {"uv": [0, 0, 16, 16], "texture": "#base"},
+        "up": {"uv": [0, 0, 16, 16], "texture": "#base"},
+        "down": {"uv": [0, 0, 16, 16], "texture": "#base"}
+      }
+    },
+    {
+      "from": [-0, -0, -0],
+      "to": [16, 16, 16],
+      "faces": {
+        "north": {"uv": [0, 0, 16, 16], "texture": "#overlay", "tintindex": 0},
+        "east": {"uv": [0, 0, 16, 16], "texture": "#overlay", "tintindex": 0},
+        "south": {"uv": [0, 0, 16, 16], "texture": "#overlay", "tintindex": 0},
+        "west": {"uv": [0, 0, 16, 16], "texture": "#overlay", "tintindex": 0},
+        "up": {"uv": [0, 0, 16, 16], "texture": "#overlay", "tintindex": 0},
+        "down": {"uv": [0, 0, 16, 16], "texture": "#overlay", "tintindex": 0}
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_portal.json b/game/client/src/main/resources/assets/minecraft/models/block/template_portal.json
new file mode 100644
index 000000000..f09178ae1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_portal.json
@@ -0,0 +1,26 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"renderlayer": 1,
+	"ambientocclusion": false,
+	"textures": {
+		"overlay": "#all",
+		"particle_up": "#all",
+		"particle_down": "#all",
+		"particle_north": "#all",
+		"particle_south": "#all",
+		"particle_west": "#all",
+		"particle_east": "#all"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 6],
+			"to": [16, 16, 10],
+			"rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 6]},
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#all"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#all"}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_torch.json b/game/client/src/main/resources/assets/minecraft/models/block/template_torch.json
new file mode 100644
index 000000000..38675e99b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_torch.json
@@ -0,0 +1,38 @@
+{
+    "ambientocclusion": false,
+    "parent": "block/cube",
+    "textures": {
+        "down": "#torch",
+        "up": "#torch",
+        "north": "#torch",
+        "east": "#torch",
+        "south": "#torch",
+        "west": "#torch"
+    },
+    "elements": [
+        {   "from": [ 7, 0, 7 ],
+            "to": [ 9, 10, 9 ],
+            "shade": false,
+            "faces": {
+                "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#torch" },
+                "up":   { "uv": [ 7,  6, 9,  8 ], "texture": "#torch" }
+            }
+        },
+        {   "from": [ 7, 0, 0 ],
+            "to": [ 9, 16, 16 ],
+            "shade": false,
+            "faces": {
+                "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" },
+                "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" }
+            }
+        },
+        {   "from": [ 0, 0, 7 ],
+            "to": [ 16, 16, 9 ],
+            "shade": false,
+            "faces": {
+                "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" },
+                "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_torch_wall.json b/game/client/src/main/resources/assets/minecraft/models/block/template_torch_wall.json
index a7083f018..ad4f4c5ff 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/template_torch_wall.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_torch_wall.json
@@ -1,7 +1,13 @@
 {
     "ambientocclusion": false,
+    "parent": "block/cube",
     "textures": {
-        "particle": "#torch"
+        "down": "#torch",
+        "up": "#torch",
+        "north": "#torch",
+        "east": "#torch",
+        "south": "#torch",
+        "west": "#torch"
     },
     "elements": [
         {   "from": [ -1, 3.5, 7 ],
@@ -9,12 +15,26 @@
             "rotation": { "origin": [ 0, 3.5, 8 ], "axis": "z", "angle": -22.5 },
             "shade": false,
             "faces": {
-                "down":  { "uv": [ 7, 13, 9, 15 ], "texture": "#torch" },
-                "up":    { "uv": [ 7,  6, 9,  8 ], "texture": "#torch" },
-                "north": { "uv": [ 7,  6, 9, 16 ], "texture": "#torch" },
-                "east":  { "uv": [ 7,  6, 9, 16 ], "texture": "#torch" },
-                "south": { "uv": [ 7,  6, 9, 16 ], "texture": "#torch" },
-                "west":  { "uv": [ 7,  6, 9, 16 ], "texture": "#torch" }
+                "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#torch" },
+                "up":   { "uv": [ 7,  6, 9,  8 ], "texture": "#torch" }
+            }
+        },
+        {   "from": [ -1, 3.5, 0 ],
+            "to": [ 1, 19.5, 16 ],
+            "rotation": { "origin": [ 0, 3.5, 8 ], "axis": "z", "angle": -22.5 },
+            "shade": false,
+            "faces": {
+                "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" },
+                "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" }
+            }
+        },
+        {   "from": [ -8, 3.5, 7 ],
+            "to": [ 8, 19.5, 9 ],
+            "rotation": { "origin": [ 0, 3.5, 8 ], "axis": "z", "angle": -22.5 },
+            "shade": false,
+            "faces": {
+                "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" },
+                "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#torch" }
             }
         }
     ]
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/tinted_cube_all.json b/game/client/src/main/resources/assets/minecraft/models/block/tinted_cube_all.json
new file mode 100644
index 000000000..dc451d3d7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/tinted_cube_all.json
@@ -0,0 +1,31 @@
+{
+    "parent": "block/block",
+    "textures": {
+        "overlay": "#north",
+        "particle_up": "#up",
+        "particle_down": "#down",
+        "particle_north": "#north",
+        "particle_south": "#south",
+        "particle_west": "#west",
+        "particle_east": "#east",
+        "down": "#all",
+        "up": "#all",
+        "north": "#all",
+        "east": "#all",
+        "south": "#all",
+        "west": "#all"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 16, 16 ],
+            "faces": {
+                "down":  { "texture": "#down", "cullface": "down", "tintindex": 0 },
+                "up":    { "texture": "#up", "cullface": "up", "tintindex": 0 },
+                "north": { "texture": "#north", "cullface": "north", "tintindex": 0 },
+                "south": { "texture": "#south", "cullface": "south", "tintindex": 0 },
+                "west":  { "texture": "#west", "cullface": "west", "tintindex": 0 },
+                "east":  { "texture": "#east", "cullface": "east", "tintindex": 0 }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/tnt.json b/game/client/src/main/resources/assets/minecraft/models/block/tnt.json
new file mode 100644
index 000000000..6c8057051
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/tnt.json
@@ -0,0 +1,8 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/tnt/top",
+    "bottom": "minecraft:block/tnt/bottom",
+    "side": "minecraft:block/tnt/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/torch_coal.json b/game/client/src/main/resources/assets/minecraft/models/block/torch_coal.json
new file mode 100644
index 000000000..5cdba1251
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/torch_coal.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_torch",
+  "textures": {
+    "torch": "minecraft:block/torch_coal"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/torch_wall.json b/game/client/src/main/resources/assets/minecraft/models/block/torch_coal_wall.json
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/models/block/torch_wall.json
rename to game/client/src/main/resources/assets/minecraft/models/block/torch_coal_wall.json
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_active.json b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_active.json
new file mode 100644
index 000000000..994d076f0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_active.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_torch",
+  "textures": {
+    "torch": "minecraft:block/torch_redstone_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_active_wall.json b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_active_wall.json
new file mode 100644
index 000000000..e1abda7ff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_active_wall.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_torch_wall",
+  "textures": {
+    "torch": "minecraft:block/torch_redstone_active"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_idle.json b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_idle.json
new file mode 100644
index 000000000..1b3f598bc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_idle.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_torch",
+  "textures": {
+    "torch": "minecraft:block/torch_redstone_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_idle_wall.json b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_idle_wall.json
new file mode 100644
index 000000000..c348f7ba7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/torch_redstone_idle_wall.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/template_torch_wall",
+  "textures": {
+    "torch": "minecraft:block/torch_redstone_idle"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/bottom.json
new file mode 100644
index 000000000..ddb91caff
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/bottom.json
@@ -0,0 +1,18 @@
+{   "parent": "block/block_thin",
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 0 ],
+            "to": [ 16, 3, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#texture" },
+                "north": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "north" },
+                "south": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "south" },
+                "west":  { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "west" },
+                "east":  { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "east" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/bottom.json
new file mode 100644
index 000000000..d4fc8d6ca
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/glass/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/open.json
new file mode 100644
index 000000000..c61fb150a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/glass/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/top.json
new file mode 100644
index 000000000..cd6052033
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/glass/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/bottom.json
new file mode 100644
index 000000000..2521efc51
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/iron/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/open.json
new file mode 100644
index 000000000..6ccf008a2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/iron/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/top.json
new file mode 100644
index 000000000..c2e8153a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/iron/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/iron/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/open.json
new file mode 100644
index 000000000..b301619c2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/open.json
@@ -0,0 +1,18 @@
+{
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "from": [ 0, 0, 13 ],
+            "to": [ 16, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [  0, 13, 16, 16 ], "texture": "#texture", "cullface": "down" },
+                "up":    { "uv": [  0, 16, 16, 13 ], "texture": "#texture", "cullface": "up" },
+                "north": { "uv": [  0,  0, 16, 16 ], "texture": "#texture" },
+                "south": { "uv": [  0,  0, 16, 16 ], "texture": "#texture", "cullface": "south" },
+                "west":  { "uv": [ 16,  0, 13, 16 ], "texture": "#texture", "cullface": "west" },
+                "east":  { "uv": [ 13,  0, 16, 16 ], "texture": "#texture", "cullface": "east" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/bottom.json
new file mode 100644
index 000000000..1bedfb69f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_black/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/open.json
new file mode 100644
index 000000000..2bcd38b62
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_black/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/top.json
new file mode 100644
index 000000000..6361ab404
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/black/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_black/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/bottom.json
new file mode 100644
index 000000000..add442be4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_blue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/open.json
new file mode 100644
index 000000000..e2cff455e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_blue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/top.json
new file mode 100644
index 000000000..f6abd8704
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/blue/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_blue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/bottom.json
new file mode 100644
index 000000000..dd9ec274c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_brown/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/open.json
new file mode 100644
index 000000000..7130f5e04
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_brown/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/top.json
new file mode 100644
index 000000000..01390b202
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/brown/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_brown/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/bottom.json
new file mode 100644
index 000000000..6da63681f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_cyan/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/open.json
new file mode 100644
index 000000000..f1538ee12
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_cyan/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/top.json
new file mode 100644
index 000000000..e276c4585
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/cyan/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_cyan/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/bottom.json
new file mode 100644
index 000000000..0090266a6
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_gray/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/open.json
new file mode 100644
index 000000000..cf25693a4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_gray/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/top.json
new file mode 100644
index 000000000..9b8aea9b4
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/gray/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_gray/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/bottom.json
new file mode 100644
index 000000000..90c2b1819
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_green/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/open.json
new file mode 100644
index 000000000..bf68ae8ab
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_green/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/top.json
new file mode 100644
index 000000000..9b8f513d7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/green/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_green/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/bottom.json
new file mode 100644
index 000000000..3b6ad5c94
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_lightblue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/open.json
new file mode 100644
index 000000000..a6fffb6d7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_lightblue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/top.json
new file mode 100644
index 000000000..1944ceb3e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lightblue/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_lightblue/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/bottom.json
new file mode 100644
index 000000000..e486edade
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_lime/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/open.json
new file mode 100644
index 000000000..d3006cca7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_lime/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/top.json
new file mode 100644
index 000000000..58887e97e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/lime/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_lime/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/bottom.json
new file mode 100644
index 000000000..a76786273
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_magenta/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/open.json
new file mode 100644
index 000000000..32f133ab3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_magenta/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/top.json
new file mode 100644
index 000000000..eb3f3ef2f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/magenta/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_magenta/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/bottom.json
new file mode 100644
index 000000000..9e9032a05
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/open.json
new file mode 100644
index 000000000..5f3da6a8c
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/top.json
new file mode 100644
index 000000000..e6844c41e
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/oak/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/bottom.json
new file mode 100644
index 000000000..f26b70c13
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_orange/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/open.json
new file mode 100644
index 000000000..a39d3a210
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_orange/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/top.json
new file mode 100644
index 000000000..f7ef46351
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/orange/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_orange/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/bottom.json
new file mode 100644
index 000000000..771e210f2
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_pink/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/open.json
new file mode 100644
index 000000000..8f89e2141
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_pink/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/top.json
new file mode 100644
index 000000000..a5032f249
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/pink/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_pink/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/bottom.json
new file mode 100644
index 000000000..732a8c9b7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_purple/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/open.json
new file mode 100644
index 000000000..d216fe930
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_purple/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/top.json
new file mode 100644
index 000000000..b92d6709b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/purple/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_purple/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/bottom.json
new file mode 100644
index 000000000..7fa536de8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_red/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/open.json
new file mode 100644
index 000000000..af3e79d50
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_red/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/top.json
new file mode 100644
index 000000000..aeceb4557
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/red/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_red/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/bottom.json
new file mode 100644
index 000000000..f76ce7242
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_silver/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/open.json
new file mode 100644
index 000000000..dcb435512
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_silver/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/top.json
new file mode 100644
index 000000000..6fd35ca76
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/silver/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_silver/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/bottom.json
new file mode 100644
index 000000000..ad474e2a1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_white/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/open.json
new file mode 100644
index 000000000..532545489
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_white/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/top.json
new file mode 100644
index 000000000..d92e5d7a9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/white/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_white/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/bottom.json
new file mode 100644
index 000000000..4655d86e1
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_yellow/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/open.json
new file mode 100644
index 000000000..8ae910c0d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_yellow/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/top.json
new file mode 100644
index 000000000..94505e1af
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/planks/yellow/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/planks_yellow/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/bottom.json
new file mode 100644
index 000000000..a5d750434
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/bottom.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/bottom",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/open.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/open.json
new file mode 100644
index 000000000..d94c76882
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/open.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/open",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/top.json
new file mode 100644
index 000000000..6c2e618c3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/steel/top.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/trapdoor/top",
+  "textures": {
+    "texture": "minecraft:block/trapdoor/steel/top"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/top.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/top.json
new file mode 100644
index 000000000..036aeb7b9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/top.json
@@ -0,0 +1,18 @@
+{
+    "textures": {
+        "particle": "#texture"
+    },
+    "elements": [
+        {   "from": [ 0, 13, 0 ],
+            "to": [ 16, 16, 16 ],
+            "faces": {
+                "down":  { "uv": [ 0,  0, 16, 16 ], "texture": "#texture" },
+                "up":    { "uv": [ 0,  0, 16, 16 ], "texture": "#texture", "cullface": "up" },
+                "north": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "north" },
+                "south": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "south" },
+                "west":  { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "west" },
+                "east":  { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "east" }
+            }
+        }
+    ]
+}
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trommel.json b/game/client/src/main/resources/assets/minecraft/models/block/trommel.json
new file mode 100644
index 000000000..c42392628
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trommel.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/trommel/top",
+    "bottom": "minecraft:block/trommel/bottom",
+    "south": "minecraft:block/trommel/idle_back",
+    "north": "minecraft:block/trommel/idle_front",
+    "west": "minecraft:block/trommel/side",
+    "east": "minecraft:block/trommel/side_slot"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/trommel_active.json b/game/client/src/main/resources/assets/minecraft/models/block/trommel_active.json
new file mode 100644
index 000000000..8394df71b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/trommel_active.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/trommel/top",
+    "bottom": "minecraft:block/trommel/bottom",
+    "south": "minecraft:block/trommel/active_back",
+    "north": "minecraft:block/trommel/active_front",
+    "west": "minecraft:block/trommel/side",
+    "east": "minecraft:block/trommel/side_slot"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/black.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/black.json
new file mode 100644
index 000000000..65d585ea5
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/black.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/black"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/blue.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/blue.json
new file mode 100644
index 000000000..28a9f25a3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/blue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/blue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/brown.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/brown.json
new file mode 100644
index 000000000..0a91159a3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/brown.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/brown"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/cyan.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/cyan.json
new file mode 100644
index 000000000..1687c4491
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/cyan.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/cyan"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/gray.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/gray.json
new file mode 100644
index 000000000..c937c88d3
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/gray.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/gray"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/green.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/green.json
new file mode 100644
index 000000000..314f1c5a8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/green.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/green"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/lightblue.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/lightblue.json
new file mode 100644
index 000000000..c99da24f9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/lightblue.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/lightblue"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/lime.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/lime.json
new file mode 100644
index 000000000..0cb349c29
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/lime.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/lime"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/magenta.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/magenta.json
new file mode 100644
index 000000000..f5336f1da
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/magenta.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/magenta"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/orange.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/orange.json
new file mode 100644
index 000000000..94c3ee891
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/orange.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/orange"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/pink.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/pink.json
new file mode 100644
index 000000000..4ca5973d8
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/pink.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/pink"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/purple.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/purple.json
new file mode 100644
index 000000000..51c898b41
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/purple.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/purple"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/red.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/red.json
new file mode 100644
index 000000000..627b628e9
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/red.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/red"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/silver.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/silver.json
new file mode 100644
index 000000000..f9294a982
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/silver.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/silver"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/white.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/white.json
new file mode 100644
index 000000000..efec5b787
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/white.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/white"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/wool/yellow.json b/game/client/src/main/resources/assets/minecraft/models/block/wool/yellow.json
new file mode 100644
index 000000000..e8238c26a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/wool/yellow.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/wool/yellow"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/workbench.json b/game/client/src/main/resources/assets/minecraft/models/block/workbench.json
new file mode 100644
index 000000000..4bf928508
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/workbench.json
@@ -0,0 +1,11 @@
+{
+  "parent": "minecraft:block/cube_bottom_top",
+  "textures": {
+    "top": "minecraft:block/workbench/top",
+    "bottom": "minecraft:block/workbench/bottom",
+    "north": "minecraft:block/workbench/front",
+    "south": "minecraft:block/workbench/front",
+    "west": "minecraft:block/workbench/side",
+    "east": "minecraft:block/workbench/side"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/basket/top.png b/game/client/src/main/resources/assets/minecraft/textures/block/basket/top.png
new file mode 100644
index 000000000..358f6a79e
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/basket/top.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/side.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond.png
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/side.png
rename to game/client/src/main/resources/assets/minecraft/textures/block/block_diamond.png
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/bottom.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/bottom.png
deleted file mode 100644
index 1e9558983..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/bottom.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/bottom_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/bottom_retro.png
deleted file mode 100644
index ee47be028..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/bottom_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/side_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/side_retro.png
deleted file mode 100644
index d31d26d71..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/side_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/top.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/top.png
deleted file mode 100644
index 65ffa68f3..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/top.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/top_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/top_retro.png
deleted file mode 100644
index c9b0af7af..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_diamond/top_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/side.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_gold.png
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/textures/block/block_gold/side.png
rename to game/client/src/main/resources/assets/minecraft/textures/block/block_gold.png
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/bottom.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/bottom.png
deleted file mode 100644
index 4b3ac636d..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/bottom.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/bottom_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/bottom_retro.png
deleted file mode 100644
index b4e4f7c18..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/bottom_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/side_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/side_retro.png
deleted file mode 100644
index 9962d72ad..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/side_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/top.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/top.png
deleted file mode 100644
index 52e94b175..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/top.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/top_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/top_retro.png
deleted file mode 100644
index fc5715a0a..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_gold/top_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/side.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_iron.png
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/textures/block/block_iron/side.png
rename to game/client/src/main/resources/assets/minecraft/textures/block/block_iron.png
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/bottom.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/bottom.png
deleted file mode 100644
index 134f102f4..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/bottom.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/bottom_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/bottom_retro.png
deleted file mode 100644
index fbfbfdb6d..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/bottom_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/side_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/side_retro.png
deleted file mode 100644
index 0d7f2e949..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/side_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/top.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/top.png
deleted file mode 100644
index 7b9139359..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/top.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/top_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/top_retro.png
deleted file mode 100644
index cb402081a..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_iron/top_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_steel/bottom.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_steel.png
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/textures/block/block_steel/bottom.png
rename to game/client/src/main/resources/assets/minecraft/textures/block/block_steel.png
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_steel/side.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_steel/side.png
deleted file mode 100644
index 043d4b6a9..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_steel/side.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/block_steel/top.png b/game/client/src/main/resources/assets/minecraft/textures/block/block_steel/top.png
deleted file mode 100644
index 043d4b6a9..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/block_steel/top.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/side.png b/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf.png
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/side.png
rename to game/client/src/main/resources/assets/minecraft/textures/block/bookshelf.png
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/side_retro.png b/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/side_retro.png
deleted file mode 100644
index a87a69657..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/side_retro.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/top.png b/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/top.png
deleted file mode 100644
index 0e743b846..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/bookshelf/top.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/door/glass/bottom_left.png b/game/client/src/main/resources/assets/minecraft/textures/block/door/glass/bottom_left.png
new file mode 100644
index 000000000..96c259a13
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/door/glass/bottom_left.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/door/glass/top_left.png b/game/client/src/main/resources/assets/minecraft/textures/block/door/glass/top_left.png
new file mode 100644
index 000000000..4616982da
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/door/glass/top_left.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/farmland/dry.png b/game/client/src/main/resources/assets/minecraft/textures/block/farmland/dry.png
deleted file mode 100644
index 4a17787e9..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/farmland/dry.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/farmland/wet.png b/game/client/src/main/resources/assets/minecraft/textures/block/farmland/wet.png
deleted file mode 100644
index 344268a9c..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/farmland/wet.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/jukebox/top.png b/game/client/src/main/resources/assets/minecraft/textures/block/jukebox.png
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/textures/block/jukebox/top.png
rename to game/client/src/main/resources/assets/minecraft/textures/block/jukebox.png
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/jukebox/bottom.png b/game/client/src/main/resources/assets/minecraft/textures/block/jukebox/bottom.png
deleted file mode 100644
index 4a37b676c..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/jukebox/bottom.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/jukebox/side.png b/game/client/src/main/resources/assets/minecraft/textures/block/jukebox/side.png
deleted file mode 100644
index 4a37b676c..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/jukebox/side.png and /dev/null differ
diff --git a/game/client/src/main/resources/shaders/clouds.fsh b/game/client/src/main/resources/shaders/clouds.fsh
index 707540157..7af39eadc 100644
--- a/game/client/src/main/resources/shaders/clouds.fsh
+++ b/game/client/src/main/resources/shaders/clouds.fsh
@@ -30,7 +30,7 @@ uniform sampler2D colortex;
 uniform sampler2D lighttex;
 
 float distance() {
-	vec4 fragPos = matrices.projectionInv * vec4((gl_FragCoord.xy / uViewPortSize) * 2.0f - 1.0f, gl_FragCoord.z * 2.0f - 1.0f, 1.0f);
+	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);
@@ -40,7 +40,7 @@ void main() {
 	vec4 tex = texture(colortex, TexCoord);
 	
 	// Alpha test
-	if(tex.a < 0.1f) {
+	if(tex.a < 0.1) {
 		discard;
 	}
 	
@@ -51,16 +51,16 @@ void main() {
 	
 	vec4 col = Color;
 
-	float fogStrength = 0.0f;
+	float fogStrength = 0.0;
 
-	float end = (fogState.end * 1.5f);
-	float start = fogState.start / (fogState.end * 1.5f);
+	float end = (fogState.end * 1.5);
+	float start = fogState.start / (fogState.end * 1.5);
 
 	fogStrength = distance() / end;
 	fogStrength -= start;
-	fogStrength /= (1.0f - start);
-	fogStrength = clamp(fogStrength, 0.0f, 1.0f);
-	col.a *= 1.0f - fogStrength;
+	fogStrength /= (1.0 - start);
+	fogStrength = clamp(fogStrength, 0.0, 1.0);
+	col.a *= 1.0 - fogStrength;
 	
 	FragColor = tex * col;
 }
\ No newline at end of file
diff --git a/game/client/src/main/resources/shaders/color_world.fsh b/game/client/src/main/resources/shaders/color_world.fsh
index f74eec6b4..7f3d1bcb4 100644
--- a/game/client/src/main/resources/shaders/color_world.fsh
+++ b/game/client/src/main/resources/shaders/color_world.fsh
@@ -27,7 +27,7 @@ layout (std140) uniform Matrices {
 uniform sampler2D lighttex;
 
 float distance() {
-    vec4 fragPos = matrices.projectionInv * vec4((gl_FragCoord.xy / uViewPortSize) * 2.0f - 1.0f, gl_FragCoord.z * 2.0f - 1.0f, 1.0f);
+    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);
@@ -70,7 +70,7 @@ void main() {
     vec4 litColor = vec4(oColor.rgb * clamp(Light, 0, 1), oColor.a);
 
     FragColor = computeFog(oColor);
-    if (FragColor.a < 0.1f) {
+    if (FragColor.a < 0.1) {
         discard;
     }
 }
diff --git a/game/client/src/main/resources/shaders/color_world.vsh b/game/client/src/main/resources/shaders/color_world.vsh
index 15a642158..8a30d9bfa 100644
--- a/game/client/src/main/resources/shaders/color_world.vsh
+++ b/game/client/src/main/resources/shaders/color_world.vsh
@@ -32,7 +32,7 @@ void main() {
     LightMapCoord = aLightmap;
 
     vec4 norm = normalize(normalTransform * model * vec4(aNormal, 0));
-    float dir1 = max(0.0f, dot(norm, lightSourcePosition1));
-    float dir2 = max(0.0f, dot(norm, lightSourcePosition2));
+    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 a5146ab49..69ed2922c 100644
--- a/game/client/src/main/resources/shaders/font.fsh
+++ b/game/client/src/main/resources/shaders/font.fsh
@@ -12,7 +12,7 @@ uniform sampler2D lighttex;
 
 void main() {
     FragColor = texture(colortex, TexCoord) * texture(lighttex, Lightmap) * Color * uColor;
-    if (FragColor.a < 0.1f) {
+    if (FragColor.a < 0.1) {
         discard;
     }
 }
\ No newline at end of file
diff --git a/game/client/src/main/resources/shaders/font.vsh b/game/client/src/main/resources/shaders/font.vsh
index 6c8c69500..66ffb5e4c 100644
--- a/game/client/src/main/resources/shaders/font.vsh
+++ b/game/client/src/main/resources/shaders/font.vsh
@@ -24,7 +24,7 @@ void main() {
     vs_out.size = aSize;
     vs_out.shift = aShift;
     vs_out.color = aColor;
-    vs_out.uv = aUv/256.0f;
-    vs_out.uvSizes = aUvSizes/256.0f;
+    vs_out.uv = aUv/256.0;
+    vs_out.uvSizes = aUvSizes/256.0;
     vs_out.lightmap = aLightmap;
 }
diff --git a/game/client/src/main/resources/shaders/lines.fsh b/game/client/src/main/resources/shaders/lines.fsh
index 856034cf0..228db697d 100644
--- a/game/client/src/main/resources/shaders/lines.fsh
+++ b/game/client/src/main/resources/shaders/lines.fsh
@@ -6,7 +6,7 @@ uniform vec4 uColor;
 
 void main() {
     FragColor = Color * uColor;
-    if (FragColor.a < 0.1f) {
+    if (FragColor.a < 0.1) {
         discard;
     }
 }
diff --git a/game/client/src/main/resources/shaders/particle.fsh b/game/client/src/main/resources/shaders/particle.fsh
index 2d23f4c9e..66678e4fa 100644
--- a/game/client/src/main/resources/shaders/particle.fsh
+++ b/game/client/src/main/resources/shaders/particle.fsh
@@ -10,7 +10,7 @@ uniform sampler2D lighttex;
 
 void main() {
     FragColor = texture(colortex, TexCoord) * texture(lighttex, Lightmap) * Color;
-    if (FragColor.a < 0.1f) {
+    if (FragColor.a < 0.1) {
         discard;
     }
 }
\ No newline at end of file
diff --git a/game/client/src/main/resources/shaders/post/base.fsh b/game/client/src/main/resources/shaders/post/base.fsh
index 1f1cfc31a..f4a539a0a 100644
--- a/game/client/src/main/resources/shaders/post/base.fsh
+++ b/game/client/src/main/resources/shaders/post/base.fsh
@@ -25,7 +25,7 @@ vec3 cbCorrection(vec3 tex)
 
     if (mode == 4)//Grayscale
     {
-        return vec3((tex.r + tex.g + tex.b) / 3.0f);
+        return vec3((tex.r + tex.g + tex.b) / 3.0);
     }
 
     float L = (17.8824 * tex.r) + (43.5161 * tex.g) + (4.11935 * tex.b);
diff --git a/game/client/src/main/resources/shaders/post/post.fsh b/game/client/src/main/resources/shaders/post/post.fsh
index 180f9656c..bc044ee4d 100644
--- a/game/client/src/main/resources/shaders/post/post.fsh
+++ b/game/client/src/main/resources/shaders/post/post.fsh
@@ -32,7 +32,7 @@ uniform float frameTimeCounter;
 // FXAA defines
 #define FXAA_REDUCE_MIN   (1.0/ 128.0)
 #define FXAA_REDUCE_MUL   (1.0 / 8.0)
-float FXAA_SPAN_MAX = 8.0f * fxaa;
+float FXAA_SPAN_MAX = 8.0 * fxaa;
 
 vec4 applyFXAA(vec2 fragCoord, sampler2D tex, vec2 uViewportSize) {
     vec4 color;
@@ -102,46 +102,46 @@ vec3 adjustColor(vec3 color, float rValue, float gValue, float bValue) {
 }
 
 void Bloom(inout vec3 color) {
-	vec3 blur = vec3(0.0f);
+	vec3 blur = vec3(0.0);
 	
 	int quality = 7 * bloom;
 	float range = 10 * (3 - bloom);
 	
-	float qh = quality / 2.0f - 0.5f;
-	float allStrengths = 0.0f;
+	float qh = quality / 2.0 - 0.5;
+	float allStrengths = 0.0;
 	for(int i=0; i < quality; i++) {
 		for(int j=0; j < quality; j++) {
 			vec2 offset = vec2((i - qh) * range / width, (j - qh) * range / height);
 			
-			float dist = 1.33f - distance(vec2(qh), vec2(i, j)) / qh;
+			float dist = 1.33 - distance(vec2(qh), vec2(i, j)) / qh;
 			
 			float strength = dist;
 			
-			blur += pow(texture(colortex0, TexCoords + offset).rgb, vec3(2.2f)) * strength;
+			blur += pow(texture(colortex0, TexCoords + offset).rgb, vec3(2.2)) * strength;
 			allStrengths += strength;
 		}
 	}
 	
 	blur /= allStrengths;
 	
-	color.rgb *= 1.0f - (bloom * 0.1f);
-	color.rgb += blur.rgb * 0.15f * bloom;
+	color.rgb *= 1.0 - (bloom * 0.1);
+	color.rgb += blur.rgb * 0.15 * bloom;
 }
 
 void HeatHaze(inout vec2 coord, float amount) {
 	float depth = texture(depthtex0, coord.xy).r;
 	float strength = pow(depth, 500);
-	strength = (strength - 0.16) * 2.0f;
-	strength = clamp(strength, 0.0f, 1.0f) * amount;
+	strength = (strength - 0.16) * 2.0;
+	strength = clamp(strength, 0.0, 1.0) * amount;
 	
-	vec2 wave = vec2(0.0f, 0.0f);
+	vec2 wave = vec2(0.0, 0.0);
 	
 	float waveSize = 50;
 	wave.x += sin(coord.y * 1.3 * waveSize + frameTimeCounter * 10);
 	wave.x += sin(coord.y * 5.0 * waveSize + frameTimeCounter * 14);
 	wave.y += sin(coord.x * 1.0 * waveSize + frameTimeCounter * 5) * 2;
 	
-	coord += wave * strength * 0.0001f;
+	coord += wave * strength * 0.0001;
 }
 
 
diff --git a/game/client/src/main/resources/shaders/terrain.fsh b/game/client/src/main/resources/shaders/terrain.fsh
index e7b0b1e1f..5d742d0ea 100644
--- a/game/client/src/main/resources/shaders/terrain.fsh
+++ b/game/client/src/main/resources/shaders/terrain.fsh
@@ -6,6 +6,7 @@ in vec4 Color;
 in vec2 TexCoord;
 in vec2 LightMapCoord;
 in vec3 Light;
+in vec3 Norm;
 
 uniform vec4 uColor;
 uniform vec2 uViewPortSize;
@@ -31,7 +32,7 @@ uniform sampler2D emmisivetex;
 //uniform sampler2D colormasktex;
 
 float distance() {
-    vec4 fragPos = matrices.projectionInv * vec4((gl_FragCoord.xy / uViewPortSize) * 2.0f - 1.0f, gl_FragCoord.z * 2.0f - 1.0f, 1.0f);
+    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);
@@ -80,12 +81,13 @@ void main() {
 
     vec4 postColor = oColor * c * uColor;
     vec4 litColor = vec4(postColor.rgb * clamp(Light, 0, 1), postColor.a);
+//    vec4 litColor = vec4(abs(Norm), 1f);
 
     vec4 fColor = computeFog(litColor);
 
 
     FragColor = fColor;
-    if (FragColor.a < 0.1f) {
+    if (FragColor.a < 0.1) {
         discard;
     }
 }
diff --git a/game/client/src/main/resources/shaders/terrain.vsh b/game/client/src/main/resources/shaders/terrain.vsh
index 4df0a92fb..bad079d51 100644
--- a/game/client/src/main/resources/shaders/terrain.vsh
+++ b/game/client/src/main/resources/shaders/terrain.vsh
@@ -9,11 +9,14 @@ out vec4 Color;
 out vec2 TexCoord;
 out vec2 LightMapCoord;
 out vec3 Light;
+out vec3 Norm;
 
 uniform mat4 normalTransform;
 uniform vec4 lightModelAmbient;
-uniform vec4 lightSourcePosition[];
-uniform vec4 lightSourceDiffuse[];
+uniform vec4 lightSourcePosition1;
+uniform vec4 lightSourcePosition2;
+uniform vec4 lightSourceDiffuse1;
+uniform vec4 lightSourceDiffuse2;
 
 uniform mat4 model;
 
@@ -32,8 +35,9 @@ void main() {
     Color = aColor;
     LightMapCoord = aLightmap;
 
-    vec3 norm = normalize(aNormal);
-    float d1 = max(0.0, dot(norm, vec3(-0.2f, 1f, -0.7f)));
-    float d2 = max(0.0, dot(norm, vec3( 0.2f, 1f,  0.7f)));
-    Light = vec3(0.5, 0.5, 0.5) + vec3(0.5, 0.5, 0.5) * clamp(d1 + d2, 0, 1);
+    Norm = normalize(aNormal);
+    vec4 norm = normalize(normalTransform * model * 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/world.fsh b/game/client/src/main/resources/shaders/world.fsh
index 1dd6db044..802eb8b50 100644
--- a/game/client/src/main/resources/shaders/world.fsh
+++ b/game/client/src/main/resources/shaders/world.fsh
@@ -29,7 +29,7 @@ uniform sampler2D colortex;
 uniform sampler2D lighttex;
 
 float distance() {
-    vec4 fragPos = matrices.projectionInv * vec4((gl_FragCoord.xy / uViewPortSize) * 2.0f - 1.0f, gl_FragCoord.z * 2.0f - 1.0f, 1.0f);
+    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);
@@ -76,7 +76,7 @@ void main() {
 
 
     FragColor = fColor;
-    if (FragColor.a < 0.1f) {
+    if (FragColor.a < 0.1) {
         discard;
     }
 }
diff --git a/game/client/src/main/resources/shaders/world.vsh b/game/client/src/main/resources/shaders/world.vsh
index e6abd030c..ed183056e 100644
--- a/game/client/src/main/resources/shaders/world.vsh
+++ b/game/client/src/main/resources/shaders/world.vsh
@@ -31,12 +31,12 @@ void main() {
     vec4 p = vec4(aPos, 1);
     gl_Position = matrices.projection * matrices.view * model * p;
 
-    TexCoord = (texture * vec4(aUV, 0.0f, 1.0f)).xy;
+    TexCoord = (texture * vec4(aUV, 0.0, 1.0)).xy;
     Color = aColor;
     LightMapCoord = aLightmap;
 
     vec4 norm = normalize(normalTransform * model * vec4(aNormal, 0));
-    float dir1 = max(0.0f, dot(norm, lightSourcePosition1));
-    float dir2 = max(0.0f, dot(norm, lightSourcePosition2));
+    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/core/src/main/java/net/minecraft/core/block/BlockLogicAlgae.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicAlgae.java
index f486b5089..2d12717ca 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
@@ -87,7 +87,7 @@ public class BlockLogicAlgae
         final @NotNull Random rand = world.rand;
 
         if (!world.isClientSide) {
-            if (player == null || player.getGamemode().consumeBlocks()) {
+            if (player == null || player.getGamemode().hasBlockConsumption()) {
                 itemStack.stackSize--;
             }
             TilePos queryPos = new TilePos();
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 9fd2d1fb9..f77fe0923 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
@@ -37,7 +37,7 @@ public class BlockLogicBed
         int data = world.getBlockData(tilePos);
         final @NotNull TilePosc headPos;
         final @NotNull TilePosc footPos;
-        if (!isBlockFootOfBed(data)) {
+        if (!isBlockHeadOfBed(data)) {
             final int dir = getDirection(data);
             headPos = tilePos;
             footPos = tilePos.add(headBlockToFootBlockMap[dir].getDirection(), new TilePos());
@@ -48,7 +48,7 @@ public class BlockLogicBed
         }
 
         // Check if bed is not complete
-        if (!isBlockFootOfBed(data)) {
+        if (!isBlockHeadOfBed(data)) {
             if (world.getBlock(footPos) != this.block) {
                 return true;
             }
@@ -122,7 +122,7 @@ public class BlockLogicBed
     protected void removeOtherHalf(final @NotNull World world, final @NotNull TilePosc tilePos) {
         final int data = world.getBlockData(tilePos);
         final int direction = getDirection(data);
-        if (isBlockFootOfBed(data)) {
+        if (isBlockHeadOfBed(data)) {
             if (world.getBlockId(tilePos.sub(headBlockToFootBlockMap[direction].getDirection(), new TilePos())) != this.block.id()) {
                 world.setBlockIdNotify(tilePos, 0);
             }
@@ -145,7 +145,7 @@ public class BlockLogicBed
     public static final int MASK_IS_OCCUPIED = 0b0000_0100;
     public static final int MASK_DIRECTION = 0b0000_0011;
 
-    public static boolean isBlockFootOfBed(final int meta) {
+    public static boolean isBlockHeadOfBed(final int meta) {
         return (meta & MASK_IS_FOOT) != 0;
     }
 
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 76c0777c7..94fe358bf 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
@@ -139,7 +139,7 @@ public class BlockLogicCactus
     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.isClientSide) {
             this.growCactusOnTop(world, tilePos);
-            if (player == null || player.getGamemode().consumeBlocks()) {
+            if (player == null || player.getGamemode().hasBlockConsumption()) {
                 itemStack.stackSize--;
             }
         }
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 ae4a7f074..fd7614437 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
@@ -121,7 +121,7 @@ public class BlockLogicCropsPumpkin
         if (world.getBlockData(tilePos) < 5) {
             if (!world.isClientSide) {
                 world.setBlockIdNotify(tilePos, Blocks.PUMPKIN.id());
-                if (player == null || player.getGamemode().consumeBlocks()) {
+                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 67ae856f1..ffb87b722 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
@@ -120,7 +120,7 @@ public class BlockLogicCropsWheat extends BlockLogicFlower implements IBonemeala
         if (world.getBlockData(tilePos) < MAX_GROWTH_STATE) {
             if (!world.isClientSide) {
                 world.setBlockDataNotify(tilePos, MAX_GROWTH_STATE);
-                if (player == null || player.getGamemode().consumeBlocks()) {
+                if (player == null || player.getGamemode().hasBlockConsumption()) {
                     itemStack.stackSize--;
                 }
             }
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 15d652fce..94dd51f61 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
@@ -117,7 +117,7 @@ public class BlockLogicLeavesCacao extends BlockLogicLeavesBase implements IBone
                 if (world.getSeasonManager().getCurrentSeason() != Seasons.OVERWORLD_SUMMER)
                     return true;
                 world.setBlockDataNotify(tilePos, setGrowthRate(meta, MAX_GROWTH_STATE));
-                if (player == null || player.getGamemode().consumeBlocks()) {
+                if (player == null || player.getGamemode().hasBlockConsumption()) {
                     itemStack.stackSize--;
                 }
             }
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 a4381e965..447ec0dad 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
@@ -96,7 +96,7 @@ public class BlockLogicLeavesCherryFlowering extends BlockLogicLeavesCherry impl
                 if(world.getSeasonManager().getCurrentSeason() != Seasons.OVERWORLD_SPRING)
                     return true;
                 world.setBlockDataNotify(tilePos, setGrowthRate(meta, MAX_GROWTH_STATE));
-                if (player == null || player.getGamemode().consumeBlocks()) {
+                if (player == null || player.getGamemode().hasBlockConsumption()) {
                     itemStack.stackSize--;
                 }
             }
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 f741b9fad..3e52c5c49 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
@@ -25,7 +25,7 @@ public class BlockLogicMeshGold extends BlockLogicMesh {
             boolean flag = meshGold.setFilterItem(player, heldItem);
             world.notifyBlocksOfNeighborChange(tilePos, id());
             if(heldItem != null && heldItem.stackSize <= 0) {
-                player.inventory.setItem(player.inventory.getCurrentItemIndex(), null);
+                player.inventory.setItem(player.inventory.getCurrentSlot(), null);
             }
             return flag;
         }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java
index 106c46fd3..e2ffc3aff 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMobSpawner.java
@@ -7,7 +7,7 @@ import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePosc;
@@ -23,7 +23,7 @@ public class BlockLogicMobSpawner extends BlockLogicMobSpawnerDeactivated {
 
     @Override
     public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) {
-        if (player.getGamemode() != Gamemode.creative) {
+        if (player.getGamemode() != Gamemodes.CREATIVE) {
             return false;
         }
 
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 a78775613..d96ef8f25 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
@@ -112,7 +112,7 @@ public class BlockLogicMoss extends BlockLogic implements IBonemealable {
     public boolean onBonemealUsed(@NotNull ItemStack itemStack, @Nullable Player player, @NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
         if (!world.isClientSide) {
             if (!canMossSpread(world, tilePos) || !airExposed(world, tilePos)) return false;
-            if (player == null || player.getGamemode().consumeBlocks()) {
+            if (player == null || player.getGamemode().hasBlockConsumption()) {
                 itemStack.stackSize--;
             }
             for (int i = 0; i < 32; i++) {
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 261b8d879..21235eedd 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
@@ -51,7 +51,7 @@ public class BlockLogicMushroom extends BlockLogicFlower {
     public boolean onBonemealUsed(@NotNull ItemStack itemStack, @Nullable Player player, @NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
         Random rand = world.rand;
         if (!world.isClientSide && this.canBeBonemealed) {
-            if (player == null || player.getGamemode().consumeBlocks()) {
+            if (player == null || player.getGamemode().hasBlockConsumption()) {
                 itemStack.stackSize--;
             }
 
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 befa6e0e7..9079469f3 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
@@ -144,7 +144,7 @@ public class BlockLogicRope
             ropesCollected++;
         }
 
-        if (player.getGamemode().consumeBlocks()) {
+        if (player.getGamemode().hasBlockConsumption()) {
             ItemStack stack = new ItemStack(Items.ROPE, ropesCollected);
             player.inventory.insertItem(stack, true);
             if (stack.stackSize > 0) {
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBase.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSaplingBase.java
index 1ac8e43aa..70566c07e 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
@@ -60,7 +60,7 @@ public abstract class BlockLogicSaplingBase extends BlockLogicFlower implements
     public boolean onBonemealUsed(@NotNull ItemStack itemStack, @Nullable Player player, @NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
         if (!world.isClientSide) {
             growTree(world, tilePos, world.rand);
-            if (player == null || player.getGamemode().consumeBlocks()) {
+            if (player == null || player.getGamemode().hasBlockConsumption()) {
                 itemStack.stackSize--;
             }
         }
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 4333eb06e..9fc5376de 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
@@ -126,7 +126,7 @@ public class BlockLogicSign extends BlockLogic implements IPaintable {
             ItemStack heldItem = player.getHeldItem();
             if (heldItem != null && heldItem.itemID == Items.DUST_GLOWSTONE.id && !signEntity.isGlowing() && heldItem.consumeItem(player)) {
                 signEntity.setGlowing(true);
-                if (player.getGamemode().consumeBlocks()) {
+                if (player.getGamemode().hasBlockConsumption()) {
                     heldItem.stackSize--;
                 }
                 player.addStat(Achievements.LIGHT_SIGN, 1);
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 dff58702a..8dd27b5f6 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
@@ -126,7 +126,7 @@ public class BlockLogicSugarcane extends BlockLogic implements IBonemealable {
     public boolean onBonemealUsed(@NotNull ItemStack itemStack, @Nullable Player player, World world, @NotNull TilePosc tilePos, @NotNull Side side, double xHit, double yHit) {
         if (!world.isClientSide) {
             growReedOnTop(world, tilePos);
-            if (player == null || player.getGamemode().consumeBlocks()) {
+            if (player == null || player.getGamemode().hasBlockConsumption()) {
                 itemStack.stackSize--;
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityActivator.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityActivator.java
index de37cda71..a370135b2 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityActivator.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityActivator.java
@@ -37,27 +37,27 @@ public class TileEntityActivator extends TileEntity implements Container {
     }
 
     @Override
-    public @Nullable ItemStack getItem(int index)
+    public @Nullable ItemStack getItem(int slot)
     {
-        return dispenserContents[index];
+        return dispenserContents[slot];
     }
 
     @Override
-    public @Nullable ItemStack removeItem(int index, int takeAmount)
+    public @Nullable ItemStack removeItem(int slot, int takeAmount)
     {
-        if(dispenserContents[index] != null)
+        if(dispenserContents[slot] != null)
         {
-            if(dispenserContents[index].stackSize <= takeAmount)
+            if(dispenserContents[slot].stackSize <= takeAmount)
             {
-                ItemStack itemstack = dispenserContents[index];
-                dispenserContents[index] = null;
+                ItemStack itemstack = dispenserContents[slot];
+                dispenserContents[slot] = null;
                 setChanged();
                 return itemstack;
             }
-            ItemStack itemstack1 = dispenserContents[index].splitStack(takeAmount);
-            if(dispenserContents[index].stackSize <= 0)
+            ItemStack itemstack1 = dispenserContents[slot].splitStack(takeAmount);
+            if(dispenserContents[slot].stackSize <= 0)
             {
-                dispenserContents[index] = null;
+                dispenserContents[slot] = null;
             }
             setChanged();
             return itemstack1;
@@ -120,18 +120,18 @@ public class TileEntityActivator extends TileEntity implements Container {
     }
 
     @Override
-    public void setItem(int index, @Nullable ItemStack itemstack)
+    public void setItem(int slot, @Nullable ItemStack stack)
     {
-        dispenserContents[index] = itemstack;
-        if(itemstack != null && itemstack.stackSize > getMaxStackSize())
+        dispenserContents[slot] = stack;
+        if(stack != null && stack.stackSize > getMaxStackSize())
         {
-            itemstack.stackSize = getMaxStackSize();
+            stack.stackSize = getMaxStackSize();
         }
         setChanged();
     }
 
     @Override
-    public String getNameTranslationKey()
+    public @NotNull String getNameTranslationKey()
     {
         return "container.activator.name";
     }
@@ -182,17 +182,17 @@ public class TileEntityActivator extends TileEntity implements Container {
     }
 
     @Override
-    public boolean stillValid(Player entityplayer)
+    public boolean stillValid(@NotNull Player player)
     {
         if(worldObj == null || worldObj.getTileEntity(x, y, z) != this)
         {
             return false;
         }
-        return entityplayer.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityChest.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityChest.java
index 162af9669..4b48855bf 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityChest.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityChest.java
@@ -35,27 +35,27 @@ public class TileEntityChest extends TileEntity
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
+	public @Nullable ItemStack getItem(int slot)
     {
-        return chestContents[index];
+        return chestContents[slot];
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
+	public @Nullable ItemStack removeItem(int slot, int takeAmount)
     {
-        if(chestContents[index] != null)
+        if(chestContents[slot] != null)
         {
-            if(chestContents[index].stackSize <= takeAmount)
+            if(chestContents[slot].stackSize <= takeAmount)
             {
-                ItemStack itemstack = chestContents[index];
-                chestContents[index] = null;
+                ItemStack itemstack = chestContents[slot];
+                chestContents[slot] = null;
                 setChanged();
                 return itemstack;
             }
-            ItemStack itemstack1 = chestContents[index].splitStack(takeAmount);
-            if(chestContents[index].stackSize <= 0)
+            ItemStack itemstack1 = chestContents[slot].splitStack(takeAmount);
+            if(chestContents[slot].stackSize <= 0)
             {
-                chestContents[index] = null;
+                chestContents[slot] = null;
             }
             setChanged();
             return itemstack1;
@@ -66,18 +66,18 @@ public class TileEntityChest extends TileEntity
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
+	public void setItem(int slot, @Nullable ItemStack stack)
     {
-        chestContents[index] = itemstack;
-        if(itemstack != null && itemstack.stackSize > getMaxStackSize())
+        chestContents[slot] = stack;
+        if(stack != null && stack.stackSize > getMaxStackSize())
         {
-            itemstack.stackSize = getMaxStackSize();
+            stack.stackSize = getMaxStackSize();
         }
         setChanged();
     }
 
     @Override
-	public String getNameTranslationKey()
+	public @NotNull String getNameTranslationKey()
     {
         return "container.chest.name";
     }
@@ -123,17 +123,17 @@ public class TileEntityChest extends TileEntity
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
+	public boolean stillValid(@NotNull Player player)
     {
         if(worldObj == null || worldObj.getTileEntity(x, y, z) != this)
         {
             return false;
         }
-        return entityplayer.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         InventorySorter.sortInventory(chestContents);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java
index 2067c9ce9..28def0062 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityDispenser.java
@@ -35,27 +35,27 @@ public class TileEntityDispenser extends TileEntity
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
+	public @Nullable ItemStack getItem(int slot)
     {
-        return dispenserContents[index];
+        return dispenserContents[slot];
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
+	public @Nullable ItemStack removeItem(int slot, int takeAmount)
     {
-        if(dispenserContents[index] != null)
+        if(dispenserContents[slot] != null)
         {
-            if(dispenserContents[index].stackSize <= takeAmount)
+            if(dispenserContents[slot].stackSize <= takeAmount)
             {
-                ItemStack itemstack = dispenserContents[index];
-                dispenserContents[index] = null;
+                ItemStack itemstack = dispenserContents[slot];
+                dispenserContents[slot] = null;
                 setChanged();
                 return itemstack;
             }
-            ItemStack itemstack1 = dispenserContents[index].splitStack(takeAmount);
-            if(dispenserContents[index].stackSize <= 0)
+            ItemStack itemstack1 = dispenserContents[slot].splitStack(takeAmount);
+            if(dispenserContents[slot].stackSize <= 0)
             {
-                dispenserContents[index] = null;
+                dispenserContents[slot] = null;
             }
             setChanged();
             return itemstack1;
@@ -97,18 +97,18 @@ public class TileEntityDispenser extends TileEntity
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
+	public void setItem(int slot, @Nullable ItemStack stack)
     {
-        dispenserContents[index] = itemstack;
-        if(itemstack != null && itemstack.stackSize > getMaxStackSize())
+        dispenserContents[slot] = stack;
+        if(stack != null && stack.stackSize > getMaxStackSize())
         {
-            itemstack.stackSize = getMaxStackSize();
+            stack.stackSize = getMaxStackSize();
         }
         setChanged();
     }
 
     @Override
-	public String getNameTranslationKey()
+	public @NotNull String getNameTranslationKey()
     {
         return "container.dispenser.name";
     }
@@ -155,17 +155,17 @@ public class TileEntityDispenser extends TileEntity
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
+	public boolean stillValid(@NotNull Player player)
     {
         if(worldObj == null || worldObj.getTileEntity(x, y, z) != this)
         {
             return false;
         }
-        return entityplayer.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java
index 3863e4ff5..8d3c3a8d7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFlag.java
@@ -186,32 +186,32 @@ public class TileEntityFlag extends TileEntity
     }
 
     @Override
-    public @Nullable ItemStack getItem(int index) {
-        index -= 36;
-        if (index < 0 || index >= 3) return null;
+    public @Nullable ItemStack getItem(int slot) {
+        slot -= 36;
+        if (slot < 0 || slot >= 3) return null;
         
-        return items[index];
+        return items[slot];
     }
 
     @Override
-    public @Nullable ItemStack removeItem(int index, int takeAmount) {
-        index -= 36;
-        if (items[index] != null)
+    public @Nullable ItemStack removeItem(int slot, int takeAmount) {
+        slot -= 36;
+        if (items[slot] != null)
         {
-            if (items[index].stackSize <= takeAmount)
+            if (items[slot].stackSize <= takeAmount)
             {
-                ItemStack stack = items[index];
-                items[index] = null;
+                ItemStack stack = items[slot];
+                items[slot] = null;
                 itemsChanges();
                 setChanged();
                 return stack;
             }
             else
             {
-                ItemStack splitStack = items[index].splitStack(takeAmount);
-                if (items[index].stackSize <= 0)
+                ItemStack splitStack = items[slot].splitStack(takeAmount);
+                if (items[slot].stackSize <= 0)
                 {
-                    items[index] = null;
+                    items[slot] = null;
                 }
                 itemsChanges();
                 setChanged();
@@ -230,10 +230,10 @@ public class TileEntityFlag extends TileEntity
     }
 
     @Override
-    public void setItem(int index, @Nullable ItemStack stack)
+    public void setItem(int slot, @Nullable ItemStack stack)
     {
-        index -= 36; // This seems so wrong and will almost certainly cause an issue at some point
-        items[index] = stack;
+        slot -= 36; // This seems so wrong and will almost certainly cause an issue at some point
+        items[slot] = stack;
         itemsChanges();
         setChanged();
     }
@@ -250,7 +250,7 @@ public class TileEntityFlag extends TileEntity
     }
 
     @Override
-    public String getNameTranslationKey()
+    public @NotNull String getNameTranslationKey()
     {
         return "container.flag.name";
     }
@@ -262,17 +262,17 @@ public class TileEntityFlag extends TileEntity
     }
 
     @Override
-    public boolean stillValid(Player entityplayer)
+    public boolean stillValid(@NotNull Player player)
     {
         if(worldObj == null || worldObj.getTileEntity(x, y, z) != this)
         {
             return false;
         }
-        return entityplayer.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java
index 9750e5a6f..e3b96734f 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnace.java
@@ -48,30 +48,30 @@ public class TileEntityFurnace extends TileEntity
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
+	public @Nullable ItemStack getItem(int slot)
     {
-        return furnaceItemStacks[index];
+        return furnaceItemStacks[slot];
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
+	public @Nullable ItemStack removeItem(int slot, int takeAmount)
     {
-        if(furnaceItemStacks[index] != null)
+        if(furnaceItemStacks[slot] != null)
         {
-            if(furnaceItemStacks[index].stackSize <= takeAmount)
+            if(furnaceItemStacks[slot].stackSize <= takeAmount)
             {
-                ItemStack itemstack = furnaceItemStacks[index];
-                furnaceItemStacks[index] = null;
-                if (worldObj != null && index == 2) {
+                ItemStack itemstack = furnaceItemStacks[slot];
+                furnaceItemStacks[slot] = null;
+                if (worldObj != null && slot == 2) {
                     worldObj.markBlockNeedsUpdate(x, y, z);
                 }
                 return itemstack;
             }
-            ItemStack itemstack1 = furnaceItemStacks[index].splitStack(takeAmount);
-            if(furnaceItemStacks[index].stackSize <= 0)
+            ItemStack itemstack1 = furnaceItemStacks[slot].splitStack(takeAmount);
+            if(furnaceItemStacks[slot].stackSize <= 0)
             {
-                furnaceItemStacks[index] = null;
-                if (worldObj != null && index == 2) {
+                furnaceItemStacks[slot] = null;
+                if (worldObj != null && slot == 2) {
                     worldObj.markBlockNeedsUpdate(x, y, z);
                 }
             }
@@ -83,20 +83,20 @@ public class TileEntityFurnace extends TileEntity
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
+	public void setItem(int slot, @Nullable ItemStack stack)
     {
-        furnaceItemStacks[index] = itemstack;
-        if(itemstack != null && itemstack.stackSize > getMaxStackSize())
+        furnaceItemStacks[slot] = stack;
+        if(stack != null && stack.stackSize > getMaxStackSize())
         {
-            itemstack.stackSize = getMaxStackSize();
+            stack.stackSize = getMaxStackSize();
         }
-        if (worldObj != null && index == 2 && itemstack == null) {
+        if (worldObj != null && slot == 2 && stack == null) {
             worldObj.markBlockNeedsUpdate(x, y, z);
         }
     }
 
     @Override
-	public String getNameTranslationKey()
+	public @NotNull String getNameTranslationKey()
     {
         return "container.furnace.name";
     }
@@ -321,13 +321,13 @@ public class TileEntityFurnace extends TileEntity
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
+	public boolean stillValid(@NotNull Player player)
     {
         if(worldObj == null || worldObj.getTileEntity(x, y, z) != this)
         {
             return false;
         }
-        return entityplayer.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
     }
 
     @Override
@@ -379,7 +379,7 @@ public class TileEntityFurnace extends TileEntity
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java
index 1708d3187..92f9329b4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityFurnaceBlast.java
@@ -56,25 +56,25 @@ public class TileEntityFurnaceBlast extends TileEntity
     }
 
     @Override
-    public @Nullable ItemStack getItem(final int index) {
-        return this.inventory[index];
+    public @Nullable ItemStack getItem(final int slot) {
+        return this.inventory[slot];
     }
 
     @Override
-    public @Nullable ItemStack removeItem(final int index, final int takeAmount) {
-        if (this.inventory[index] != null) {
-            if (this.inventory[index].stackSize <= takeAmount) {
-                final ItemStack itemstack = this.inventory[index];
-                this.inventory[index] = null;
-                if (this.worldObj != null && index == SLOT_RESULT) {
+    public @Nullable ItemStack removeItem(final int slot, final int takeAmount) {
+        if (this.inventory[slot] != null) {
+            if (this.inventory[slot].stackSize <= takeAmount) {
+                final ItemStack itemstack = this.inventory[slot];
+                this.inventory[slot] = null;
+                if (this.worldObj != null && slot == SLOT_RESULT) {
                     this.worldObj.markBlockNeedsUpdate(this.x, this.y, this.z);
                 }
                 return itemstack;
             }
-            final ItemStack itemstack1 = this.inventory[index].splitStack(takeAmount);
-            if (this.inventory[index].stackSize <= 0) {
-                this.inventory[index] = null;
-                if (this.worldObj != null && index == SLOT_RESULT) {
+            final ItemStack itemstack1 = this.inventory[slot].splitStack(takeAmount);
+            if (this.inventory[slot].stackSize <= 0) {
+                this.inventory[slot] = null;
+                if (this.worldObj != null && slot == SLOT_RESULT) {
                     this.worldObj.markBlockNeedsUpdate(this.x, this.y, this.z);
                 }
             }
@@ -85,18 +85,18 @@ public class TileEntityFurnaceBlast extends TileEntity
     }
 
     @Override
-    public void setItem(final int index, @Nullable final ItemStack itemstack) {
-        this.inventory[index] = itemstack;
-        if (itemstack != null && itemstack.stackSize > getMaxStackSize()) {
-            itemstack.stackSize = getMaxStackSize();
+    public void setItem(final int slot, @Nullable final ItemStack stack) {
+        this.inventory[slot] = stack;
+        if (stack != null && stack.stackSize > getMaxStackSize()) {
+            stack.stackSize = getMaxStackSize();
         }
-        if (this.worldObj != null && index == SLOT_RESULT && itemstack == null) {
+        if (this.worldObj != null && slot == SLOT_RESULT && stack == null) {
             this.worldObj.markBlockNeedsUpdate(this.x, this.y, this.z);
         }
     }
 
     @Override
-    public String getNameTranslationKey() {
+    public @NotNull String getNameTranslationKey() {
         return "container.furnace_blast.name";
     }
 
@@ -286,11 +286,11 @@ public class TileEntityFurnaceBlast extends TileEntity
     }
 
     @Override
-    public boolean stillValid(final Player entityplayer) {
+    public boolean stillValid(final @NotNull Player player) {
         if (this.worldObj == null || this.worldObj.getTileEntity(this.x, this.y, this.z) != this) {
             return false;
         }
-        return entityplayer.distanceToSqr((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D) <= 64D;
     }
 
     @Override
@@ -334,7 +334,7 @@ slotLoop:   for (int slot = 0; slot < this.getContainerSize(); slot++) {
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
index c31b65acb..d5564e64c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
@@ -28,7 +28,7 @@ public class TileEntityMeshGold extends TileEntity {
     public boolean setFilterItem(Player player, @Nullable ItemStack stack){
         boolean success = false;
         boolean wasNull = filterItem == null;
-        if (filterItem != null && player.getGamemode().consumeBlocks()){
+        if (filterItem != null && player.getGamemode().hasBlockConsumption()){
             player.inventory.insertItem(filterItem, true);
             if (filterItem.stackSize > 0) {
                 player.dropPlayerItem(filterItem);
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
index 4b57e83e5..a79f03de4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
@@ -61,26 +61,26 @@ public class TileEntityTrommel extends TileEntity
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
+	public @Nullable ItemStack getItem(int slot)
     {
-        return itemStacks[index];
+        return itemStacks[slot];
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
+	public @Nullable ItemStack removeItem(int slot, int takeAmount)
     {
-        if(itemStacks[index] != null)
+        if(itemStacks[slot] != null)
         {
-            if(itemStacks[index].stackSize <= takeAmount)
+            if(itemStacks[slot].stackSize <= takeAmount)
             {
-                ItemStack itemstack = itemStacks[index];
-                itemStacks[index] = null;
+                ItemStack itemstack = itemStacks[slot];
+                itemStacks[slot] = null;
                 return itemstack;
             }
-            ItemStack itemstack1 = itemStacks[index].splitStack(takeAmount);
-            if(itemStacks[index].stackSize <= 0)
+            ItemStack itemstack1 = itemStacks[slot].splitStack(takeAmount);
+            if(itemStacks[slot].stackSize <= 0)
             {
-                itemStacks[index] = null;
+                itemStacks[slot] = null;
             }
             return itemstack1;
         } else
@@ -90,17 +90,17 @@ public class TileEntityTrommel extends TileEntity
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
+	public void setItem(int slot, @Nullable ItemStack stack)
     {
-        itemStacks[index] = itemstack;
-        if(itemstack != null && itemstack.stackSize > getMaxStackSize())
+        itemStacks[slot] = stack;
+        if(stack != null && stack.stackSize > getMaxStackSize())
         {
-            itemstack.stackSize = getMaxStackSize();
+            stack.stackSize = getMaxStackSize();
         }
     }
 
     @Override
-	public String getNameTranslationKey()
+	public @NotNull String getNameTranslationKey()
     {
         return "container.trommel.name";
     }
@@ -387,17 +387,17 @@ public class TileEntityTrommel extends TileEntity
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
+	public boolean stillValid(@NotNull Player player)
     {
         if(worldObj == null || worldObj.getTileEntity(x, y, z) != this)
         {
             return false;
         }
-        return entityplayer.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
+        return player.distanceToSqr((double) x + 0.5D, (double) y + 0.5D, (double) z + 0.5D) <= 64D;
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/data/gamerule/TreecapitatorHelper.java b/game/core/src/main/java/net/minecraft/core/data/gamerule/TreecapitatorHelper.java
index c2442ba8e..45dcb024f 100644
--- a/game/core/src/main/java/net/minecraft/core/data/gamerule/TreecapitatorHelper.java
+++ b/game/core/src/main/java/net/minecraft/core/data/gamerule/TreecapitatorHelper.java
@@ -135,7 +135,7 @@ public class TreecapitatorHelper {
 			ChunkPosition pos = allBlocksList.get(i);
 			Block<?> block = world.getBlock(pos.x, pos.y, pos.z);
 			if(block != null && block.getLogic() instanceof BlockLogicLeavesBase) {
-				if(player.getGamemode().dropBlockOnBreak()) {
+				if(player.getGamemode().hasItemDrops()) {
 					ItemStack[] drops = block.getBreakResult(world, EnumDropCause.PROPER_TOOL, pos.x, pos.y, pos.z, world.getBlockMetadata(pos.x, pos.y, pos.z), null);
 					if(itemList != null) {
 						itemList.addAll(drops);
@@ -198,7 +198,7 @@ public class TreecapitatorHelper {
 		if(world.setBlockWithNotify(pos.x, pos.y, pos.z, 0)) {
 			int meta = world.getBlockMetadata(pos.x, pos.y, pos.z);
 			ItemStack[] drops = block.getBreakResult(world, EnumDropCause.PROPER_TOOL, pos.x, pos.y, pos.z, meta, null);
-			if(player.getGamemode().dropBlockOnBreak()) {
+			if(player.getGamemode().hasItemDrops()) {
 				if(itemList != null) {
 					itemList.addAll(drops);
 				}else {
diff --git a/game/core/src/main/java/net/minecraft/core/data/registry/Registries.java b/game/core/src/main/java/net/minecraft/core/data/registry/Registries.java
index fc928805f..ced3b0458 100644
--- a/game/core/src/main/java/net/minecraft/core/data/registry/Registries.java
+++ b/game/core/src/main/java/net/minecraft/core/data/registry/Registries.java
@@ -10,23 +10,26 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.data.gamerule.GameRule;
 import net.minecraft.core.data.gamerule.GameRules;
 import net.minecraft.core.item.Items;
+import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.type.WorldType;
 import net.minecraft.core.world.type.WorldTypes;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
-public class Registries extends Registry<Registry<?>>
-{
-    public static final Registry<WorldType> WORLD_TYPES = new Registry<>();
-    public static final Registry<Biome> BIOMES = new Registry<>();
-    public static final Registry<GameRule<?>> GAME_RULES = new Registry<>();
-    public static final Registry<Class<? extends RecipeEntryBase<?,?,?>>> RECIPE_TYPES = new Registry<>();
-    public static final Registry<List<ItemStack>> ITEM_GROUPS = new Registry<>();
+public class Registries extends Registry<Registry<?>> {
+    public static final @NotNull Registry<@NotNull WorldType> WORLD_TYPES = new Registry<>();
+    public static final @NotNull Registry<@NotNull Biome> BIOMES = new Registry<>();
+    public static final @NotNull Registry<@NotNull GameRule<?>> GAME_RULES = new Registry<>();
+    public static final @NotNull Registry<@NotNull Gamemode> GAMEMODES = new Registry<>();
+    public static final @NotNull Registry<@NotNull Class<? extends RecipeEntryBase<?, ?, ?>>> RECIPE_TYPES = new Registry<>();
+    public static final @NotNull Registry<@NotNull List<@NotNull ItemStack>> ITEM_GROUPS = new Registry<>();
     public static RecipeRegistry RECIPES;
     public static RecipeRegistry RECIPES_LOCAL_COPY;
 
@@ -35,22 +38,26 @@ public class Registries extends Registry<Registry<?>>
 
     public static boolean init = false;
 
-    public Registries(){
-        if(init) return;
+    public Registries() {
+        if (init) return;
         init = true;
         INSTANCE = this;
-        register("minecraft:world_types",WORLD_TYPES);
-        register("minecraft:biomes",BIOMES);
-        register("minecraft:recipe_types",RECIPE_TYPES);
-        register("minecraft:item_groups",ITEM_GROUPS);
-        init();
-        register("minecraft:recipes",RECIPES);
+
+        this.init();
+        this.register("minecraft:world_types", WORLD_TYPES);
+        this.register("minecraft:biomes", BIOMES);
+        this.register("minecraft:gamerules", GAME_RULES);
+        this.register("minecraft:gamemodes", GAMEMODES);
+        this.register("minecraft:recipe_types", RECIPE_TYPES);
+        this.register("minecraft:item_groups", ITEM_GROUPS);
+        this.register("minecraft:recipes", RECIPES);
     }
 
-    private void init(){
+    private void init() {
         WorldTypes.init();
         Biomes.init();
         GameRules.init();
+        Gamemodes.init();
 
         RECIPE_TYPES.register("minecraft:crafting/shaped", RecipeEntryCraftingShaped.class);
         RECIPE_TYPES.register("minecraft:crafting/shapeless", RecipeEntryCraftingShapeless.class);
@@ -67,38 +74,38 @@ public class Registries extends Registry<Registry<?>>
         RECIPE_TYPES.register("minecraft:smelting/blast", RecipeEntryBlastFurnace.class);
         RECIPE_TYPES.register("minecraft:trommeling", RecipeEntryTrommel.class);
 
-        ITEM_GROUPS.register("minecraft:stones",stackListOf(Blocks.STONE, Blocks.BASALT, Blocks.LIMESTONE, Blocks.GRANITE, Blocks.PERMAFROST, Blocks.NETHERRACK));
-        ITEM_GROUPS.register("minecraft:cobblestones",stackListOf(Blocks.COBBLE_STONE, Blocks.COBBLE_BASALT, Blocks.COBBLE_LIMESTONE, Blocks.COBBLE_GRANITE, Blocks.COBBLE_PERMAFROST, Blocks.COBBLE_NETHERRACK));
-        ITEM_GROUPS.register("minecraft:grasses",stackListOf(Blocks.GRASS, Blocks.GRASS_RETRO));
-        ITEM_GROUPS.register("minecraft:dirt",stackListOf(Blocks.DIRT, Blocks.DIRT_SCORCHED));
-        ITEM_GROUPS.register("minecraft:trommel_dirt",stackListOf(Blocks.DIRT, Blocks.DIRT_SCORCHED, Blocks.GRASS, Blocks.GRASS_RETRO, Blocks.GRASS_SCORCHED, Blocks.PATH_DIRT, Blocks.FARMLAND_DIRT));
-        ITEM_GROUPS.register("minecraft:moss_stones",stackListOf(Blocks.MOSS_STONE, Blocks.MOSS_BASALT, Blocks.MOSS_LIMESTONE, Blocks.MOSS_GRANITE));
-        ITEM_GROUPS.register("minecraft:logs",stackListOf(Blocks.LOG_OAK, Blocks.LOG_PINE, Blocks.LOG_BIRCH, Blocks.LOG_CHERRY, Blocks.LOG_EUCALYPTUS, Blocks.LOG_OAK_MOSSY, Blocks.LOG_THORN, Blocks.LOG_PALM));
-        ITEM_GROUPS.register("minecraft:leaves",stackListOf(Blocks.LEAVES_OAK, Blocks.LEAVES_OAK_RETRO, Blocks.LEAVES_PINE, Blocks.LEAVES_BIRCH, Blocks.LEAVES_CHERRY, Blocks.LEAVES_EUCALYPTUS, Blocks.LEAVES_SHRUB));
-        ITEM_GROUPS.register("minecraft:coal_ores",stackListOf(Blocks.ORE_COAL_STONE, Blocks.ORE_COAL_BASALT, Blocks.ORE_COAL_LIMESTONE, Blocks.ORE_COAL_GRANITE, Blocks.ORE_COAL_PERMAFROST));
-        ITEM_GROUPS.register("minecraft:iron_ores",stackListOf(Blocks.ORE_IRON_STONE, Blocks.ORE_IRON_BASALT, Blocks.ORE_IRON_LIMESTONE, Blocks.ORE_IRON_GRANITE, Blocks.ORE_IRON_PERMAFROST));
-        ITEM_GROUPS.register("minecraft:gold_ores",stackListOf(Blocks.ORE_GOLD_STONE, Blocks.ORE_GOLD_BASALT, Blocks.ORE_GOLD_LIMESTONE, Blocks.ORE_GOLD_GRANITE, Blocks.ORE_GOLD_PERMAFROST));
-        ITEM_GROUPS.register("minecraft:lapis_ores",stackListOf(Blocks.ORE_LAPIS_STONE, Blocks.ORE_LAPIS_BASALT, Blocks.ORE_LAPIS_LIMESTONE, Blocks.ORE_LAPIS_GRANITE, Blocks.ORE_LAPIS_PERMAFROST));
-        ITEM_GROUPS.register("minecraft:redstone_ores",stackListOf(Blocks.ORE_REDSTONE_STONE, Blocks.ORE_REDSTONE_BASALT, Blocks.ORE_REDSTONE_LIMESTONE, Blocks.ORE_REDSTONE_GRANITE, Blocks.ORE_REDSTONE_PERMAFROST, Blocks.ORE_REDSTONE_GLOWING_STONE, Blocks.ORE_REDSTONE_GLOWING_BASALT, Blocks.ORE_REDSTONE_GLOWING_LIMESTONE, Blocks.ORE_REDSTONE_GLOWING_GRANITE, Blocks.ORE_REDSTONE_GLOWING_PERMAFROST));
-        ITEM_GROUPS.register("minecraft:diamond_ores",stackListOf(Blocks.ORE_DIAMOND_STONE, Blocks.ORE_DIAMOND_BASALT, Blocks.ORE_DIAMOND_LIMESTONE, Blocks.ORE_DIAMOND_GRANITE, Blocks.ORE_DIAMOND_PERMAFROST));
+        ITEM_GROUPS.register("minecraft:stones", stackListOf(Blocks.STONE, Blocks.BASALT, Blocks.LIMESTONE, Blocks.GRANITE, Blocks.PERMAFROST, Blocks.NETHERRACK));
+        ITEM_GROUPS.register("minecraft:cobblestones", stackListOf(Blocks.COBBLE_STONE, Blocks.COBBLE_BASALT, Blocks.COBBLE_LIMESTONE, Blocks.COBBLE_GRANITE, Blocks.COBBLE_PERMAFROST, Blocks.COBBLE_NETHERRACK));
+        ITEM_GROUPS.register("minecraft:grasses", stackListOf(Blocks.GRASS, Blocks.GRASS_RETRO));
+        ITEM_GROUPS.register("minecraft:dirt", stackListOf(Blocks.DIRT, Blocks.DIRT_SCORCHED));
+        ITEM_GROUPS.register("minecraft:trommel_dirt", stackListOf(Blocks.DIRT, Blocks.DIRT_SCORCHED, Blocks.GRASS, Blocks.GRASS_RETRO, Blocks.GRASS_SCORCHED, Blocks.PATH_DIRT, Blocks.FARMLAND_DIRT));
+        ITEM_GROUPS.register("minecraft:moss_stones", stackListOf(Blocks.MOSS_STONE, Blocks.MOSS_BASALT, Blocks.MOSS_LIMESTONE, Blocks.MOSS_GRANITE));
+        ITEM_GROUPS.register("minecraft:logs", stackListOf(Blocks.LOG_OAK, Blocks.LOG_PINE, Blocks.LOG_BIRCH, Blocks.LOG_CHERRY, Blocks.LOG_EUCALYPTUS, Blocks.LOG_OAK_MOSSY, Blocks.LOG_THORN, Blocks.LOG_PALM));
+        ITEM_GROUPS.register("minecraft:leaves", stackListOf(Blocks.LEAVES_OAK, Blocks.LEAVES_OAK_RETRO, Blocks.LEAVES_PINE, Blocks.LEAVES_BIRCH, Blocks.LEAVES_CHERRY, Blocks.LEAVES_EUCALYPTUS, Blocks.LEAVES_SHRUB));
+        ITEM_GROUPS.register("minecraft:coal_ores", stackListOf(Blocks.ORE_COAL_STONE, Blocks.ORE_COAL_BASALT, Blocks.ORE_COAL_LIMESTONE, Blocks.ORE_COAL_GRANITE, Blocks.ORE_COAL_PERMAFROST));
+        ITEM_GROUPS.register("minecraft:iron_ores", stackListOf(Blocks.ORE_IRON_STONE, Blocks.ORE_IRON_BASALT, Blocks.ORE_IRON_LIMESTONE, Blocks.ORE_IRON_GRANITE, Blocks.ORE_IRON_PERMAFROST));
+        ITEM_GROUPS.register("minecraft:gold_ores", stackListOf(Blocks.ORE_GOLD_STONE, Blocks.ORE_GOLD_BASALT, Blocks.ORE_GOLD_LIMESTONE, Blocks.ORE_GOLD_GRANITE, Blocks.ORE_GOLD_PERMAFROST));
+        ITEM_GROUPS.register("minecraft:lapis_ores", stackListOf(Blocks.ORE_LAPIS_STONE, Blocks.ORE_LAPIS_BASALT, Blocks.ORE_LAPIS_LIMESTONE, Blocks.ORE_LAPIS_GRANITE, Blocks.ORE_LAPIS_PERMAFROST));
+        ITEM_GROUPS.register("minecraft:redstone_ores", stackListOf(Blocks.ORE_REDSTONE_STONE, Blocks.ORE_REDSTONE_BASALT, Blocks.ORE_REDSTONE_LIMESTONE, Blocks.ORE_REDSTONE_GRANITE, Blocks.ORE_REDSTONE_PERMAFROST, Blocks.ORE_REDSTONE_GLOWING_STONE, Blocks.ORE_REDSTONE_GLOWING_BASALT, Blocks.ORE_REDSTONE_GLOWING_LIMESTONE, Blocks.ORE_REDSTONE_GLOWING_GRANITE, Blocks.ORE_REDSTONE_GLOWING_PERMAFROST));
+        ITEM_GROUPS.register("minecraft:diamond_ores", stackListOf(Blocks.ORE_DIAMOND_STONE, Blocks.ORE_DIAMOND_BASALT, Blocks.ORE_DIAMOND_LIMESTONE, Blocks.ORE_DIAMOND_GRANITE, Blocks.ORE_DIAMOND_PERMAFROST));
         ITEM_GROUPS.register("minecraft:nethercoal_ores", stackListOf(Blocks.ORE_NETHERCOAL_NETHERRACK));
         {
-            List<ItemStack> plankStackList = new ArrayList<>();
-            List<ItemStack> signStackList = new ArrayList<>();
-            List<ItemStack> doorStackList = new ArrayList<>();
-            List<ItemStack> chestStackList = new ArrayList<>();
-            List<ItemStack> stairsStackList = new ArrayList<>();
-            List<ItemStack> slabsStackList = new ArrayList<>();
-            List<ItemStack> fencesStackList = new ArrayList<>();
-            List<ItemStack> fenceGatesStackList = new ArrayList<>();
-            List<ItemStack> trapdoorStackList = new ArrayList<>();
-            List<ItemStack> woolStackList = new ArrayList<>();
-            List<ItemStack> lampStackList = new ArrayList<>();
-            List<ItemStack> invertedLampStackList = new ArrayList<>();
-            List<ItemStack> woodenButtonsList = new ArrayList<>();
-            List<ItemStack> woodenPressurePlatesList = new ArrayList<>();
-            List<ItemStack> buttonsList = new ArrayList<>();
-            List<ItemStack> pressurePlatesList = new ArrayList<>();
+            final List<ItemStack> plankStackList = new ArrayList<>();
+            final List<ItemStack> signStackList = new ArrayList<>();
+            final List<ItemStack> doorStackList = new ArrayList<>();
+            final List<ItemStack> chestStackList = new ArrayList<>();
+            final List<ItemStack> stairsStackList = new ArrayList<>();
+            final List<ItemStack> slabsStackList = new ArrayList<>();
+            final List<ItemStack> fencesStackList = new ArrayList<>();
+            final List<ItemStack> fenceGatesStackList = new ArrayList<>();
+            final List<ItemStack> trapdoorStackList = new ArrayList<>();
+            final List<ItemStack> woolStackList = new ArrayList<>();
+            final List<ItemStack> lampStackList = new ArrayList<>();
+            final List<ItemStack> invertedLampStackList = new ArrayList<>();
+            final List<ItemStack> woodenButtonsList = new ArrayList<>();
+            final List<ItemStack> woodenPressurePlatesList = new ArrayList<>();
+            final List<ItemStack> buttonsList = new ArrayList<>();
+            final List<ItemStack> pressurePlatesList = new ArrayList<>();
 
             plankStackList.add(Blocks.PLANKS_OAK.getDefaultStack());
             signStackList.add(Items.SIGN.getDefaultStack());
@@ -115,7 +122,7 @@ public class Registries extends Registry<Registry<?>>
             pressurePlatesList.add(Blocks.PRESSURE_PLATE_STONE.getDefaultStack());
             pressurePlatesList.add(Blocks.PRESSURE_PLATE_COBBLE_STONE.getDefaultStack());
 
-            for (DyeColor color : DyeColor.values()) {
+            for (final DyeColor color : DyeColor.values()) {
                 plankStackList.add(new ItemStack(Blocks.PLANKS_OAK_PAINTED, 1, color.blockMeta));
                 signStackList.add(new ItemStack(Items.SIGN_PAINTED, 1, color.itemMeta));
                 doorStackList.add(new ItemStack(Items.DOOR_OAK_PAINTED, 1, color.itemMeta));
@@ -135,9 +142,9 @@ public class Registries extends Registry<Registry<?>>
             buttonsList.addAll(woodenButtonsList);
             pressurePlatesList.addAll(woodenPressurePlatesList);
 
-            ITEM_GROUPS.register("minecraft:planks",plankStackList);
-            ITEM_GROUPS.register("minecraft:signs",signStackList);
-            ITEM_GROUPS.register("minecraft:doors",doorStackList);
+            ITEM_GROUPS.register("minecraft:planks", plankStackList);
+            ITEM_GROUPS.register("minecraft:signs", signStackList);
+            ITEM_GROUPS.register("minecraft:doors", doorStackList);
             ITEM_GROUPS.register("minecraft:chests", chestStackList);
             ITEM_GROUPS.register("minecraft:wools", woolStackList);
             ITEM_GROUPS.register("minecraft:lamps", lampStackList);
@@ -162,12 +169,12 @@ public class Registries extends Registry<Registry<?>>
                 new ItemStack(Items.TOOL_SWORD_DIAMOND, 1, -1),
                 new ItemStack(Items.TOOL_SWORD_STEEL, 1, -1)));
 
-        if(RECIPES == null) new RecipeRegistry();
+        if (RECIPES == null) new RecipeRegistry();
     }
 
-    public static List<ItemStack> stackListOf(Object... items) {
-        ArrayList<ItemStack> list = new ArrayList<>();
-        for (Object item : items) {
+    public static List<ItemStack> stackListOf(final Object... items) {
+        final ArrayList<ItemStack> list = new ArrayList<>();
+        for (final Object item : items) {
             if (item instanceof Block) {
                 list.add(new ItemStack((Block<?>) item));
             } else if (item instanceof Item) {
@@ -181,7 +188,7 @@ public class Registries extends Registry<Registry<?>>
         return list;
     }
 
-    public static Registries getInstance(){
+    public static Registries getInstance() {
         return INSTANCE;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java b/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
index 0cea76c87..f4552b196 100644
--- a/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
+++ b/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
@@ -5,6 +5,7 @@ import com.mojang.nbt.tags.IntTag;
 import com.mojang.nbt.tags.Tag;
 import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
 
@@ -78,7 +79,7 @@ public class Registry<T>
      * @param key The key of the item.
      * @return The item associated with the given key, or null if no such key-item association is present.
      */
-    public T getItem(String key)
+    public @Nullable T getItem(String key)
     {
         Objects.requireNonNull(key);
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java b/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java
index 593f35531..1e70d2221 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java
@@ -187,7 +187,7 @@ public class EntityPainting extends Entity {
     public boolean hurt(Entity entity, int i, DamageType type) {
         if (!this.removed && !this.world.isClientSide) {
             markHurt();
-            if (!(entity instanceof Player) || ((Player) entity).getGamemode().dropBlockOnBreak()) {
+            if (!(entity instanceof Player) || ((Player) entity).getGamemode().hasItemDrops()) {
                 drop();
                 remove();
             }
@@ -289,9 +289,9 @@ public class EntityPainting extends Entity {
             setStack(new ItemStack(stack.getItem(), 1, stack.getMetadata()));
             stack.consumeItem(player);
             if (stack.stackSize <= 0) {
-                player.inventory.setItem(player.inventory.getCurrentItemIndex(), null);
+                player.inventory.setItem(player.inventory.getCurrentSlot(), null);
             }
-            if (paintingStack != null && player.getGamemode().consumeBlocks()) {
+            if (paintingStack != null && player.getGamemode().hasBlockConsumption()) {
                 player.inventory.insertItem(paintingStack, true);
                 if (paintingStack.stackSize > 0) {
                     player.dropPlayerItem(paintingStack);
@@ -299,7 +299,7 @@ public class EntityPainting extends Entity {
             }
             return true;
         } else if (getBorderStack() != null) {
-            if (player.getGamemode().consumeBlocks()) {
+            if (player.getGamemode().hasBlockConsumption()) {
                 player.inventory.insertItem(getBorderStack(), true);
             }
             setStack(null);
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobDeer.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobDeer.java
index 8ba37c9ed..aa14a680d 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobDeer.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobDeer.java
@@ -80,7 +80,7 @@ public class MobDeer
     protected @Nullable Entity findThreatNearby() {
         final int dist = 10;
         final Player player = this.world.getClosestPlayer(this.x, this.y, this.z, dist);
-        if (player != null && player.getGamemode().areMobsHostile()) {
+        if (player != null && player.getGamemode().hasHostileMobs()) {
             return player;
         }
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobSheep.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobSheep.java
index f4bb60d89..7b5a3a093 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobSheep.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobSheep.java
@@ -11,7 +11,6 @@ import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.EnumBlockSoundEffectType;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.tool.ItemToolShears;
-import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.LevelListener;
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java
index deabb3348..26d2b11f4 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobWolf.java
@@ -636,10 +636,10 @@ public class MobWolf
             if (itemstack != null && itemstack.itemID == Items.BONE.id && !isWolfAngry()) {
                 itemstack.consumeItem(player);
                 if (itemstack.stackSize <= 0) {
-                    player.inventory.setItem(player.inventory.getCurrentItemIndex(), null);
+                    player.inventory.setItem(player.inventory.getCurrentSlot(), null);
                 }
                 if (!this.world.isClientSide) {
-                    if (this.random.nextInt(3) == 0 || !player.getGamemode().consumeBlocks()) {
+                    if (this.random.nextInt(3) == 0 || !player.getGamemode().hasBlockConsumption()) {
                         setWolfTamed(true);
                         setPathToEntity(null);
                         setWolfSitting(true);
@@ -657,10 +657,10 @@ public class MobWolf
         } else {
             if (itemstack != null && (Item.itemsList[itemstack.itemID] instanceof ItemFood itemfood)) {
                 if (itemfood.getIsWolfsFavoriteMeat() && getHealth() < getMaxHealth()) {
-                    if (player.getGamemode().consumeBlocks()) {
+                    if (player.getGamemode().hasBlockConsumption()) {
                         itemstack.stackSize--;
                         if (itemstack.stackSize <= 0) {
-                            player.inventory.setItem(player.inventory.getCurrentItemIndex(), null);
+                            player.inventory.setItem(player.inventory.getCurrentSlot(), null);
                         }
                     }
                     heal(itemfood.getHealAmount());
@@ -674,10 +674,10 @@ public class MobWolf
                         setArmor(null);
                     }
                     setArmor(new ItemStack(itemstack.getItem(), 1, itemstack.getMetadata(), itemstack.getData()));
-                    if (player.getGamemode().consumeBlocks()) {
+                    if (player.getGamemode().hasBlockConsumption()) {
                         itemstack.stackSize--;
                         if (itemstack.stackSize <= 0) {
-                            player.inventory.setItem(player.inventory.getCurrentItemIndex(), null);
+                            player.inventory.setItem(player.inventory.getCurrentSlot(), null);
                         }
                     }
                     return true;
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 b39971d03..58dd6c077 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
@@ -122,7 +122,7 @@ public class MobGhast extends MobFlying
         }
         if (this.targetedEntity == null || this.aggroCooldown-- <= 0) {
             this.targetedEntity = this.world.getClosestPlayerToEntity(this, 100D);
-            if (this.targetedEntity != null && !((Player) this.targetedEntity).getGamemode().areMobsHostile()) {
+            if (this.targetedEntity != null && !((Player) this.targetedEntity).getGamemode().hasHostileMobs()) {
                 this.targetedEntity = null;
             }
             if (this.targetedEntity != null) {
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 a7f292162..36c2398a5 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
@@ -69,7 +69,7 @@ public abstract class MobMonster extends MobPathfinder
     @Override
     protected Entity findPlayerToAttack() {
         Player entityplayer = this.world.getClosestPlayerToEntity(this, 16D);
-        if (entityplayer != null && canEntityBeSeen(entityplayer) && entityplayer.getGamemode().areMobsHostile()) {
+        if (entityplayer != null && canEntityBeSeen(entityplayer) && entityplayer.getGamemode().hasHostileMobs()) {
             return entityplayer;
         } else {
             return null;
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobScorpion.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobScorpion.java
index 3b7043182..aa7b4ec50 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobScorpion.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobScorpion.java
@@ -65,7 +65,7 @@ public class MobScorpion extends MobMonster
             Player p = world.getClosestPlayerToEntity(this, d);
             if (p != null)
             {
-            	if (!p.gamemode.areMobsHostile()) return null;
+            	if (!p.gamemode.hasHostileMobs()) return null;
             }
             return p;
         } else
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobSlime.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobSlime.java
index 85f03b35a..e4e330716 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobSlime.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobSlime.java
@@ -4,7 +4,6 @@ import net.minecraft.core.WeightedRandomLootObject;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.Items;
-import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.util.helper.MathHelper;
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.world.World;
@@ -132,7 +131,7 @@ public class MobSlime extends Mob
     {
         tryToDespawn();
         Player entityplayer = world.getClosestPlayerToEntity(this, 16D);
-        boolean targetPlayer = entityplayer != null && entityplayer.getGamemode().areMobsHostile();
+        boolean targetPlayer = entityplayer != null && entityplayer.getGamemode().hasHostileMobs();
         if(entityplayer != null && targetPlayer)
         {
             lookAt(entityplayer, 10F, 20F);
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobSpider.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobSpider.java
index 49dcbbb6e..151ba872a 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobSpider.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobSpider.java
@@ -64,7 +64,7 @@ public class MobSpider extends MobMonster
             Player p = world.getClosestPlayerToEntity(this, d);
             if (p != null)
             {
-            	if (!p.gamemode.areMobsHostile()) return null;
+            	if (!p.gamemode.hasHostileMobs()) return null;
             }
             return p;
         } else
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 5165626fb..f161b7d88 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
@@ -1,10 +1,10 @@
 package net.minecraft.core.entity.player;
 
-import com.mojang.nbt.tags.CompoundTag;
-import com.mojang.nbt.tags.ListTag;
+import com.mojang.nbt.tags.*;
 import net.minecraft.core.block.BlockLogicBed;
 import net.minecraft.core.block.entity.*;
 import net.minecraft.core.block.material.Materials;
+import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.*;
 import net.minecraft.core.entity.animal.MobPig;
 import net.minecraft.core.entity.animal.MobWolf;
@@ -41,6 +41,7 @@ import net.minecraft.core.item.tool.ItemToolSword;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.player.inventory.container.Container;
 import net.minecraft.core.player.inventory.container.ContainerInventory;
 import net.minecraft.core.player.inventory.menu.MenuAbstract;
@@ -85,7 +86,7 @@ public abstract class Player
     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 = Gamemode.survival;
+    public Gamemode gamemode = Gamemodes.SURVIVAL;
     //    public byte userType;
     public int score;
     public List<String> messageHistory = new ArrayList<>();
@@ -140,7 +141,7 @@ public abstract class Player
         this.timeUntilPortal = 20;
         this.inPortal = false;
         this.bobberEntity = null;
-        this.inventorySlots = new MenuInventory(this.inventory, !world.isClientSide);
+        this.inventorySlots = new MenuInventory(this.inventory);
         this.craftingInventory = this.inventorySlots;
         TilePos spawnPoint = world.getSpawnPoint();
         moveTo((double) spawnPoint.x + 0.5D, spawnPoint.y + 1, (double) spawnPoint.z + 0.5D, 0.0F, 0.0F);
@@ -453,8 +454,8 @@ public abstract class Player
 
     @Override
     public void onDeath(Entity entityKilledBy) {
-        if (getGamemode().isPermaDeath()) {
-            setGamemode(Gamemode.spectator);
+        if (getGamemode().hasPermaDeath()) {
+            setGamemode(Gamemodes.SPECTATOR);
         }
         super.onDeath(entityKilledBy);
         setSize(0.2F, 0.2F);
@@ -462,16 +463,16 @@ public abstract class Player
         this.lastDeathPoint = new TilePos(this);
         this.yd = 0.1d;
         if (UUID_MAK.equals(this.uuid) || this.username.equals("MaggAndGeez")) {
-            dropPlayerItemWithRandomChoice(new ItemStack(Items.AMMO_FIREBALL, 1), true);
+            dropItem(new ItemStack(Items.AMMO_FIREBALL, 1), true);
         } else if (UUID_JONK.equals(this.uuid) || this.username.equals("jonkadelic")) {
-            dropPlayerItemWithRandomChoice(new ItemStack(Items.FOOD_COOKIE, 1), true);
+            dropItem(new ItemStack(Items.FOOD_COOKIE, 1), true);
         } else if (UUID_SHIGN.equals(this.uuid) || this.username.equals("ShignBright")) {
-            dropPlayerItemWithRandomChoice(new ItemStack(Items.SIGN_PAINTED, 1, DyeColor.PINK.itemMeta), true);
+            dropItem(new ItemStack(Items.SIGN_PAINTED, 1, DyeColor.PINK.itemMeta), true);
         } else if ((UUID_MELON.equals(this.uuid) || this.username.equals("MelonMojito")) || (UUID_WATERMELON.equals(this.uuid) || this.username.equals("WatermelonMojito"))) {
             ItemStack melon = new ItemStack(Blocks.PUMPKIN, 1, this.random.nextInt(Short.MAX_VALUE / 2) + 1);
             melon.setCustomName("Melon");
             melon.setCustomColor((byte) TextFormatting.LIME.id);
-            dropPlayerItemWithRandomChoice(melon, true);
+            dropItem(melon, true);
         }
 
         if (!this.world.getGameRuleValue(GameRules.KEEP_INVENTORY)) {
@@ -614,11 +615,11 @@ public abstract class Player
     }
 
     public void dropCurrentItem(boolean dropFullStack) {
-        dropPlayerItemWithRandomChoice(this.inventory.removeItem(this.inventory.getCurrentItemIndex(), dropFullStack ? 64 : 1), false);
+        dropItem(this.inventory.removeItem(this.inventory.getCurrentSlot(), dropFullStack ? 64 : 1), false);
     }
 
     public void dropPlayerItem(ItemStack itemstack) {
-        dropPlayerItemWithRandomChoice(itemstack, false);
+        dropItem(itemstack, false);
     }
 
     public void setHotbarOffset(int offset) {
@@ -665,34 +666,38 @@ public abstract class Player
         super.push(entity);
     }
 
-    public void dropPlayerItemWithRandomChoice(ItemStack itemstack, boolean flag) {
-        if (!getGamemode().canInteract()) return;
-        if (itemstack == null) {
+    public void dropItem(final @Nullable ItemStack stack, final boolean randomDirection) {
+        if (!this.getGamemode().canInteract()) return;
+        if (stack == null) {
             return;
         }
-        EntityItem entityitem = new EntityItem(this.world, this.x, (this.y - 0.30000001192092896D) + (double) this.getHeadHeight(), this.z, itemstack);
-        entityitem.pickupDelay = 40;
-        float f = 0.1F;
-        if (flag) {
-            float f2 = this.random.nextFloat() * 0.5F;
-            float f4 = this.random.nextFloat() * MathHelper.PI * 2.0F;
-            entityitem.xd = -MathHelper.sin(f4) * f2;
-            entityitem.zd = MathHelper.cos(f4) * f2;
-            entityitem.yd = 0.2D;
+
+        final @NotNull EntityItem itemEntity = new EntityItem(this.world, this.x, (this.y - 0.3) + (double) this.getHeadHeight(), this.z, stack);
+        itemEntity.pickupDelay = 40;
+
+        if (randomDirection) {
+            final float speed = this.random.nextFloat() * 0.5F;
+            final float angle = this.random.nextFloat() * MathHelper.PI * 2.0F;
+
+            itemEntity.xd = -MathHelper.sin(angle) * speed;
+            itemEntity.zd = MathHelper.cos(angle) * speed;
+            itemEntity.yd = 0.2D;
         } else {
-            float f1 = 0.3F;
-            entityitem.xd = -MathHelper.sin((this.yRot / 180F) * MathHelper.PI) * MathHelper.cos((this.xRot / 180F) * MathHelper.PI) * f1;
-            entityitem.zd = MathHelper.cos((this.yRot / 180F) * MathHelper.PI) * MathHelper.cos((this.xRot / 180F) * MathHelper.PI) * f1;
-            entityitem.yd = -MathHelper.sin((this.xRot / 180F) * MathHelper.PI) * f1 + 0.1F;
-            f1 = 0.02F;
-            float f3 = this.random.nextFloat() * MathHelper.PI * 2.0F;
-            f1 *= this.random.nextFloat();
-            entityitem.xd += java.lang.Math.cos(f3) * (double) f1;
-            entityitem.yd += (this.random.nextFloat() - this.random.nextFloat()) * 0.1F;
-            entityitem.zd += java.lang.Math.sin(f3) * (double) f1;
+            float speed = 0.3F;
+            itemEntity.xd = -MathHelper.sin((this.yRot / 180F) * MathHelper.PI) * MathHelper.cos((this.xRot / 180F) * MathHelper.PI) * speed;
+            itemEntity.yd = -MathHelper.sin((this.xRot / 180F) * MathHelper.PI) * speed + 0.1F;
+            itemEntity.zd = MathHelper.cos((this.yRot / 180F) * MathHelper.PI) * MathHelper.cos((this.xRot / 180F) * MathHelper.PI) * speed;
+
+            speed = 0.02F;
+            final float jitterAngle = this.random.nextFloat() * MathHelper.PI * 2.0F;
+            speed *= this.random.nextFloat();
+            itemEntity.xd += Math.cos(jitterAngle) * speed;
+            itemEntity.yd += (this.random.nextFloat() - this.random.nextFloat()) * 0.1F;
+            itemEntity.zd += Math.sin(jitterAngle) * speed;
         }
-        joinEntityItemWithWorld(entityitem);
-        addStat(StatList.dropStat, 1);
+
+        this.joinEntityItemWithWorld(itemEntity);
+        this.addStat(StatList.dropStat, 1);
     }
 
     protected void joinEntityItemWithWorld(EntityItem entityitem) {
@@ -700,22 +705,40 @@ public abstract class Player
     }
 
     public float getCurrentPlayerStrVsBlock(@NotNull Block<?> block) {
-        float f = this.inventory.getStrVsBlock(block);
+        final @Nullable ItemStack currentItem = this.inventory.getCurrentItem();
+        float str;
+        if (currentItem != null) {
+            str = currentItem.getStrVsBlock(block);
+        } else {
+            str = 1.0f;
+        }
         float defaultBreakSpeed = (this.inventory.getCurrentItem() != null && this.inventory.getCurrentItem().getItem() instanceof ItemToolSword) ? 1.51f : 1.01f;
-        if (this.getGamemode().doesRequireToolToBreak() && f <= defaultBreakSpeed)
+        if (this.getGamemode().isProperToolNeededToMine() && str <= defaultBreakSpeed)
             return 0; // Requires to break and not effective against block
         if (isUnderLiquid(Materials.WATER)) {
-            f /= 5F;
+            str /= 5F;
         }
         if (!this.onGround && !canClimb() && this.vehicle == null) {
-            f /= 5F;
+            str /= 5F;
         }
-        return f;
+        return str;
     }
 
-    public boolean canHarvestBlock(Block<?> block) {
-        if (block == null) return false;
-        return this.inventory.canHarvestBlock(block);
+    public boolean canHarvestBlock(final @Nullable Block<?> block) {
+        if (block == null) {
+            return false;
+        }
+        if (block.getMaterial().isAlwaysDestroyable()) {
+            return true;
+        }
+
+        final @Nullable ItemStack stack = this.inventory.getCurrentItem();
+
+        if (stack != null) {
+            return stack.canHarvestBlock(this, block);
+        } else {
+            return false;
+        }
     }
 
     @Override
@@ -723,19 +746,33 @@ public abstract class Player
         super.readAdditionalSaveData(tag);
         this.nickname = this.nickname.replace(" ", "");
         ListTag nbttaglist = tag.getList("Inventory");
-        this.inventory.readFromNBT(nbttaglist);
+        this.inventory.load(nbttaglist);
 
         System.arraycopy(this.inventory.armorInventory, 0, this.oldArmorInventory, 0, this.oldArmorInventory.length);
 
-        this.inventory.setCurrentItemIndex(tag.getIntegerOrDefault("CurrentItem", this.inventory.getCurrentItemIndex()), true);
+        this.inventory.setCurrentSlot(tag.getIntegerOrDefault("CurrentItem", this.inventory.getCurrentSlot()), true);
         this.inventory.setHotbarOffset(tag.getIntegerOrDefault("HotbarOffset", this.inventory.getHotbarOffset()), true);
         int dim = tag.getInteger("Dimension");
         if (dim == -1) dim = 1;
         this.dimension = dim;
         this.sleeping = tag.getBoolean("Sleeping");
         this.sleepTimer = tag.getShort("SleepTimer");
-        setGamemodeOnLogin(Gamemode.gamemodesList[tag.getInteger("Gamemode")]);
-        this.noPhysics = tag.getBoolean("Noclip") && this.gamemode.canPlayerFly();
+        final @Nullable Tag<?> gamemodeTag = tag.getTag("Gamemode");
+        if (gamemodeTag != null) {
+            final @Nullable Gamemode gamemode;
+            if (gamemodeTag instanceof final @NotNull StringTag stringTag) {
+                gamemode = Registries.GAMEMODES.getItem(stringTag.getValue());
+            } else if (gamemodeTag instanceof final @NotNull IntTag intTag) {
+                gamemode = Gamemodes.getGamemodeByLegacyId(intTag.getValue());
+            } else {
+                gamemode = null;
+            }
+
+            this.setGamemodeOnLogin(Objects.requireNonNullElse(gamemode, Gamemodes.SURVIVAL));
+        } else {
+            this.setGamemodeOnLogin(Gamemodes.SURVIVAL);
+        }
+        this.noPhysics = tag.getBoolean("Noclip") && this.gamemode.hasPlayerFlight();
         this.sneaking = tag.getBoolean("Sneaking");
         if (this.sleeping) {
             this.bedTilePos = new TilePos(this);
@@ -756,14 +793,14 @@ public abstract class Player
     @Override
     public void addAdditionalSaveData(@NotNull CompoundTag tag) {
         super.addAdditionalSaveData(tag);
-        tag.put("Inventory", this.inventory.writeToNBT(new ListTag()));
-        tag.putInt("CurrentItem", this.inventory.getCurrentItemIndex());
+        tag.put("Inventory", this.inventory.save(new ListTag()));
+        tag.putInt("CurrentItem", this.inventory.getCurrentSlot());
         tag.putInt("HotbarOffset", this.inventory.getHotbarOffset());
         tag.putInt("Dimension", this.dimension);
         tag.putBoolean("Sleeping", this.sleeping);
         tag.putShort("SleepTimer", (short) this.sleepTimer);
-        tag.putInt("Gamemode", this.gamemode.getId());
-        tag.putBoolean("Noclip", this.noPhysics && this.gamemode.canPlayerFly());
+        tag.putString("Gamemode", this.gamemode.getId());
+        tag.putBoolean("Noclip", this.noPhysics && this.gamemode.hasPlayerFlight());
         tag.putBoolean("Sneaking", this.sneaking);
         if (this.playerSpawnPoint != null) {
             tag.putInt("SpawnX", this.playerSpawnPoint.x);
@@ -839,7 +876,7 @@ public abstract class Player
         if (getHealth() <= 0) {
             return false;
         }
-        if (this.gamemode.isPlayerInvulnerable()) {
+        if (this.gamemode.hasInvulnerablePlayer()) {
             return false;
         }
         if (isPlayerSleeping() && !this.world.isClientSide) {
@@ -998,7 +1035,7 @@ public abstract class Player
     }
 
     public void destroyCurrentEquippedItem() {
-        this.inventory.setItem(this.inventory.getCurrentItemIndex(), null);
+        this.inventory.setItem(this.inventory.getCurrentSlot(), null);
     }
 
     @Override
@@ -1013,12 +1050,18 @@ public abstract class Player
 
     public void attackTargetEntityWithCurrentItem(@NotNull Entity entity) {
         if (!getGamemode().canInteract()) return;
-        int i = this.inventory.getDamageVsEntity(entity);
-        if (i > 0) {
+
+        int damage = 1;
+        final @Nullable ItemStack currentItem = this.inventory.getCurrentItem();
+        if (currentItem != null) {
+            damage = currentItem.getDamageVsEntity(entity);
+        }
+
+        if (damage > 0) {
             if (this.yd < 0.0D) {
-                i++;
+                damage++;
             }
-            entity.hurt(this, i, DamageType.COMBAT);
+            entity.hurt(this, damage, DamageType.COMBAT);
             ItemStack itemstack = getCurrentEquippedItem();
             if (itemstack != null && (entity instanceof Mob)) {
                 itemstack.hitEntity((Mob) entity, this);
@@ -1030,7 +1073,7 @@ public abstract class Player
                 if (entity.isAlive()) {
                     alertWolves((Mob) entity, true);
                 }
-                addStat(StatList.damageDealtStat, i);
+                addStat(StatList.damageDealtStat, damage);
             }
         }
         addStat(StatList.mobEncounterStats.get(entity.getDispatcherId()), 1);
@@ -1041,9 +1084,6 @@ public abstract class Player
 
     public abstract void animate4();
 
-    public void onItemStackChanged(ItemStack itemstack) {
-    }
-
     @Override
     public void remove() {
         super.remove();
@@ -1254,7 +1294,7 @@ public abstract class Player
 
     @Override
     public void setHeldItem(@Nullable ItemStack item) {
-        this.inventory.setCurrentItem(item, true);
+        this.inventory.setCurrentItem(item);
     }
 
     public void updateCreativeInventory(int page, String searchText) {
@@ -1380,7 +1420,7 @@ public abstract class Player
 
     @Override
     public boolean canBreatheUnderwater() {
-        return this.gamemode.isPlayerInvulnerable();
+        return this.gamemode.hasInvulnerablePlayer();
     }
 
     public @NotNull Gamemode getGamemode() {
@@ -1391,21 +1431,21 @@ public abstract class Player
     public void setGamemodeOnLogin(Gamemode gamemode) {
         this.gamemode = gamemode;
 
-        MenuInventory newContainer = gamemode.getContainer(this.inventory, !this.world.isClientSide);
+        MenuInventory newContainer = gamemode.getInventoryMenu(this.inventory);
         if (this.craftingInventory == this.inventorySlots) {
             this.craftingInventory = newContainer;
         }
         this.inventorySlots = newContainer;
-        if (!gamemode.canPlayerFly()) {
+        if (!gamemode.hasPlayerFlight()) {
             this.noPhysics = false;
         }
 
-        this.fireImmune = gamemode.isImmuneToFire();
+        this.fireImmune = gamemode.hasFireImmunity();
     }
 
     public void setGamemode(Gamemode gamemode) {
         this.gamemode = gamemode;
-        this.fireImmune = gamemode.isImmuneToFire();
+        this.fireImmune = gamemode.hasFireImmunity();
     }
 
     public void setNoclip(final boolean noclip) {
@@ -1439,7 +1479,7 @@ public abstract class Player
             return;
         }
 
-        if (pickFully && this.gamemode == Gamemode.creative && tileEntity != null) {
+        if (pickFully && this.gamemode == Gamemodes.CREATIVE && tileEntity != null) {
             CompoundTag entityTag = new CompoundTag();
             tileEntity.writeAdditionalData(entityTag);
             selectItem.getData().put("tileEntityData", entityTag);
@@ -1456,7 +1496,7 @@ public abstract class Player
 
         //Find empty hotbar slot
         int emptyHotbarSlot = -1;
-        int slot = this.inventory.getCurrentItemIndex();
+        int slot = this.inventory.getCurrentSlot();
         for (int i = 0; i < 9; i++) {
             if (this.inventory.getItem(i + this.inventory.getHotbarOffset()) == null) {
                 emptyHotbarSlot = i + this.inventory.getHotbarOffset();
@@ -1479,7 +1519,7 @@ public abstract class Player
         }
 
         if (itemSlot == -1) {
-            if (getGamemode() == Gamemode.creative) {
+            if (getGamemode() == Gamemodes.CREATIVE) {
                 int emptySlot = -1;
                 for (int i = 0; i < 36; i++) {
                     if (this.inventory.getItem(i) == null) {
@@ -1488,7 +1528,7 @@ public abstract class Player
                     }
                 }
 
-                int createItemInsertSlot = emptyHotbarSlot != -1 ? emptyHotbarSlot : this.inventory.getCurrentItemIndex();
+                int createItemInsertSlot = emptyHotbarSlot != -1 ? emptyHotbarSlot : this.inventory.getCurrentSlot();
                 selectItem.stackSize = 1;
                 if (emptySlot != -1) {
                     swapItems(emptySlot, createItemInsertSlot);
@@ -1505,7 +1545,7 @@ public abstract class Player
     }
 
     public void setCurrentItem(int i) {
-        this.inventory.setCurrentItemIndex(i, false);
+        this.inventory.setCurrentSlot(i, false);
     }
 
     public void swapItems(int slot1, int slot2) {
diff --git a/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java b/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
index e2873835b..4decb46f8 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
@@ -10,7 +10,7 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.BlockParticleHelper;
 import net.minecraft.core.util.helper.DamageType;
 import net.minecraft.core.util.helper.MathHelper;
@@ -114,7 +114,7 @@ public class EntityBoat extends Entity {
             return true;
         }
         if (entity instanceof Player player) {
-            if (player.getGamemode() == Gamemode.creative) {
+            if (player.getGamemode() == Gamemodes.CREATIVE) {
                 remove();
                 if (this.flag != null) {
                     dropItem(this.flag.copy(), 0.0F);
@@ -445,7 +445,7 @@ public class EntityBoat extends Entity {
         if (!this.world.isClientSide) {
             if (player.getHeldItem() != null && player.getHeldItem().itemID == Items.FLAG.id && this.flag == null) {
                 this.flag = player.getHeldItem().copy();
-                player.inventory.setItem(player.inventory.getCurrentItemIndex(), null);
+                player.inventory.setItem(player.inventory.getCurrentSlot(), null);
                 createTileEntity();
                 this.world.sendTrackedEntityDataPacket(this);
                 return true;
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 7d3ab1f45..2fb52e496 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
@@ -18,7 +18,7 @@ import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.Items;
-import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.player.inventory.container.Container;
 import net.minecraft.core.player.inventory.InventorySorter;
 import net.minecraft.core.util.helper.DamageType;
@@ -224,7 +224,7 @@ public class EntityMinecart extends Entity implements Container {
             return true;
         }
         if (entity instanceof Player player) {
-            if (player.getGamemode() == Gamemode.creative) {
+            if (player.getGamemode() == Gamemodes.CREATIVE) {
                 remove();
                 return true;
             }
@@ -745,7 +745,7 @@ public class EntityMinecart extends Entity implements Container {
     }
 
     @Override
-    public boolean stillValid(Player player) {
+    public boolean stillValid(@NotNull Player player) {
         if (isRemoved()) {
             return false;
         }
@@ -807,7 +807,7 @@ public class EntityMinecart extends Entity implements Container {
                 ItemStack itemstack = player.inventory.getCurrentItem();
                 if (itemstack != null && LookupFuelFurnace.instance.getFuelYield(itemstack.itemID) > 0 && itemstack.consumeItem(player)) {
                     if (itemstack.stackSize <= 0) {
-                        player.inventory.setItem(player.inventory.getCurrentItemIndex(), null);
+                        player.inventory.setItem(player.inventory.getCurrentSlot(), null);
                     }
                     setFuel(getFuel() + MathHelper.round(((LookupFuelFurnace.instance.getFuelYield(itemstack.itemID) / 1600F) * 1200)));
                 }
@@ -873,7 +873,7 @@ public class EntityMinecart extends Entity implements Container {
     }
 
     @Override
-    public String getNameTranslationKey() {
+    public @NotNull String getNameTranslationKey() {
         return "container.minecart.name";
     }
 
@@ -888,21 +888,21 @@ public class EntityMinecart extends Entity implements Container {
     }
 
     @Override
-    public @Nullable ItemStack getItem(int index) {
-        return this.items[index];
+    public @Nullable ItemStack getItem(int slot) {
+        return this.items[slot];
     }
 
     @Override
-    public @Nullable ItemStack removeItem(int index, int takeAmount) {
-        if (this.items[index] != null) {
-            if (this.items[index].stackSize <= takeAmount) {
-                ItemStack itemstack = this.items[index];
-                this.items[index] = null;
+    public @Nullable ItemStack removeItem(int slot, int takeAmount) {
+        if (this.items[slot] != null) {
+            if (this.items[slot].stackSize <= takeAmount) {
+                ItemStack itemstack = this.items[slot];
+                this.items[slot] = null;
                 return itemstack;
             }
-            ItemStack itemstack1 = this.items[index].splitStack(takeAmount);
-            if (this.items[index].stackSize <= 0) {
-                this.items[index] = null;
+            ItemStack itemstack1 = this.items[slot].splitStack(takeAmount);
+            if (this.items[slot].stackSize <= 0) {
+                this.items[slot] = null;
             }
             return itemstack1;
         } else {
@@ -911,10 +911,10 @@ public class EntityMinecart extends Entity implements Container {
     }
 
     @Override
-    public void setItem(int index, @Nullable ItemStack itemstack) {
-        this.items[index] = itemstack;
-        if (itemstack != null && itemstack.stackSize > getMaxStackSize()) {
-            itemstack.stackSize = getMaxStackSize();
+    public void setItem(int slot, @Nullable ItemStack stack) {
+        this.items[slot] = stack;
+        if (stack != null && stack.stackSize > getMaxStackSize()) {
+            stack.stackSize = getMaxStackSize();
         }
     }
 
@@ -923,7 +923,7 @@ public class EntityMinecart extends Entity implements Container {
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         InventorySorter.sortInventory(this.items);
     }
 
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 252832a64..459d54675 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
@@ -68,7 +68,7 @@ public class ItemBucket extends Item {
                 block1.dropWithCause(world, EnumDropCause.WORLD, rayCastPos, world.getBlockData(rayCastPos), null, null);
             }
             world.setBlockIdDataNotify(rayCastPos, this.blockToPlace.id(), 0);
-            if (player.getGamemode().consumeBlocks()) {
+            if (player.getGamemode().hasBlockConsumption()) {
                 return new ItemStack(Items.BUCKET);
             }
         }
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 c48450322..1904e2510 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
@@ -77,7 +77,7 @@ public class ItemBucketEmpty extends Item {
     public static boolean useBucket(@NotNull Player player, @NotNull ItemStack itemToGive) {
         ItemStack currentItem = player.inventory.getCurrentItem();
         if (currentItem == null || currentItem.stackSize <= 1) {
-            player.inventory.setItem(player.inventory.getCurrentItemIndex(), itemToGive);
+            player.inventory.setItem(player.inventory.getCurrentSlot(), itemToGive);
             return true;
         } else {
             player.inventory.insertItem(itemToGive, true);
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 48d97f4e0..7d8e7d181 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
@@ -44,7 +44,7 @@ public class ItemDye extends Item {
         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()));
-                if (player == null || player.getGamemode().consumeBlocks()) {
+                if (player == null || player.getGamemode().hasBlockConsumption()) {
                     selfStack.stackSize--;
                 }
                 return true;
@@ -67,7 +67,7 @@ public class ItemDye extends Item {
                             grass = Blocks.GRASS_RETRO.id();
                         }
                         world.setBlockIdNotify(blockPos, grass);
-                        if (player == null || player.getGamemode().consumeBlocks()) {
+                        if (player == null || player.getGamemode().hasBlockConsumption()) {
                             selfStack.stackSize--;
                         }
                     }
@@ -79,7 +79,7 @@ public class ItemDye extends Item {
                     if (Blocks.lightBlock[world.getBlockId(blockPos.up(queryPos))] <= 2) {
                         int grass = Blocks.GRASS_SCORCHED.id();
                         world.setBlockIdNotify(blockPos, grass);
-                        if (player == null || player.getGamemode().consumeBlocks()) {
+                        if (player == null || player.getGamemode().hasBlockConsumption()) {
                             selfStack.stackSize--;
                         }
                     }
@@ -89,7 +89,7 @@ public class ItemDye extends Item {
 
             if (block != null && block.hasTag(BlockTags.GROWS_FLOWERS)) {
                 if (!world.isClientSide) {
-                    if (player == null || player.getGamemode().consumeBlocks()) {
+                    if (player == null || player.getGamemode().hasBlockConsumption()) {
                         selfStack.stackSize--;
                     }
                     TilePos p = new TilePos(blockPos);
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemJar.java b/game/core/src/main/java/net/minecraft/core/item/ItemJar.java
index f1327289c..b2ec41d87 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemJar.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemJar.java
@@ -85,7 +85,7 @@ public class ItemJar extends ItemPlaceable {
     public static boolean fillJar(@NotNull Player player, @NotNull ItemStack itemToGive) {
         ItemStack currentItem = player.inventory.getCurrentItem();
         if (currentItem == null || currentItem.stackSize <= 1) {
-            player.inventory.setItem(player.inventory.getCurrentItemIndex(), itemToGive);
+            player.inventory.setItem(player.inventory.getCurrentSlot(), itemToGive);
         } else {
             player.inventory.insertItem(itemToGive, true);
         }
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 0b0898cc4..971180231 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
@@ -33,7 +33,7 @@ public class ItemMinecart extends Item {
         if(!world.isClientSide) {
             world.entityJoinedWorld(new EntityMinecart(world, (float) blockPos.x() + 0.5F, (float) blockPos.y() + 0.5F, (float) blockPos.z() + 0.5F, this.minecartType));
         }
-        if (player == null || player.getGamemode().consumeBlocks()) {
+        if (player == null || player.getGamemode().hasBlockConsumption()) {
             selfStack.stackSize--;
         }
         return true;
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 857c8b278..3f421b05d 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
@@ -255,7 +255,7 @@ public final class ItemStack {
 
     public void damageItem(int damage, @Nullable Entity entity) {
         if (entity instanceof Player) {
-            if (!((Player)entity).getGamemode().toolDurability()) return;
+            if (!((Player)entity).getGamemode().hasToolDurability()) return;
         }
         if(!isItemStackDamageable())
         {
@@ -313,7 +313,7 @@ public final class ItemStack {
         if(this.stackSize <= 0) {
             return false;
         }
-        if (entityplayer == null || entityplayer.getGamemode().consumeBlocks()) {
+        if (entityplayer == null || entityplayer.getGamemode().hasBlockConsumption()) {
             this.stackSize--;
         }
         return true;
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java b/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java
index 09285a34e..8979d9b70 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemWandSpawner.java
@@ -2,12 +2,12 @@ package net.minecraft.core.item;
 
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.entity.Mob;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
@@ -22,7 +22,7 @@ public class ItemWandSpawner extends Item implements IDispensable
     }
     @Override
     public @Nullable ItemStack onUse(@NotNull ItemStack selfStack, @NotNull World world, @NotNull Player player) {
-        if (player.gamemode != Gamemode.creative){
+        if (player.gamemode != Gamemodes.CREATIVE){
             player.sendTranslatedChatMessage("wand.wrongmode");
             return selfStack;
         }
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 3578ffb7e..3f7f54fa6 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
@@ -59,7 +59,7 @@ public class ItemBlock<T extends BlockLogic> extends Item {
                 }
                 world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.block, EnumBlockSoundEffectType.PLACE);
                 return true;
-            } else if (player == null || player.getGamemode().consumeBlocks()) {
+            } else if (player == null || player.getGamemode().hasBlockConsumption()) {
                 selfStack.stackSize += 1;
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/item/tag/ItemTags.java b/game/core/src/main/java/net/minecraft/core/item/tag/ItemTags.java
index bdbc8063a..e4edf7f3d 100644
--- a/game/core/src/main/java/net/minecraft/core/item/tag/ItemTags.java
+++ b/game/core/src/main/java/net/minecraft/core/item/tag/ItemTags.java
@@ -3,6 +3,7 @@ package net.minecraft.core.item.tag;
 import com.mojang.logging.LogUtils;
 import net.minecraft.core.data.tag.Tag;
 import net.minecraft.core.item.Item;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 
 import java.lang.reflect.Field;
@@ -15,29 +16,29 @@ public abstract class ItemTags
     /**
      * Items with this tag will not destroy blocks in creative mode
      */
-    public static Tag<Item> PREVENT_CREATIVE_MINING = Tag.of("prevent_creative_mining");
+    public static final @NotNull Tag<Item> PREVENT_CREATIVE_MINING = Tag.of("prevent_creative_mining");
     /**
      * Items with this tag will break blocks with silk touch
      */
-    public static Tag<Item> IS_SILK_TOUCH = Tag.of("is_silk_touch");
+    public static final @NotNull Tag<Item> IS_SILK_TOUCH = Tag.of("is_silk_touch");
     /**
      * Items with this tag will not be shown in the creative inventory.
      */
-    public static Tag<Item> NOT_IN_CREATIVE_MENU = Tag.of("not_in_creative_menu");
+    public static final @NotNull Tag<Item> NOT_IN_CREATIVE_MENU = Tag.of("not_in_creative_menu");
     /**
      * Blocks like doors and levers should not be interacted with when mining them with an item with this tag
      */
-    public static Tag<Item> PREVENT_LEFT_CLICK_INTERACTIONS = Tag.of("prevent_left_click_interactions");
+    public static final @NotNull Tag<Item> PREVENT_LEFT_CLICK_INTERACTIONS = Tag.of("prevent_left_click_interactions");
     /**
      * Chickens will follow the player if they are holding this item.
      */
-    public static Tag<Item> CHICKENS_FAVOURITE_ITEM = Tag.of("chickens_favourite_item");
+    public static final @NotNull Tag<Item> CHICKENS_FAVOURITE_ITEM = Tag.of("chickens_favourite_item");
     /**
      * Cows will follow the player if they are holding this item.
      */
-    public static Tag<Item> COWS_FAVOURITE_ITEM = Tag.of("cows_favourite_item");
+    public static final @NotNull Tag<Item> COWS_FAVOURITE_ITEM = Tag.of("cows_favourite_item");
 
-    public static List<Tag<Item>> TAG_LIST;
+    public static final @NotNull List<@NotNull Tag<@NotNull Item>> TAG_LIST;
 
     static
     {
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java
index 8bca8bfc1..431217d1d 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java
@@ -6,9 +6,11 @@ import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.brigadier.suggestion.Suggestions;
 import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -16,7 +18,7 @@ import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 public class ArgumentTypeGameMode implements ArgumentType<Gamemode> {
-    private static final Collection<String> EXAMPLES = Arrays.asList(Gamemode.creative.getLanguageKey(), Gamemode.survival.getLanguageKey());
+    private static final Collection<String> EXAMPLES = Arrays.asList(Gamemodes.CREATIVE.getId(), Gamemodes.SURVIVAL.getId());
 
     public static ArgumentType<Gamemode> gameMode() {
         return new ArgumentTypeGameMode();
@@ -26,8 +28,8 @@ public class ArgumentTypeGameMode implements ArgumentType<Gamemode> {
     public Gamemode parse(StringReader reader) throws CommandSyntaxException {
         final String string = reader.readString();
 
-        for (Gamemode gamemode : Gamemode.gamemodesList) {
-            if (CommandHelper.matchesKeyString(gamemode.getLanguageKey(), string) || string.equals(String.valueOf(gamemode.getId()))) {
+        for (Gamemode gamemode : Registries.GAMEMODES) {
+            if (CommandHelper.matchesKeyString(gamemode.getId(), string)) {
                 return gamemode;
             }
         }
@@ -37,8 +39,8 @@ public class ArgumentTypeGameMode implements ArgumentType<Gamemode> {
     @Override
     public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
         String remaining = builder.getRemainingLowerCase();
-        for (Gamemode gamemode : Gamemode.gamemodesList) {
-            Optional<String> optional = CommandHelper.getStringToSuggest(gamemode.getLanguageKey(), remaining);
+        for (Gamemode gamemode : Registries.GAMEMODES) {
+            Optional<String> optional = CommandHelper.getStringToSuggest(gamemode.getId(), remaining);
             optional.ifPresent(builder::suggest);
         }
         return builder.buildFuture();
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/helpers/EntitySelectorOptions.java b/game/core/src/main/java/net/minecraft/core/net/command/helpers/EntitySelectorOptions.java
index 0f11eb454..b9e384c67 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/helpers/EntitySelectorOptions.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/helpers/EntitySelectorOptions.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.tags.Tag;
+import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.lang.text.ChainText;
 import net.minecraft.core.lang.text.Text;
 import net.minecraft.core.entity.Entity;
@@ -18,6 +19,7 @@ import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.net.command.util.NbtHelper;
 import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.util.helper.LoggedPrintStream;
 
@@ -208,9 +210,9 @@ public class EntitySelectorOptions {
                         bl2 = false;
                     }
                 }
-                for (Gamemode gameMode : Gamemode.gamemodesList) {
-                    if (!CommandHelper.getStringToSuggest(gameMode.getLanguageKey(), string).isPresent()) continue;
-                    String stringToSuggest = CommandHelper.getStringToSuggest(gameMode.getLanguageKey(), string).get();
+                for (Gamemode gameMode : Registries.GAMEMODES) {
+                    if (!CommandHelper.getStringToSuggest(gameMode.getId(), string).isPresent()) continue;
+                    String stringToSuggest = CommandHelper.getStringToSuggest(gameMode.getId(), string).get();
                     if (bl2) {
                         builder.suggest("!" + stringToSuggest);
                     }
@@ -224,8 +226,8 @@ public class EntitySelectorOptions {
             String value = parser.getReader().readUnquotedString();
 
             Gamemode gamemode = null;
-            for (Gamemode iteratedGameMode : Gamemode.gamemodesList) {
-                if (CommandHelper.matchesKeyString(iteratedGameMode.getLanguageKey(), value)) {
+            for (Gamemode iteratedGameMode : Registries.GAMEMODES) {
+                if (CommandHelper.matchesKeyString(iteratedGameMode.getId(), value)) {
                     gamemode = iteratedGameMode;
                 }
             }
@@ -237,7 +239,7 @@ public class EntitySelectorOptions {
             parser.setIncludesEntities(false);
             parser.addPredicate((entity) -> {
                 if (!(entity instanceof Player)) return false;
-                return CommandHelper.matchesKeyString(((Player) entity).gamemode.getLanguageKey(), value) != invert;
+                return CommandHelper.matchesKeyString(((Player) entity).gamemode.getId(), value) != invert;
             });
 
             if (invert) {
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java b/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
index 6548d1f21..c99415d3f 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
@@ -38,6 +38,7 @@ public abstract class Packet
 
     public static final int MAX_USERNAME_SIZE = 16;
     public static final int MAX_NICKNAME_SIZE = 256;
+    public static final int MAX_REGISTRY_KEY_SIZE = 256;
     public static final int MAX_AES_KEY_SIZE = 392;
     public static final int MAX_MESSAGE_SIZE = 1024;
 
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java
index 65a2c6991..5cd09ac5e 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java
@@ -25,7 +25,7 @@ public class PacketAddPlayer extends Packet
     public String nickname;
     public byte chatColor;
     public short playerConfig;
-    public int gamemode;
+    public String gamemode;
 
 
     public PacketAddPlayer() {
@@ -73,7 +73,7 @@ public class PacketAddPlayer extends Packet
         this.nickname = readStringUTF16BE(dis, MAX_NICKNAME_SIZE);
         this.chatColor = dis.readByte();
         this.playerConfig = dis.readShort();
-        this.gamemode = Byte.toUnsignedInt(dis.readByte());
+        this.gamemode = readStringUTF16BE(dis, MAX_REGISTRY_KEY_SIZE);
 
         if (dis.readByte() == 1) {
             this.heldObjectTag = readCompressedCompoundTag(dis);
@@ -98,7 +98,7 @@ public class PacketAddPlayer extends Packet
         writeStringUTF16BE(this.nickname, dos);
         dos.writeByte(this.chatColor);
         dos.writeShort(this.playerConfig);
-        dos.writeByte(this.gamemode & 0xFF);
+        writeStringUTF16BE(this.gamemode, dos);
 
         if (this.heldObjectTag != null) {
             dos.writeByte(1);
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerGamemode.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerGamemode.java
index 0c1300a96..8f14fefa1 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerGamemode.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketPlayerGamemode.java
@@ -11,7 +11,7 @@ public class PacketPlayerGamemode extends Packet
     {
     }
     
-    public PacketPlayerGamemode(int entityId, int gamemodeId)
+    public PacketPlayerGamemode(int entityId, String gamemodeId)
     {
         this.entityId = entityId;
         this.gamemodeId = gamemodeId;
@@ -22,7 +22,7 @@ public class PacketPlayerGamemode extends Packet
         throws IOException
     {
         entityId = dis.readInt();
-        gamemodeId = dis.readByte();
+        gamemodeId = readStringUTF16BE(dis, MAX_REGISTRY_KEY_SIZE);
     }
 
     @Override
@@ -30,7 +30,7 @@ public class PacketPlayerGamemode extends Packet
         throws IOException
     {
         dos.writeInt(entityId);
-        dos.writeByte(gamemodeId);
+        writeStringUTF16BE(gamemodeId, dos);
     }
 
     @Override
@@ -45,6 +45,6 @@ public class PacketPlayerGamemode extends Packet
         return 5;
     }
 
-    public int gamemodeId;
+    public String gamemodeId;
     public int entityId;
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/gamemode/Gamemode.java b/game/core/src/main/java/net/minecraft/core/player/gamemode/Gamemode.java
index a3f41a29c..681a78a03 100644
--- a/game/core/src/main/java/net/minecraft/core/player/gamemode/Gamemode.java
+++ b/game/core/src/main/java/net/minecraft/core/player/gamemode/Gamemode.java
@@ -1,203 +1,189 @@
 package net.minecraft.core.player.gamemode;
 
+import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.player.inventory.menu.MenuInventory;
 import net.minecraft.core.player.inventory.container.ContainerInventory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class Gamemode
-{
-	private final int id;
-	private final String languageKey;
-
-	private boolean isPlayerInvulnerable = false;
-	private boolean canPlayerFly = false;
-	private boolean consumeBlocks = false;
-	private boolean doBlockBreakingAnim = false;
-	private boolean toolDurability = false;
-	private boolean dropBlockOnBreak = false;
-	private boolean areMobsHostile = false;
-	private boolean isImmuneToFire = false;
-	private boolean instantPortalTravel = false;
-	private boolean requireToolToBreak = false;
-	private boolean canInteract = true;
-	private boolean hideFromWorldCreation = false;
-	private boolean isPermaDeath = false;
-	private float blockReachDistance = 4.5f;
-	private float entityReachDistance = 3.0f;
-	
-	public Gamemode(int id, String languageKey)
-	{
-		this.id = id;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * A gamemode is essentially a collection of persistent status effects on a player. It defines a lot of core behaviours
+ * in the game, such as whether the player is invulnerable, whether blocks are dropped, and whether they can fly.
+ */
+public final class Gamemode {
+    private final @NotNull String languageKey;
+    private final @NotNull Function<@NotNull ContainerInventory, @NotNull MenuInventory> inventoryMenuSupplier;
+    private final boolean invulnerablePlayer;
+    private final boolean playerFlight;
+    private final boolean blockConsumption;
+    private final boolean blockBreakingAnimation;
+    private final boolean toolDurability;
+    private final boolean itemDrops;
+    private final boolean hostileMobs;
+    private final boolean fireImmunity;
+    private final boolean instantPortalTravel;
+    private final boolean properToolNeededToMine;
+    private final boolean canInteract;
+    private final boolean permaDeath;
+    private final float blockReachDistance;
+    private final float entityReachDistance;
+
+	/* package-private */ Gamemode(
+		final @NotNull String languageKey,
+		final @NotNull Function<@NotNull ContainerInventory, @NotNull MenuInventory> inventoryMenuSupplier,
+		final boolean invulnerablePlayer,
+		final boolean playerFlight,
+		final boolean blockConsumption,
+		final boolean blockBreakingAnimation,
+		final boolean toolDurability,
+		final boolean itemDrops,
+		final boolean hostileMobs,
+		final boolean fireImmunity,
+		final boolean instantPortalTravel,
+		final boolean properToolNeededToMine,
+		final boolean canInteract,
+		final boolean permaDeath,
+		final float blockReachDistance,
+		final float entityReachDistance
+	) {
 		this.languageKey = languageKey;
-		gamemodesList[id] = this;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public String getLanguageKey() {
-		return languageKey;
-	}
-
-	public Gamemode setIsPlayerInvulnerable()
-	{
-		isPlayerInvulnerable = true;
-		return this;
-	}
-
-	public boolean isPlayerInvulnerable() {
-		return isPlayerInvulnerable;
-	}
-
-	public Gamemode setCanPlayerFly()
-	{
-		canPlayerFly = true;
-		return this;
-	}
-
-	public boolean canPlayerFly() {
-		return canPlayerFly;
-	}
-
-	public Gamemode setConsumeBlocks()
-	{
-		consumeBlocks = true;
-		return this;
-	}
-
-	public boolean consumeBlocks() {
-		return consumeBlocks;
-	}
-
-	public Gamemode setDoBlockBreakingAnim()
-	{
-		doBlockBreakingAnim = true;
-		return this;
-	}
-
-	public boolean doBlockBreakingAnim() {
-		return doBlockBreakingAnim;
-	}
-
-	public Gamemode setToolDurability()
-	{
-		toolDurability = true;
-		return this;
-	}
-
-	public boolean toolDurability() {
-		return toolDurability;
-	}
-
-	public Gamemode setDropBlockOnBreak()
-	{
-		dropBlockOnBreak = true;
-		return this;
-	}
-
-	public boolean dropBlockOnBreak() {
-		return dropBlockOnBreak;
-	}
-
-	public Gamemode setAreMobsHostile()
-	{
-		areMobsHostile = true;
-		return this;
-	}
-
-	public boolean areMobsHostile() {
-		return areMobsHostile;
-	}
-
-	public Gamemode setIsImmuneToFire()
-	{
-		isImmuneToFire = true;
-		return this;
-	}
-
-	public boolean isImmuneToFire() {
-		return isImmuneToFire;
-	}
-
-	public Gamemode setInstantPortalTravel()
-	{
-		this.instantPortalTravel = true;
-		return this;
-	}
-
-	public boolean instantPortalTravel() {
-		return instantPortalTravel;
-	}
-
-	public Gamemode setBlockReachDistance(float blockReachDistance)
-	{
+		this.inventoryMenuSupplier = inventoryMenuSupplier;
+		this.invulnerablePlayer = invulnerablePlayer;
+		this.playerFlight = playerFlight;
+		this.blockConsumption = blockConsumption;
+		this.blockBreakingAnimation = blockBreakingAnimation;
+		this.toolDurability = toolDurability;
+		this.itemDrops = itemDrops;
+		this.hostileMobs = hostileMobs;
+		this.fireImmunity = fireImmunity;
+		this.instantPortalTravel = instantPortalTravel;
+		this.properToolNeededToMine = properToolNeededToMine;
+		this.canInteract = canInteract;
+		this.permaDeath = permaDeath;
 		this.blockReachDistance = blockReachDistance;
-		return this;
-	}
-
-	public float getBlockReachDistance() {
-		return blockReachDistance;
-	}
-	public Gamemode setEntityReachDistance(float entityReachDistance)
-	{
 		this.entityReachDistance = entityReachDistance;
-		return this;
-	}
-	public float getEntityReachDistance() {
-		return entityReachDistance;
-	}
-
-	public boolean doesRequireToolToBreak(){
-		return requireToolToBreak;
-	}
-	public Gamemode setRequireToolToBreak()
-	{
-		this.requireToolToBreak = true;
-		return this;
-	}
-	public boolean canInteract(){
-		return canInteract;
-	}
-	public Gamemode setCantInteract()
-	{
-		this.canInteract = false;
-		return this;
-	}
-
-	public boolean isHiddenFromWorldCreation(){
-		return hideFromWorldCreation;
-	}
-	public Gamemode setHideFromWorldCreation()
-	{
-		this.hideFromWorldCreation = true;
-		return this;
-	}
-	public boolean isPermaDeath(){
-		return isPermaDeath;
-	}
-	public Gamemode setPermaDeath()
-	{
-		this.isPermaDeath = true;
-		return this;
-	}
-
-	public abstract MenuInventory getContainer(ContainerInventory inventory, boolean isNotClientSide);
-
-	public static final Gamemode[] gamemodesList = new Gamemode[5];
-	public static List<Gamemode> getPublicGamemodes(){
-		List<Gamemode> gamemodes = new ArrayList<>();
-		for (Gamemode gamemode : gamemodesList){
-			if (gamemode.isHiddenFromWorldCreation()) continue;
-			gamemodes.add(gamemode);
-		}
-		return gamemodes;
-	}
-	public static final Gamemode survival = new GamemodeSurvival(0, "gamemode.survival").setConsumeBlocks().setDoBlockBreakingAnim().setToolDurability().setDropBlockOnBreak().setAreMobsHostile();
-	public static final Gamemode creative = new GamemodeCreative(1, "gamemode.creative").setIsPlayerInvulnerable().setCanPlayerFly().setIsImmuneToFire().setInstantPortalTravel().setBlockReachDistance(6.0f).setEntityReachDistance(4.5f);
-	public static final Gamemode hardcore = new GamemodeSurvival(2, "gamemode.hardcore").setConsumeBlocks().setDoBlockBreakingAnim().setToolDurability().setDropBlockOnBreak().setAreMobsHostile().setPermaDeath();
-	public static final Gamemode adventure = new GamemodeSurvival(3, "gamemode.adventure").setConsumeBlocks().setDoBlockBreakingAnim().setToolDurability().setDropBlockOnBreak().setAreMobsHostile().setRequireToolToBreak();
-	public static final Gamemode spectator = new GamemodeSurvival(4, "gamemode.spectator").setIsPlayerInvulnerable().setCanPlayerFly().setIsImmuneToFire().setInstantPortalTravel().setBlockReachDistance(5000).setEntityReachDistance(5000).setCantInteract().setHideFromWorldCreation();
+    }
+
+    /**
+     * Fetches the namespace ID for this gamemode.
+     */
+    public @NotNull String getId() {
+        return Objects.requireNonNull(Registries.GAMEMODES.getKey(this));
+    }
+
+    /**
+     * Fetches the language key for this gamemode.
+     */
+    public @NotNull String getLanguageKey() {
+        return this.languageKey;
+    }
+
+    /**
+     * Provides the correct {@link net.minecraft.core.player.inventory.menu.MenuInventory MenuInventory} wrapper for
+     * the provided {@link net.minecraft.core.player.inventory.container.ContainerInventory ContainerInventory}.
+     */
+	public @NotNull MenuInventory getInventoryMenu(final @NotNull ContainerInventory inventory) {
+		return this.inventoryMenuSupplier.apply(inventory);
+	}
+
+    /**
+     * If true, the player is immune to damage.
+     */
+    public boolean hasInvulnerablePlayer() {
+        return this.invulnerablePlayer;
+    }
+
+    /**
+     * If true, the player can fly.
+     */
+    public boolean hasPlayerFlight() {
+        return this.playerFlight;
+    }
+
+    /**
+     * If true, blocks in the inventory are consumed when placed.
+     */
+    public boolean hasBlockConsumption() {
+        return this.blockConsumption;
+    }
+
+    /**
+     * If true, blocks take time to break, and a breaking animation is displayed on the client.
+     */
+    public boolean hasBlockBreakingAnimation() {
+        return this.blockBreakingAnimation;
+    }
+
+    /**
+     * If true, tools lose durability when used, and will break when that durability runs out.
+     */
+    public boolean hasToolDurability() {
+        return this.toolDurability;
+    }
+
+    /**
+     * If true, items will drop when blocks are mined by the player.
+     */
+    public boolean hasItemDrops() {
+        return this.itemDrops;
+    }
+
+    /**
+     * If true, mobs will be hostile to the player.
+     */
+    public boolean hasHostileMobs() {
+        return this.hostileMobs;
+    }
+
+    /**
+     * If true, the player cannot be hurt by fire.
+     */
+    public boolean hasFireImmunity() {
+        return this.fireImmunity;
+    }
+
+    /**
+     * If true, the player will travel through dimensional portals instantly, rather than playing an animation first.
+     */
+    public boolean hasInstantPortalTravel() {
+        return this.instantPortalTravel;
+    }
+
+    /**
+     * Fetches the distance away from the player that blocks can be hit and interacted with.
+     */
+    public float getBlockReachDistance() {
+        return this.blockReachDistance;
+    }
+
+    /**
+     * Fetches the distance away from the player that entities can be hit and interacted with.
+     */
+    public float getEntityReachDistance() {
+        return this.entityReachDistance;
+    }
+
+    /**
+     * If true, blocks will only be mine-able using the correct tool, e.g. shovel on dirt, and will never break
+     * otherwise.
+     */
+    public boolean isProperToolNeededToMine() {
+        return this.properToolNeededToMine;
+    }
+
+    /**
+     * If true, the player can interact with mobs and entities.
+     */
+    public boolean canInteract() {
+        return this.canInteract;
+    }
+
+    /**
+     * If true, the player cannot respawn on death and will be forced to delete their world.
+     */
+    public boolean hasPermaDeath() {
+        return this.permaDeath;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeBuilder.java b/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeBuilder.java
new file mode 100644
index 000000000..8ecbcb55a
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeBuilder.java
@@ -0,0 +1,185 @@
+package net.minecraft.core.player.gamemode;
+
+import net.minecraft.core.player.inventory.container.ContainerInventory;
+import net.minecraft.core.player.inventory.menu.MenuInventory;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Function;
+
+/**
+ * Used to construct an instance of {@link net.minecraft.core.player.gamemode.Gamemode Gamemode}.
+ */
+public class GamemodeBuilder {
+    private final @NotNull String languageKey;
+    private final @NotNull Function<@NotNull ContainerInventory, @NotNull MenuInventory> inventoryMenuSupplier;
+
+    private boolean invulnerablePlayer = false;
+    private boolean playerFlight = false;
+    private boolean blockConsumption = false;
+    private boolean blockBreakingAnimation = false;
+    private boolean toolDurability = false;
+    private boolean itemDrops = false;
+    private boolean hostileMobs = false;
+    private boolean fireImmunity = false;
+    private boolean instantPortalTravel = false;
+    private boolean properToolNeededToMine = false;
+    private boolean canInteract = true;
+    private boolean permaDeath = false;
+    private float blockReachDistance = 4.5f;
+    private float entityReachDistance = 3.0f;
+
+    public GamemodeBuilder(
+        final @NotNull String languageKey,
+        final @NotNull Function<@NotNull ContainerInventory, @NotNull MenuInventory> inventoryMenuSupplier
+    ) {
+        this.languageKey = languageKey;
+        this.inventoryMenuSupplier = inventoryMenuSupplier;
+    }
+
+    public @NotNull Gamemode build() {
+        return new Gamemode(
+            this.languageKey,
+            this.inventoryMenuSupplier,
+            this.invulnerablePlayer,
+            this.playerFlight,
+            this.blockConsumption,
+            this.blockBreakingAnimation,
+            this.toolDurability,
+            this.itemDrops,
+            this.hostileMobs,
+            this.fireImmunity,
+            this.instantPortalTravel,
+            this.properToolNeededToMine,
+            this.canInteract,
+            this.permaDeath,
+            this.blockReachDistance,
+            this.entityReachDistance
+        );
+    }
+
+    /**
+     * Sets the player to be invulnerable.
+     * @see Gamemode#hasInvulnerablePlayer()
+     */
+    public @NotNull GamemodeBuilder withInvulnerablePlayer() {
+        this.invulnerablePlayer = true;
+        return this;
+    }
+
+    /**
+     * Sets the player to be able to fly.
+     * @see Gamemode#hasPlayerFlight()
+     */
+    public @NotNull GamemodeBuilder withPlayerFlight() {
+        this.playerFlight = true;
+        return this;
+    }
+
+    /**
+     * Sets the player to consume blocks on place.
+     * @see Gamemode#hasBlockConsumption()
+     */
+    public @NotNull GamemodeBuilder withBlockConsumption() {
+        this.blockConsumption = true;
+        return this;
+    }
+
+    /**
+     * Sets the player to break blocks with an animation.
+     * @see Gamemode#hasBlockBreakingAnimation()
+     */
+    public @NotNull GamemodeBuilder withBlockBreakingAnimation() {
+        this.blockBreakingAnimation = true;
+        return this;
+    }
+
+    /**
+     * Sets the player's tools to take durability damage.
+     * @see Gamemode#hasToolDurability()
+     */
+    public @NotNull GamemodeBuilder withToolDurability() {
+        this.toolDurability = true;
+        return this;
+    }
+
+    /**
+     * Sets blocks to drop items when mined by the player.
+     * @see Gamemode#hasItemDrops()
+     */
+    public @NotNull GamemodeBuilder withItemDrops() {
+        this.itemDrops = true;
+        return this;
+    }
+
+    /**
+     * Sets mobs to be hostile to the player.
+     * @see Gamemode#hasHostileMobs()
+     */
+    public @NotNull GamemodeBuilder withHostileMobs() {
+        this.hostileMobs = true;
+        return this;
+    }
+
+    /**
+     * Sets the player to be immune to fire.
+     * @see Gamemode#hasFireImmunity()
+     */
+    public @NotNull GamemodeBuilder withFireImmunity() {
+        this.fireImmunity = true;
+        return this;
+    }
+
+    /**
+     * Sets the player to travel through portals instantly.
+     * @see Gamemode#hasInstantPortalTravel()
+     */
+    public @NotNull GamemodeBuilder withInstantPortalTravel() {
+        this.instantPortalTravel = true;
+        return this;
+    }
+
+    /**
+     * Sets the player's block reach distance.
+     * @see Gamemode#getBlockReachDistance()
+     */
+    public @NotNull GamemodeBuilder withBlockReachDistance(final float blockReachDistance) {
+        this.blockReachDistance = blockReachDistance;
+        return this;
+    }
+
+    /**
+     * Sets the player's entity reach distance.
+     * @see Gamemode#getEntityReachDistance()
+     */
+    public @NotNull GamemodeBuilder withEntityReachDistance(final float entityReachDistance) {
+        this.entityReachDistance = entityReachDistance;
+        return this;
+    }
+
+    /**
+     * Sets that the player needs the correct tool to mine blocks.
+     * @see Gamemode#isProperToolNeededToMine()
+     */
+    public @NotNull GamemodeBuilder withProperToolNeededToMine() {
+        this.properToolNeededToMine = true;
+        return this;
+    }
+
+    /**
+     * Sets that the player cannot interact with mobs or items.
+     * @see Gamemode#canInteract()
+     */
+    public @NotNull GamemodeBuilder withNoInteraction() {
+        this.canInteract = false;
+        return this;
+    }
+
+    /**
+     * Sets that the player cannot respawn on death.
+     * @see Gamemode#hasPermaDeath()
+     */
+    public @NotNull GamemodeBuilder withPermaDeath() {
+        this.permaDeath = true;
+        return this;
+    }
+}
diff --git a/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeCreative.java b/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeCreative.java
deleted file mode 100644
index cab24ec2b..000000000
--- a/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeCreative.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.minecraft.core.player.gamemode;
-
-import net.minecraft.core.player.inventory.container.ContainerInventory;
-import net.minecraft.core.player.inventory.menu.MenuInventory;
-import net.minecraft.core.player.inventory.menu.MenuInventoryCreative;
-
-public class GamemodeCreative extends Gamemode
-{
-
-	public GamemodeCreative(int id, String languageKey)
-	{
-		super(id, languageKey);
-	}
-
-	@Override
-	public MenuInventory getContainer(ContainerInventory inventory, boolean isNotClientSide)
-	{
-		return new MenuInventoryCreative(inventory, isNotClientSide);
-	}
-}
diff --git a/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeSurvival.java b/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeSurvival.java
deleted file mode 100644
index cce883503..000000000
--- a/game/core/src/main/java/net/minecraft/core/player/gamemode/GamemodeSurvival.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package net.minecraft.core.player.gamemode;
-
-import net.minecraft.core.player.inventory.menu.MenuInventory;
-import net.minecraft.core.player.inventory.container.ContainerInventory;
-
-public class GamemodeSurvival extends Gamemode
-{
-
-	public GamemodeSurvival(int id, String languageKey)
-	{
-		super(id, languageKey);
-	}
-
-	@Override
-	public MenuInventory getContainer(ContainerInventory inventory, boolean isNotClientSide)
-	{
-		return new MenuInventory(inventory, isNotClientSide);
-	}
-}
diff --git a/game/core/src/main/java/net/minecraft/core/player/gamemode/Gamemodes.java b/game/core/src/main/java/net/minecraft/core/player/gamemode/Gamemodes.java
new file mode 100644
index 000000000..5ab6818c3
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/player/gamemode/Gamemodes.java
@@ -0,0 +1,109 @@
+package net.minecraft.core.player.gamemode;
+
+import net.minecraft.core.data.registry.Registries;
+import net.minecraft.core.player.inventory.container.ContainerInventory;
+import net.minecraft.core.player.inventory.menu.MenuInventory;
+import net.minecraft.core.player.inventory.menu.MenuInventoryCreative;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public final class Gamemodes {
+    /**
+     * The default gamemode. Players will be forced to survive in the wilderness, collecting blocks and items and
+     * fighting monsters.
+     */
+    public static final @NotNull Gamemode SURVIVAL = register("minecraft:gamemode/survival",
+        new GamemodeBuilder("gamemode.survival", Gamemodes::survivalInventory)
+            .withBlockConsumption()
+            .withBlockBreakingAnimation()
+            .withToolDurability()
+            .withItemDrops()
+            .withHostileMobs()
+            .build()
+    );
+
+    /**
+     * Minecraft's original gamemode. Players are invulnerable and have unlimited access to blocks and items.
+     */
+    public static final @NotNull Gamemode CREATIVE = register("minecraft:gamemode/creative",
+        new GamemodeBuilder("gamemode.creative", Gamemodes::creativeInventory)
+            .withInvulnerablePlayer()
+            .withPlayerFlight()
+            .withFireImmunity()
+            .withInstantPortalTravel()
+            .withBlockReachDistance(6.0f)
+            .withEntityReachDistance(4.5f)
+            .build()
+    );
+
+    /**
+     * Identical to {@link Gamemodes#SURVIVAL} but the player must delete their world on death.
+     */
+    public static final @NotNull Gamemode HARDCORE = register("minecraft:gamemode/hardcore",
+        new GamemodeBuilder("gamemode.hardcore", Gamemodes::survivalInventory)
+            .withBlockConsumption()
+            .withBlockBreakingAnimation()
+            .withToolDurability()
+            .withItemDrops()
+            .withHostileMobs()
+            .withPermaDeath()
+            .build()
+    );
+
+    /**
+     * Identical to {@link Gamemodes#SURVIVAL} but the player can only break blocks with the proper tool.
+     */
+    public static final @NotNull Gamemode ADVENTURE = register("minecraft:gamemode/adventure",
+        new GamemodeBuilder("gamemode.adventure", Gamemodes::survivalInventory)
+            .withBlockConsumption()
+            .withBlockBreakingAnimation()
+            .withToolDurability()
+            .withItemDrops()
+            .withHostileMobs()
+            .withProperToolNeededToMine()
+            .build()
+    );
+
+    /**
+     * The player is a ghost - they cannot be seen or heard, and cannot have any impact on the world.
+     */
+    public static final @NotNull Gamemode SPECTATOR = register("minecraft:gamemode/spectator",
+        new GamemodeBuilder("gamemode.spectator", Gamemodes::survivalInventory)
+            .withInvulnerablePlayer()
+            .withPlayerFlight()
+            .withFireImmunity()
+            .withInstantPortalTravel()
+            .withBlockReachDistance(5000)
+            .withEntityReachDistance(5000)
+            .withNoInteraction()
+            .build()
+    );
+
+    public static @NotNull Gamemode register(final @NotNull String id, final @NotNull Gamemode gamemode) {
+        Registries.GAMEMODES.register(id, gamemode);
+        return gamemode;
+    }
+
+    public static void init() { }
+
+    public static @Nullable Gamemode getGamemodeByLegacyId(final int id) {
+        return switch (id) {
+            case 0 -> SURVIVAL;
+            case 1 -> CREATIVE;
+            case 2 -> HARDCORE;
+            case 3 -> ADVENTURE;
+            case 4 -> SPECTATOR;
+            default -> null;
+        };
+    }
+
+    private static @NotNull MenuInventory survivalInventory(final @NotNull ContainerInventory inventory) {
+        return new MenuInventory(inventory);
+    }
+
+    private static @NotNull MenuInventory creativeInventory(final @NotNull ContainerInventory inventory) {
+        return new MenuInventoryCreative(inventory);
+    }
+
+    private Gamemodes() { }
+}
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/container/Container.java b/game/core/src/main/java/net/minecraft/core/player/inventory/container/Container.java
index 357d36376..123bf68aa 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/container/Container.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/container/Container.java
@@ -2,30 +2,75 @@ package net.minecraft.core.player.inventory.container;
 
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import net.minecraft.core.item.Item;
 
-public interface Container
-{
-
+/**
+ * Models a container, which holds a set of {@link ItemStack ItemStack}s.
+ */
+public interface Container {
+    /**
+     * Fetches the total size of the container in slots.
+     */
     int getContainerSize();
 
-    @Nullable ItemStack getItem(int index);
+    /**
+     * Fetches the {@link ItemStack} at the given slot.
+     * @param slot The slot to fetch the item from.
+     */
+    @Nullable ItemStack getItem(int slot);
 
-    @Nullable ItemStack removeItem(int index, int takeAmount);
+    /**
+     * Removes {@code takeAmount} quantity of items from the given slot, effectively splitting the {@link ItemStack} in
+     * that slot.
+     * <br><br>
+     * For example, if {@code takeAmount} was 2 and the {@code stackSize} of the {@link ItemStack} was 5, an
+     * {@link ItemStack} identical to the {@link ItemStack} in the slot would be returned, but with a {@code stackSize}
+     * of 2. The {@code stackSize} of the original {@link ItemStack} would be set to 3.
+     * @param slot The slot to take items from.
+     * @return A new {@link ItemStack}, or {@code null} if the slot was empty.
+     */
+    @Nullable ItemStack removeItem(int slot, int takeAmount);
 
-    void setItem(int index, @Nullable ItemStack itemstack);
+    /**
+     * Overwrites the {@link ItemStack} in the given slot with {@code stack}.
+     * @param slot The slot to overwrite.
+     * @param stack The stack to insert.
+     */
+    void setItem(int slot, @Nullable ItemStack stack);
 
-    String getNameTranslationKey();
+    /**
+     * Fetches the translation key for the container.
+     */
+    @NotNull String getNameTranslationKey();
 
+    /**
+     * The maximum stack size for any given slot in the container. The "true" stack size for any given slot is the
+     * minimum of this and {@link Item#getItemStackLimit(ItemStack)}.
+     */
     int getMaxStackSize();
 
+    /**
+     * Called whenever a slot in the container is changed somehow.
+     */
     void setChanged();
 
-    boolean stillValid(Player entityplayer);
+    /**
+     * Determines whether the container view is still valid. If it is invalid, it should be closed immediately.
+     * @param player The player viewing the container.
+     */
+    boolean stillValid(@NotNull Player player);
 
-    void sortContainer();
+    /**
+     * Sorts the contents of the container.
+     */
+    void sort();
 
-    default boolean locked(int index) {
+    /**
+     * Determines whether the given slot has been locked and cannot be modified.
+     */
+    default boolean locked(final int slot) {
         return false;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCompound.java b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCompound.java
index b9896ff91..5b04596d1 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCompound.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCompound.java
@@ -3,98 +3,127 @@ package net.minecraft.core.player.inventory.container;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.player.inventory.InventorySorter;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class ContainerCompound
-    implements Container
-{
-    private String name;
-    private Container c1;
-    private Container c2;
-
-    public ContainerCompound(String s, Container c1, Container c2)
-    {
-        name = s;
-        this.c1 = c1;
-        this.c2 = c2;
+    implements Container {
+    private final @NotNull String name;
+    private final @NotNull Container @NotNull [] containers;
+
+    public ContainerCompound(final @NotNull String name, final @NotNull Container @NotNull... containers) {
+        this.name = name;
+        this.containers = containers;
+
+        if (this.containers.length == 0) {
+            throw new IllegalArgumentException("Cannot create an empty compound!");
+        }
     }
 
     @Override
-	public int getContainerSize()
-    {
-        return c1.getContainerSize() + c2.getContainerSize();
+    public int getContainerSize() {
+        int sum = 0;
+        for (final @NotNull Container container : this.containers) {
+            sum += container.getContainerSize();
+        }
+
+        return sum;
     }
 
     @Override
-	public String getNameTranslationKey()
-    {
-        return name;
+    public @NotNull String getNameTranslationKey() {
+        return this.name;
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
-    {
-        if(index >= c1.getContainerSize())
-        {
-            return c2.getItem(index - c1.getContainerSize());
-        } else
-        {
-            return c1.getItem(index);
+    public @Nullable ItemStack getItem(final int slot) {
+        if (slot < 0) {
+            return null;
         }
+
+        int sum = 0;
+        for (final @NotNull Container container : this.containers) {
+            if (slot < sum + container.getContainerSize()) {
+                return container.getItem(slot - sum);
+            }
+
+            sum += container.getContainerSize();
+        }
+
+        return null;
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
-    {
-        if(index >= c1.getContainerSize())
-        {
-            return c2.removeItem(index - c1.getContainerSize(), takeAmount);
-        } else
-        {
-            return c1.removeItem(index, takeAmount);
+    public @Nullable ItemStack removeItem(final int slot, final int takeAmount) {
+        if (slot < 0) {
+            return null;
         }
+
+        int sum = 0;
+        for (final @NotNull Container container : this.containers) {
+            if (slot < sum + container.getContainerSize()) {
+                return container.removeItem(slot - sum, takeAmount);
+            }
+
+            sum += container.getContainerSize();
+        }
+
+        return null;
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
-    {
-        if(index >= c1.getContainerSize())
-        {
-            c2.setItem(index - c1.getContainerSize(), itemstack);
-        } else
-        {
-            c1.setItem(index, itemstack);
+    public void setItem(final int slot, final @Nullable ItemStack stack) {
+        if (slot < 0) {
+            return;
+        }
+
+        int sum = 0;
+        for (final @NotNull Container container : this.containers) {
+            if (slot < sum + container.getContainerSize()) {
+                container.setItem(slot - sum, stack);
+                break;
+            }
+
+            sum += container.getContainerSize();
         }
     }
 
     @Override
-	public int getMaxStackSize()
-    {
-        return c1.getMaxStackSize();
+    public int getMaxStackSize() {
+        return this.containers[0].getMaxStackSize();
     }
 
     @Override
-	public void setChanged()
-    {
-        c1.setChanged();
-        c2.setChanged();
+    public void setChanged() {
+        for (final @NotNull Container container : this.containers) {
+            container.setChanged();
+        }
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
-    {
-        return c1.stillValid(entityplayer) && c2.stillValid(entityplayer);
+    public boolean stillValid(final @NotNull Player player) {
+        boolean invalid = false;
+        for (final @NotNull Container container : this.containers) {
+            invalid |= !container.stillValid(player);
+        }
+
+        return !invalid;
     }
 
     @Override
-    public void sortContainer() {
-        ItemStack[] itemStacks = new ItemStack[getContainerSize()];
+    public void sort() {
+        // Create unified copy of joined inventory
+        final @Nullable ItemStack @NotNull [] itemStacks = new ItemStack[this.getContainerSize()];
         for (int i = 0; i < itemStacks.length; i++) {
-            itemStacks[i] = getItem(i);
+            itemStacks[i] = this.getItem(i);
         }
+
+        // Sort unified copy
         InventorySorter.sortInventory(itemStacks);
+
+        // Copy unified copy back into joined inventory
         for (int i = 0; i < itemStacks.length; i++) {
-            setItem(i, itemStacks[i]);
+            this.setItem(i, itemStacks[i]);
         }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCrafting.java b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCrafting.java
index 9e806cdcd..226fdaaa5 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCrafting.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerCrafting.java
@@ -3,123 +3,97 @@ package net.minecraft.core.player.inventory.container;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.player.inventory.menu.MenuAbstract;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class ContainerCrafting
-    implements Container
-{
-    private ItemStack[] items;
-    private int width;
-    private MenuAbstract menu;
+    implements Container {
+    private final @NotNull MenuAbstract menu;
+    private final int xSize;
+    private final @Nullable ItemStack @NotNull [] items;
 
-    public ContainerCrafting(MenuAbstract container, int width, int n)
-    {
-        int k = width * n;
-        items = new ItemStack[k];
-        menu = container;
-        this.width = width;
+    public ContainerCrafting(final @NotNull MenuAbstract menu, final int xSize, final int ySize) {
+        this.menu = menu;
+        this.xSize = xSize;
+        this.items = new ItemStack[xSize * ySize];
     }
 
     @Override
-	public int getContainerSize()
-    {
-        return items.length;
+    public int getContainerSize() {
+        return this.items.length;
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
-    {
-        if(index >= getContainerSize())
-        {
+    public @Nullable ItemStack getItem(final int slot) {
+        if (slot >= this.getContainerSize()) {
             return null;
-        } else
-        {
-            return items[index];
+        } else {
+            return this.items[slot];
         }
     }
 
-    public ItemStack getItemStackAt(int i, int j)
-    {
-        if(i < 0 || i >= width)
-        {
+    public @Nullable ItemStack getItemStackAt(final int x, final int y) {
+        if (x < 0 || x >= this.xSize) {
             return null;
-        } else
-        {
-            int k = i + j * width;
-            return getItem(k);
+        } else {
+            return this.getItem(x + y * this.xSize);
         }
     }
 
-    public void setSlotContentsAt(int i, int j, ItemStack itemStack)
-    {
-        if(i < 0 || i >= width)
-        {
-            return;
-        } else
-        {
-            int k = i + j * width;
-            setItem(k, itemStack);
+    public void setSlotContentsAt(final int x, final int y, final @Nullable ItemStack stack) {
+        if (x >= 0 && x < this.xSize) {
+            this.setItem(x + y * this.xSize, stack);
         }
     }
 
     @Override
-	public String getNameTranslationKey()
-    {
+    public @NotNull String getNameTranslationKey() {
         return "container.crafting.name";
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
-    {
-        if(items[index] != null)
-        {
-            if(items[index].stackSize <= takeAmount)
-            {
-                ItemStack itemstack = items[index];
-                items[index] = null;
-                menu.slotsChanged(this);
-                return itemstack;
+    public @Nullable ItemStack removeItem(final int slot, final int takeAmount) {
+        final @Nullable ItemStack currentItem = this.items[slot];
+        if (currentItem != null) {
+            if (currentItem.stackSize <= takeAmount) {
+                this.items[slot] = null;
+                this.menu.slotsChanged(this);
+                return currentItem;
             }
-            ItemStack itemstack1 = items[index].splitStack(takeAmount);
-            if(items[index].stackSize <= 0)
-            {
-                items[index] = null;
+            final @NotNull ItemStack otherHalf = currentItem.splitStack(takeAmount);
+            if (currentItem.stackSize <= 0) {
+                this.items[slot] = null;
             }
-            menu.slotsChanged(this);
-            return itemstack1;
-        } else
-        {
+            this.menu.slotsChanged(this);
+            return otherHalf;
+        } else {
             return null;
         }
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
-    {
-        items[index] = itemstack;
-        menu.slotsChanged(this);
+    public void setItem(final int slot, final @Nullable ItemStack stack) {
+        this.items[slot] = stack;
+        this.menu.slotsChanged(this);
     }
 
     @Override
-	public int getMaxStackSize()
-    {
+    public int getMaxStackSize() {
         return 64;
     }
 
     @Override
-	public void setChanged()
-    {
-        menu.slotsChanged(this);
+    public void setChanged() {
+        this.menu.slotsChanged(this);
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
-    {
+    public boolean stillValid(final @NotNull Player player) {
         return true;
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 }
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 d3df9372d..a4c6ddfc1 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
@@ -4,487 +4,407 @@ package net.minecraft.core.player.inventory.container;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.tags.ListTag;
 
-import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.tag.BlockTags;
-import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.IArmorShape;
 import net.minecraft.core.item.IArmorItem;
 import net.minecraft.core.item.Item;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.item.material.ArmorMaterial;
 import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.player.inventory.InventorySorter;
-import net.minecraft.core.util.helper.DamageType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.Arrays;
+import java.util.Objects;
+
 public class ContainerInventory
-    implements Container
-{
-    protected int hotbarOffset = 0;
-    public @Nullable ItemStack @NotNull [] mainInventory;
-    public @Nullable ItemStack @NotNull [] armorInventory;
-    protected int currentItem;
-    public @NotNull Player player;
-    private ItemStack heldItem;
-    public boolean inventoryChanged;
-
-    public ContainerInventory(@NotNull Player player)
-    {
-        mainInventory = new ItemStack[36];
-        armorInventory = new ItemStack[4];
-        currentItem = 0;
-        inventoryChanged = false;
+    implements Container {
+    public static final int MAIN_INVENTORY_SIZE = 36;
+    public static final int ARMOR_INVENTORY_SIZE = 4;
+    public static final int HOTBAR_SIZE = 9;
+
+    private static final int NBT_ARMOR_SLOT_OFFSET = 100;
+
+    public final @NotNull Player player;
+
+    public final @Nullable ItemStack @NotNull [] mainInventory = new ItemStack[MAIN_INVENTORY_SIZE];
+    public final @Nullable ItemStack @NotNull [] armorInventory = new ItemStack[ARMOR_INVENTORY_SIZE];
+
+    private int currentSlot = 0;
+    private @Nullable ItemStack heldItem = null;
+    private int hotbarOffset = 0;
+
+    public ContainerInventory(final @NotNull Player player) {
         this.player = player;
     }
 
+    @Override
+    public @Nullable ItemStack getItem(int slot) {
+        @Nullable ItemStack @NotNull [] inventory = this.mainInventory;
+
+        if (slot >= MAIN_INVENTORY_SIZE) {
+            inventory = this.armorInventory;
+            slot -= MAIN_INVENTORY_SIZE;
+        }
+
+        return inventory[slot];
+    }
+
+    @Override
+    public void setItem(int slot, final @Nullable ItemStack stack) {
+        @Nullable ItemStack @NotNull [] inventory = this.mainInventory;
+
+        if (slot >= MAIN_INVENTORY_SIZE) {
+            inventory = this.armorInventory;
+            slot -= MAIN_INVENTORY_SIZE;
+        }
+
+        inventory[slot] = stack;
+    }
+
     public int getHotbarOffset() {
-        return hotbarOffset;
+        return this.hotbarOffset;
     }
 
-    public void setHotbarOffset(int offset, boolean overrideLock) {
-        if (!overrideLock && currentItemLocked()) return;
-        hotbarOffset = offset;
+    public void setHotbarOffset(final int offset, final boolean overrideLock) {
+        if (!overrideLock && this.currentSlotLocked()) {
+            return;
+        }
+
+        this.hotbarOffset = offset;
     }
 
-    @Nullable
-    public ItemStack getCurrentItem()
-    {
-        if(currentItem < 9 + hotbarOffset && currentItem >= hotbarOffset)
-        {
-            return mainInventory[currentItem];
-        } else
-        {
+
+    public @Nullable ItemStack getCurrentItem() {
+        if (this.currentSlot >= this.hotbarOffset && this.currentSlot < this.hotbarOffset + HOTBAR_SIZE) {
+            return this.mainInventory[this.currentSlot];
+        } else {
             return null;
         }
     }
 
-    public int getCurrentItemIndex() {
-        return currentItem;
+    public int setCurrentItem(final @NotNull 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;
+            }
+        }
+
+        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;
+            }
+        }
+
+        this.mainInventory[this.currentSlot] = stack;
+
+        return this.currentSlot;
     }
 
-    public void setCurrentItemIndex(int index, boolean overrideLock) {
-        if (!overrideLock && currentItemLocked()) return;
-        currentItem = index;
+    public int getCurrentSlot() {
+        return this.currentSlot;
     }
-    
-    public static int playerMainInventorySize()
-    {
-        return 9 * 4;
+
+    public void setCurrentSlot(final int slot, final boolean overrideLock) {
+        if (!overrideLock && this.currentSlotLocked()) return;
+        this.currentSlot = slot;
     }
 
-    private int getInventorySlotContainItem(int i)
-    {
-        for(int j = 0; j < mainInventory.length; j++)
-        {
-            if(mainInventory[j] != null && mainInventory[j].itemID == i)
-            {
-                return j;
-            }
+    public void setHeldItemStack(final @Nullable ItemStack itemstack) {
+        this.heldItem = itemstack;
+
+        if (itemstack != null && itemstack.stackSize <= 0) {
+            this.heldItem = null;
         }
+    }
 
-        return -1;
+    public @Nullable ItemStack getHeldItemStack() {
+        return this.heldItem;
     }
 
-    private int storeItemStack(ItemStack itemstack)
-    {
-        for(int i = 0; i < mainInventory.length; i++)
-        {
-            if (mainInventory[i] != null &&
-                    mainInventory[i].itemID == itemstack.itemID &&
-                    mainInventory[i].isStackable() &&
-                    mainInventory[i].stackSize < mainInventory[i].getMaxStackSize() &&
-                    mainInventory[i].stackSize < getMaxStackSize() &&
-                    (!mainInventory[i].getHasSubtypes() || mainInventory[i].getMetadata() == itemstack.getMetadata())
-            )
-            {
+    private int getFirstSlotContaining(final int itemId) {
+        for (int i = 0; i < this.mainInventory.length; i++) {
+            final @Nullable ItemStack stack = this.mainInventory[i];
+            if (stack != null && stack.itemID == itemId) {
                 return i;
             }
         }
 
         return -1;
     }
-	
+
     /**
      * Add an ItemStack into the players inventory. When items are added to the players inventory, the stack size of the given ItemStack is reduced. <br>
-     * The given ItemStack may have a stack size that is higher than its limit, which is the case when items are taken out of a basket. 
+     * The given ItemStack may have a stack size that is higher than its limit, which is the case when items are taken out of a basket.
      */
-    public void insertItem(ItemStack stackToAdd, boolean useHotbarOffset) {
-    	// In the first stage we combine the given item with stacks that are already in the inventory
-    	// In the second stage we put the remaining items into empty slots
-        if (!player.getGamemode().canInteract()) return;
-    	for(int stage = 0; stage < 2; stage++) {
-        	for(int i=0; i < mainInventory.length; i++) {
-        		int slotId = useHotbarOffset ? (i + hotbarOffset) % mainInventory.length : i;
-
-                if (locked(slotId)) continue;
-
-        		ItemStack stackInSlot = mainInventory[slotId];
-        		
-        		if(stage == 0) {
-        			if(stackInSlot != null && stackInSlot.canStackWith(stackToAdd)) {
-            			int transferAmount = Math.min(stackToAdd.stackSize, stackInSlot.getMaxStackSize() - stackInSlot.stackSize);
-            			transferAmount = Math.min(transferAmount, stackToAdd.getMaxStackSize()); // When taking items out of a basket item stacks may have stack sizes higher than their limit
-            			
-            			if(transferAmount == 0) {
-            				continue;
-            			}
-        				stackInSlot.stackSize += transferAmount;
-        				stackToAdd.stackSize -= transferAmount;
-        				stackInSlot.animationsToGo = 5;
-        			}
-        		}else if(stage == 1) {
-            		if(stackInSlot == null) {
-            			int transferAmount = Math.min(stackToAdd.stackSize, stackToAdd.getMaxStackSize());
-            			
-            			mainInventory[slotId] = stackToAdd.copy();
-            			mainInventory[slotId].stackSize = transferAmount;
-            			mainInventory[slotId].animationsToGo = 5;
-            			
-            			stackToAdd.stackSize -= transferAmount;
-            			
-            		}
-        		}
-        		
-    			if(stackToAdd.stackSize <= 0) {
-    				return;
-    			}
-        	}
-    	}
-    }
-
-    public int setCurrentItem(ItemStack itemstack, boolean flag)
-    {
-        if (currentItemLocked()) return currentItem;
-    	if (!flag) return currentItem;
-    	
-    	if (itemstack.itemID < Blocks.blocksList.length)
-    	{
-    		if (Blocks.blocksList[itemstack.itemID].hasTag(BlockTags.NOT_IN_CREATIVE_MENU)) return currentItem;
-    	}
-    	else
-    	{
-    		if (Item.itemsList[itemstack.itemID].hasTag(ItemTags.NOT_IN_CREATIVE_MENU)) return currentItem;
-    	}
-    	
-    	for (int j = hotbarOffset; j < 9 + hotbarOffset; j++)
-    	{
-    		if (mainInventory[j] != null && mainInventory[j].itemID == itemstack.itemID) 
-			{
-    			currentItem = j;
-    			return currentItem;
-			}
-    	}
-    	
-        mainInventory[currentItem] = itemstack;
-        
-        return currentItem;
-    }
-
-    public void changeCurrentItem(int i)
-    {
-        if (currentItemLocked()) return;
-        if(i > 0)
-        {
-            i = 1;
+    public void insertItem(final @NotNull ItemStack stackToAdd, final boolean useHotbarOffset) {
+        // In the first stage we combine the given item with stacks that are already in the inventory
+        // In the second stage we put the remaining items into empty slots
+        if (!this.player.getGamemode().canInteract()) return;
+        for (int stage = 0; stage < 2; stage++) {
+            for (int i = 0; i < this.mainInventory.length; i++) {
+                final int slotId = useHotbarOffset ? (i + this.hotbarOffset) % this.mainInventory.length : i;
+
+                if (this.locked(slotId)) continue;
+
+                final @Nullable ItemStack stackInSlot = this.mainInventory[slotId];
+
+                if (stage == 0) {
+                    if (stackInSlot != null && stackInSlot.canStackWith(stackToAdd)) {
+                        int transferAmount = Math.min(stackToAdd.stackSize, stackInSlot.getMaxStackSize() - stackInSlot.stackSize);
+                        transferAmount = Math.min(transferAmount, stackToAdd.getMaxStackSize()); // When taking items out of a basket item stacks may have stack sizes higher than their limit
+
+                        if (transferAmount == 0) {
+                            continue;
+                        }
+                        stackInSlot.stackSize += transferAmount;
+                        stackToAdd.stackSize -= transferAmount;
+                        stackInSlot.animationsToGo = 5;
+                    }
+                } else if (stage == 1) {
+                    if (stackInSlot == null) {
+                        final int transferAmount = Math.min(stackToAdd.stackSize, stackToAdd.getMaxStackSize());
+
+                        final @NotNull ItemStack stackCopy = stackToAdd.copy();
+                        stackCopy.stackSize = transferAmount;
+                        stackCopy.animationsToGo = 5;
+                        this.mainInventory[slotId] = stackCopy;
+
+                        stackToAdd.stackSize -= transferAmount;
+                    }
+                }
+
+                if (stackToAdd.stackSize <= 0) {
+                    return;
+                }
+            }
         }
-        if(i < 0)
-        {
-            i = -1;
+    }
+
+    public void changeCurrentSlot(int offset) {
+        if (this.currentSlotLocked()) {
+            return;
+        }
+
+        if (offset > 0) {
+            offset = 1;
+        }
+        if (offset < 0) {
+            offset = -1;
+        }
+        this.currentSlot -= offset;
+
+        while (this.currentSlot < this.hotbarOffset) {
+            this.currentSlot += HOTBAR_SIZE;
+        }
+        while (this.currentSlot >= this.hotbarOffset + HOTBAR_SIZE) {
+            this.currentSlot -= HOTBAR_SIZE;
         }
-        for(currentItem -= i; currentItem < hotbarOffset; currentItem += 9) { }
-        for(; currentItem >= 9 + hotbarOffset; currentItem -= 9) { }
     }
 
-    public void decrementAnimations()
-    {
-        for(int slot = 0; slot < mainInventory.length; slot++)
-        {
-            if(mainInventory[slot] != null)
-            {
-                mainInventory[slot].updateAnimation(player.world, player, slot, currentItem == slot);
+    public void decrementAnimations() {
+        for (int i = 0; i < this.mainInventory.length; i++) {
+            final @Nullable ItemStack stack = this.mainInventory[i];
+            if (stack != null) {
+                stack.updateAnimation(this.player.world, this.player, i, this.currentSlot == i);
             }
         }
 
     }
 
-    public boolean consumeInventoryItem(int i)
-    {
-        int j = getInventorySlotContainItem(i);
-        if(j < 0)
-        {
+    public boolean consumeInventoryItem(final int itemId) {
+        final int slot = this.getFirstSlotContaining(itemId);
+        if (slot < 0) {
             return false;
         }
 
-    	if (player.getGamemode().consumeBlocks())
-        {
-    		if(--mainInventory[j].stackSize <= 0)
-    		{
-    			mainInventory[j] = null;
-    		}
+        if (this.player.getGamemode().hasBlockConsumption()) {
+            final @NotNull ItemStack stack = Objects.requireNonNull(this.mainInventory[slot]);
+
+            stack.stackSize--;
+            if (stack.stackSize <= 0) {
+                this.mainInventory[slot] = null;
+            }
         }
+
         return true;
     }
 
-    public boolean currentItemLocked() {
-        return player.getHeldObject() != null;
+    public boolean currentSlotLocked() {
+        return this.player.getHeldObject() != null;
     }
 
     @Override
-    public boolean locked(int index) {
-        return currentItemLocked() && index == currentItem;
+    public boolean locked(final int slot) {
+        return this.currentSlotLocked() && slot == this.currentSlot;
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
-    {
-        ItemStack aitemstack[] = mainInventory;
-        if(index >= mainInventory.length)
-        {
-            aitemstack = armorInventory;
-            index -= mainInventory.length;
+    public @Nullable ItemStack removeItem(int slot, final int takeAmount) {
+        @Nullable ItemStack @NotNull [] inventory = this.mainInventory;
+
+        if (slot >= MAIN_INVENTORY_SIZE) {
+            inventory = this.armorInventory;
+            slot -= MAIN_INVENTORY_SIZE;
         }
-        if(aitemstack[index] != null)
-        {
-            if(aitemstack[index].stackSize <= takeAmount)
-            {
-                ItemStack itemstack = aitemstack[index];
-                aitemstack[index] = null;
-                return itemstack;
+
+        final @Nullable ItemStack currentStack = inventory[slot];
+        if (currentStack != null) {
+            if (currentStack.stackSize <= takeAmount) {
+                inventory[slot] = null;
+                return currentStack;
             }
-            ItemStack itemstack1 = aitemstack[index].splitStack(takeAmount);
-            if(aitemstack[index].stackSize <= 0)
-            {
-                aitemstack[index] = null;
+            final @NotNull ItemStack otherHalf = currentStack.splitStack(takeAmount);
+            if (currentStack.stackSize <= 0) {
+                inventory[slot] = null;
             }
-            return itemstack1;
-        } else
-        {
+
+            return otherHalf;
+        } else {
             return null;
         }
     }
 
-    @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
-    {
-        ItemStack aitemstack[] = mainInventory;
-        if(index >= aitemstack.length)
-        {
-            index -= aitemstack.length;
-            aitemstack = armorInventory;
-        }
-        aitemstack[index] = itemstack;
-    }
+    public @NotNull ListTag save(final @NotNull ListTag parentTag) {
+        for (int i = 0; i < this.mainInventory.length; i++) {
+            final @Nullable ItemStack stack = this.mainInventory[i];
 
-    public float getStrVsBlock(@NotNull Block<?> block)
-    {
-        float f = 1.0F;
-        if(mainInventory[currentItem] != null)
-        {
-            f *= mainInventory[currentItem].getStrVsBlock(block);
-        }
-        return f;
-    }
-
-    public ListTag writeToNBT(ListTag nbttaglist)
-    {
-        for(int i = 0; i < mainInventory.length; i++)
-        {
-            if(mainInventory[i] != null)
-            {
-                CompoundTag nbttagcompound = new CompoundTag();
-                nbttagcompound.putByte("Slot", (byte)i);
-                mainInventory[i].writeToNBT(nbttagcompound);
-                nbttaglist.addTag(nbttagcompound);
+            if (stack != null) {
+                final @NotNull CompoundTag itemTag = new CompoundTag();
+
+                itemTag.putByte("Slot", (byte) i);
+                stack.writeToNBT(itemTag);
+                parentTag.addTag(itemTag);
             }
         }
 
-        for(int j = 0; j < armorInventory.length; j++)
-        {
-            if(armorInventory[j] != null)
-            {
-                CompoundTag nbttagcompound1 = new CompoundTag();
-                nbttagcompound1.putByte("Slot", (byte)(j + 100));
-                armorInventory[j].writeToNBT(nbttagcompound1);
-                nbttaglist.addTag(nbttagcompound1);
+        for (int i = 0; i < this.armorInventory.length; i++) {
+            final @Nullable ItemStack stack = this.armorInventory[i];
+
+            if (stack != null) {
+                final @NotNull CompoundTag itemTag = new CompoundTag();
+
+                itemTag.putByte("Slot", (byte) (i + NBT_ARMOR_SLOT_OFFSET));
+                stack.writeToNBT(itemTag);
+                parentTag.addTag(itemTag);
             }
         }
 
-        return nbttaglist;
+        return parentTag;
     }
 
-    public void readFromNBT(ListTag nbttaglist)
-    {
-        mainInventory = new ItemStack[36];
-        armorInventory = new ItemStack[4];
-        for(int i = 0; i < nbttaglist.tagCount(); i++)
-        {
-            CompoundTag nbttagcompound = (CompoundTag)nbttaglist.tagAt(i);
-            int j = nbttagcompound.getByte("Slot") & 0xff;
-            ItemStack itemstack = ItemStack.readItemStackFromNbt(nbttagcompound);
-            if(itemstack  == null)
-            {
+    public void load(final @NotNull ListTag parentTag) {
+        this.clear();
+
+        for (int i = 0; i < parentTag.tagCount(); i++) {
+            final @NotNull CompoundTag itemTag = (CompoundTag) parentTag.tagAt(i);
+            final int slot = itemTag.getByte("Slot") & 0xFF;
+            final @Nullable ItemStack stack = ItemStack.readItemStackFromNbt(itemTag);
+
+            if (stack == null) {
                 continue;
             }
-            if(j >= 0 && j < mainInventory.length)
-            {
-                mainInventory[j] = itemstack;
+            if (slot < MAIN_INVENTORY_SIZE) {
+                this.mainInventory[slot] = stack;
             }
-            if(j >= 100 && j < armorInventory.length + 100)
-            {
-                armorInventory[j - 100] = itemstack;
+            if (slot >= NBT_ARMOR_SLOT_OFFSET && slot < ARMOR_INVENTORY_SIZE + NBT_ARMOR_SLOT_OFFSET) {
+                this.armorInventory[slot - NBT_ARMOR_SLOT_OFFSET] = stack;
             }
         }
-
     }
 
-    @Override
-	public int getContainerSize()
-    {
-        return mainInventory.length + 4;
+    private void clear() {
+        Arrays.fill(this.mainInventory, null);
+        Arrays.fill(this.armorInventory, null);
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
-    {
-        ItemStack aitemstack[] = mainInventory;
-        if(index >= aitemstack.length)
-        {
-            index -= aitemstack.length;
-            aitemstack = armorInventory;
-        }
-        return aitemstack[index];
+    public int getContainerSize() {
+        return this.mainInventory.length + 4;
     }
 
     @Override
-	public String getNameTranslationKey()
-    {
+    public @NotNull String getNameTranslationKey() {
         return "container.inventory.name";
     }
 
     @Override
-	public int getMaxStackSize()
-    {
+    public int getMaxStackSize() {
         return 64;
     }
 
-    public int getDamageVsEntity(@NotNull Entity entity)
-    {
-        ItemStack itemstack = getItem(currentItem);
-        if(itemstack != null)
-        {
-            return itemstack.getDamageVsEntity(entity);
-        } else
-        {
-            return 1;
-        }
+    public @Nullable ItemStack armorItemInSlot(final @NotNull IArmorShape shape) {
+        return this.armorInventory[shape.getSlotIndex()];
     }
 
-    public boolean canHarvestBlock(Block<?> block)
-    {
-        if (block == null) return false;
-        if(block.getMaterial().isAlwaysDestroyable())
-        {
-            return true;
-        }
-        ItemStack itemstack = getItem(currentItem);
-        if(itemstack != null)
-        {
-            return itemstack.canHarvestBlock(player, block);
-        } else
-        {
-            return false;
+    public int getTotalArmorPoints() {
+        float armorDurability = 0.0f;
+        float maxDurability = 0.0f;
+
+        for (final @Nullable ItemStack stack : this.armorInventory) {
+            if (stack != null && stack.getItem() instanceof IArmorItem) {
+                final Item armor = stack.getItem();
+
+                maxDurability += armor.getMaxDamage();
+                armorDurability += armor.getMaxDamage() - stack.getMetadata();
+            }
         }
+
+        return (int) (20 * (armorDurability / maxDurability));
     }
 
-    public @Nullable ItemStack armorItemInSlot(@NotNull IArmorShape shape)
-    {
-        return armorInventory[shape.getSlotIndex()];
-    }
-
-    public int getTotalArmourPoints() {
-    	float armorDurability = 0.0f;
-    	float maxDurability = 0.0f;
-    	
-    	for(int armorPiece=0; armorPiece < armorInventory.length; armorPiece++) {
-    		ItemStack itemStack = armorInventory[armorPiece];
-    		if(itemStack != null && itemStack.getItem() instanceof IArmorItem) {
-                Item armor = itemStack.getItem();
-    			
-    			maxDurability += armor.getMaxDamage();
-    			armorDurability += armor.getMaxDamage() - itemStack.getMetadata();
-    		}
-    	}
-    	
-    	return (int) (20 * (armorDurability / maxDurability));
-    }
-
-    public void dropAllItems()
-    {
-        for(int i = 0; i < mainInventory.length; i++)
-        {
-            if(mainInventory[i] != null)
-            {
-                player.dropPlayerItemWithRandomChoice(mainInventory[i], true);
-                mainInventory[i] = null;
+    public void dropAllItems() {
+        for (int i = 0; i < this.mainInventory.length; i++) {
+            final @Nullable ItemStack stack = this.mainInventory[i];
+            if (stack != null) {
+                this.player.dropItem(stack, true);
+                this.mainInventory[i] = null;
             }
         }
 
-        for(int j = 0; j < armorInventory.length; j++)
-        {
-            if(armorInventory[j] != null)
-            {
-                player.dropPlayerItemWithRandomChoice(armorInventory[j], true);
-                armorInventory[j] = null;
+        for (int i = 0; i < ARMOR_INVENTORY_SIZE; i++) {
+            if (this.armorInventory[i] != null) {
+                this.player.dropItem(this.armorInventory[i], true);
+                this.armorInventory[i] = null;
             }
         }
-
     }
 
     @Override
-	public void setChanged()
-    {
-        inventoryChanged = true;
-    }
-
-    public void setHeldItemStack(ItemStack itemstack)
-    {
-        heldItem = itemstack;
-        if (itemstack != null && itemstack.stackSize <= 0) heldItem = null;
-        player.onItemStackChanged(itemstack);
-    }
-
-    public ItemStack getHeldItemStack()
-    {
-        return heldItem;
+    public void setChanged() {
+        // Do nothing
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
-    {
-        if(player.removed)
-        {
+    public boolean stillValid(final @NotNull Player player) {
+        if (this.player.removed) {
             return false;
         }
-        return entityplayer.distanceToSqr(player) <= 64D;
+
+        return player.distanceToSqr(this.player) <= 64D;
     }
 
-    public boolean func_28018_c(ItemStack itemstack)
-    {
-        for(int i = 0; i < armorInventory.length; i++)
-        {
-            if(armorInventory[i] != null && armorInventory[i].isStackEqual(itemstack))
-            {
+    public boolean containsItem(final @NotNull ItemStack stack) {
+        for (final @Nullable ItemStack inventoryStack : this.armorInventory) {
+            if (inventoryStack != null && inventoryStack.isStackEqual(stack)) {
                 return true;
             }
         }
 
-        for(int j = 0; j < mainInventory.length; j++)
-        {
-            if(mainInventory[j] != null && mainInventory[j].isStackEqual(itemstack))
-            {
+        for (final @Nullable ItemStack inventoryStack : this.mainInventory) {
+            if (inventoryStack != null && inventoryStack.isStackEqual(stack)) {
                 return true;
             }
         }
@@ -493,19 +413,19 @@ public class ContainerInventory
     }
 
     @Override
-    public void sortContainer() {
-        InventorySorter.sortInventory(mainInventory, 9, mainInventory.length - 1);
-    }
-	
-	public void transferAllContents(ContainerInventory inventory) {
-		for(int i=0; i < mainInventory.length; i++) {
-			this.mainInventory[i] = inventory.mainInventory[i];
-			inventory.mainInventory[i] = null;
-		}
-		
-		for(int i=0; i < armorInventory.length; i++) {
-			this.armorInventory[i] = inventory.armorInventory[i];
-			inventory.armorInventory[i] = null;
-		}
-	}
+    public void sort() {
+        InventorySorter.sortInventory(this.mainInventory, HOTBAR_SIZE, MAIN_INVENTORY_SIZE - 1);
+    }
+
+    public void transferAllContents(final @NotNull ContainerInventory inventory) {
+        for (int i = 0; i < this.mainInventory.length; i++) {
+            this.mainInventory[i] = inventory.mainInventory[i];
+            inventory.mainInventory[i] = null;
+        }
+
+        for (int i = 0; i < this.armorInventory.length; i++) {
+            this.armorInventory[i] = inventory.armorInventory[i];
+            inventory.armorInventory[i] = null;
+        }
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerResult.java b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerResult.java
index 8146062fd..296abceee 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerResult.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerResult.java
@@ -2,76 +2,70 @@ package net.minecraft.core.player.inventory.container;
 
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class ContainerResult
-    implements Container
-{
-    private ItemStack[] items;
+    implements Container {
+    private @Nullable ItemStack stack = null;
 
-    public ContainerResult()
-    {
-        items = new ItemStack[1];
-    }
+    public ContainerResult() { }
 
     @Override
-	public int getContainerSize()
-    {
+    public int getContainerSize() {
         return 1;
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
-    {
-        return items[index];
+    public @Nullable ItemStack getItem(final int slot) {
+        if (slot == 0) {
+            return this.stack;
+        }
+
+        return null;
     }
 
     @Override
-	public String getNameTranslationKey()
-    {
+    public @NotNull String getNameTranslationKey() {
         return "container.result.name";
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
-    {
-        if(items[index] != null)
-        {
-            ItemStack itemstack = items[index];
-            items[index] = null;
-            return itemstack;
-        } else
-        {
+    public @Nullable ItemStack removeItem(final int slot, final int takeAmount) {
+        if (this.stack != null) {
+            final @NotNull ItemStack currentStack = this.stack;
+            this.stack = null;
+            return currentStack;
+        } else {
             return null;
         }
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
-    {
-        items[index] = itemstack;
+    public void setItem(final int slot, final @Nullable ItemStack stack) {
+        if (slot == 0) {
+            this.stack = stack;
+        }
     }
 
 
     @Override
-	public int getMaxStackSize()
-    {
+    public int getMaxStackSize() {
         return 64;
     }
 
     @Override
-	public void setChanged()
-    {
+    public void setChanged() {
+        // Do nothing
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
-    {
+    public boolean stillValid(final @NotNull Player player) {
         return true;
     }
 
     @Override
-    public void sortContainer() {
+    public void sort() {
         // Do nothing
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerSimple.java b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerSimple.java
index 6986c5369..ece775fcc 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerSimple.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/container/ContainerSimple.java
@@ -3,95 +3,82 @@ package net.minecraft.core.player.inventory.container;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.player.inventory.InventorySorter;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class ContainerSimple
-    implements Container
-{
-    private String name;
-    private int size;
-    private ItemStack[] items;
-
-    public ContainerSimple(String name, int size)
-    {
+    implements Container {
+    private final @NotNull String name;
+    private final @Nullable ItemStack @NotNull [] items;
+
+    public ContainerSimple(final @NotNull String name, final int size) {
         this.name = name;
-        this.size = size;
-        items = new ItemStack[size];
+        this.items = new ItemStack[size];
     }
 
     @Override
-	public @Nullable ItemStack getItem(int index)
-    {
-        return items[index];
+    public @Nullable ItemStack getItem(final int slot) {
+        return this.items[slot];
     }
 
     @Override
-	public @Nullable ItemStack removeItem(int index, int takeAmount)
-    {
-        if(items[index] != null)
-        {
-            if(items[index].stackSize <= takeAmount)
-            {
-                ItemStack itemstack = items[index];
-                items[index] = null;
-                setChanged();
-                return itemstack;
+    public @Nullable ItemStack removeItem(final int slot, final int takeAmount) {
+        final @Nullable ItemStack stack = this.items[slot];
+
+        if (stack != null) {
+            if (stack.stackSize <= takeAmount) {
+                final @NotNull ItemStack currentStack = stack;
+                this.items[slot] = null;
+                return currentStack;
             }
-            ItemStack itemstack1 = items[index].splitStack(takeAmount);
-            if(items[index].stackSize <= 0)
-            {
-                items[index] = null;
+
+            final @NotNull ItemStack otherHalf = stack.splitStack(takeAmount);
+            if (stack.stackSize <= 0) {
+                this.items[slot] = null;
             }
-            setChanged();
-            return itemstack1;
-        } else
-        {
+
+            return otherHalf;
+        } else {
             return null;
         }
     }
 
     @Override
-	public void setItem(int index, @Nullable ItemStack itemstack)
-    {
-        items[index] = itemstack;
-        if(itemstack != null && itemstack.stackSize > getMaxStackSize())
-        {
-            itemstack.stackSize = getMaxStackSize();
+    public void setItem(final int slot, final @Nullable ItemStack stack) {
+        this.items[slot] = stack;
+
+        if (stack != null && stack.stackSize > this.getMaxStackSize()) {
+            stack.stackSize = this.getMaxStackSize();
         }
-        setChanged();
     }
 
     @Override
-	public int getContainerSize()
-    {
-        return size;
+    public int getContainerSize() {
+        return this.items.length;
     }
 
     @Override
-	public String getNameTranslationKey()
-    {
-        return name;
+    public @NotNull String getNameTranslationKey() {
+        return this.name;
     }
 
     @Override
-	public int getMaxStackSize()
-    {
+    public int getMaxStackSize() {
         return 64;
     }
 
     @Override
-	public void setChanged()
-    {
+    public void setChanged() {
+        // Do nothing
     }
 
     @Override
-	public boolean stillValid(Player entityplayer)
-    {
+    public boolean stillValid(@NotNull final Player player) {
         return true;
     }
 
     @Override
-    public void sortContainer() {
-        InventorySorter.sortInventory(items);
+    public void sort() {
+        InventorySorter.sortInventory(this.items);
     }
 }
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 ecf7d7cfb..001586e41 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
@@ -128,7 +128,7 @@ public abstract class MenuAbstract
 	 */
 	public ItemStack clicked(InventoryAction action, int[] args, Player player) {
 		if(action.requireCreative()) {
-			if(player.getGamemode().consumeBlocks()) {
+			if(player.getGamemode().hasBlockConsumption()) {
                 LOGGER.warn("Player {} used a creative inventory action but is not in creative mode!", player.username);
 				return null;
 			}
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java
index ef8021653..bb72be543 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java
@@ -19,17 +19,11 @@ public class MenuInventory extends MenuAbstract {
 
 	public ContainerCrafting craftSlots;
 	public Container resultSlots;
-	public boolean active;
 	public ContainerInventory inventory;
 
 	public MenuInventory(ContainerInventory inventory) {
-		this(inventory, true);
-	}
-
-	public MenuInventory(ContainerInventory inventory, boolean active) {
 		craftSlots = new ContainerCrafting(this, 2, 2);
 		resultSlots = new ContainerResult();
-		this.active = active;
 		this.inventory = inventory;
 		addSlot(new SlotResult(inventory.player, craftSlots, resultSlots, 0, 144, 36));
 		
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventoryCreative.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventoryCreative.java
index fa8af726c..c46bf0af7 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventoryCreative.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventoryCreative.java
@@ -24,15 +24,10 @@ public class MenuInventoryCreative extends MenuInventory
 	protected int creativeSlotsStart;
 	protected List<ItemStack> searchedItems = new ArrayList<ItemStack>();
 	public String searchText = "";
-	
+
 	public MenuInventoryCreative(ContainerInventory inventoryplayer)
 	{
-		this(inventoryplayer, true);
-	}
-	
-	public MenuInventoryCreative(ContainerInventory inventoryplayer, boolean isNotClientSide)
-	{
-		super(inventoryplayer, isNotClientSide);
+		super(inventoryplayer);
 		
 		creativeSlotsStart = this.slots.size();
 		
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/slot/Slot.java b/game/core/src/main/java/net/minecraft/core/player/inventory/slot/Slot.java
index 634b1363b..d994e9400 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/slot/Slot.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/slot/Slot.java
@@ -27,7 +27,7 @@ public class Slot
 
 	public void sortSlotInventory() {
 		if (this.container != null) {
-            this.container.sortContainer();
+            this.container.sort();
 		}
 	}
 
diff --git a/game/core/src/main/java/net/minecraft/core/util/collection/NamespaceID.java b/game/core/src/main/java/net/minecraft/core/util/collection/NamespaceID.java
index 01e0b0fa7..99568caf2 100644
--- a/game/core/src/main/java/net/minecraft/core/util/collection/NamespaceID.java
+++ b/game/core/src/main/java/net/minecraft/core/util/collection/NamespaceID.java
@@ -72,6 +72,10 @@ public final class NamespaceID implements Comparable<NamespaceID>, CharSequence,
         set(namespace, value);
     }
 
+    public NamespaceID(final @NotNull NamespaceID id) {
+        set(id.namespace(), id.value());
+    }
+
     @Override
     public @NotNull ObjectPool<NamespaceID> getPool() {
         return NamespaceID.POOL;
diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java b/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java
index 098e9bc10..bc8f0e509 100644
--- a/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java
+++ b/game/core/src/main/java/net/minecraft/core/util/helper/Direction.java
@@ -177,5 +177,45 @@ public enum Direction {
 		if (mob.xRot > 45) return DOWN;
 		return getHorizontalDirection(mob.yRot);
 	}
-	
+
+	//////////////////
+
+	public static @NotNull Direction[] rotXMap = new Direction[] {
+		Direction.DOWN, Direction.NORTH, Direction.UP, Direction.SOUTH,
+		Direction.UP, Direction.SOUTH, Direction.DOWN, Direction.NORTH,
+		Direction.NORTH, Direction.UP, Direction.SOUTH, Direction.DOWN,
+		Direction.SOUTH, Direction.DOWN, Direction.NORTH, Direction.UP,
+		Direction.WEST, Direction.WEST, Direction.WEST, Direction.WEST,
+		Direction.EAST, Direction.EAST, Direction.EAST, Direction.EAST,
+	};
+
+	public static @NotNull Direction rotateX(@NotNull Direction direction, int amount) {
+		return rotXMap[direction.getId() * 4 + (amount & 0b11)];
+	}
+
+	public static @NotNull Direction[] rotYMap = new Direction[] {
+		Direction.DOWN, Direction.DOWN, Direction.DOWN, Direction.DOWN,
+		Direction.UP, Direction.UP, Direction.UP, Direction.UP,
+		Direction.NORTH, Direction.WEST, Direction.SOUTH, Direction.EAST,
+		Direction.SOUTH, Direction.EAST, Direction.NORTH, Direction.WEST,
+		Direction.WEST, Direction.SOUTH, Direction.EAST, Direction.NORTH,
+		Direction.EAST, Direction.NORTH, Direction.WEST, Direction.SOUTH,
+	};
+
+	public static @NotNull Direction rotateY(@NotNull Direction direction, int amount) {
+		return rotYMap[direction.getId() * 4 + (amount & 0b11)];
+	}
+
+	public static @NotNull Direction[] rotZMap = new Direction[] {
+		Direction.DOWN, Direction.EAST, Direction.UP, Direction.WEST,
+		Direction.UP, Direction.WEST, Direction.DOWN, Direction.EAST,
+		Direction.NORTH, Direction.NORTH, Direction.NORTH, Direction.NORTH,
+		Direction.SOUTH, Direction.SOUTH, Direction.SOUTH, Direction.SOUTH,
+		Direction.WEST, Direction.DOWN, Direction.EAST, Direction.UP,
+		Direction.EAST, Direction.UP, Direction.WEST, Direction.DOWN,
+	};
+
+	public static @NotNull Direction rotateZ(@NotNull Direction direction, int amount) {
+		return rotZMap[direction.getId() * 4 + (amount & 0b11)];
+	}
 }
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 835fe200c..7bf468882 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
@@ -204,7 +204,7 @@ public final class SpawnerMobs {
         if (player.isPlayerSleeping()) {
             return false;
         }
-        if (player.getGamemode().isPlayerInvulnerable()) {
+        if (player.getGamemode().hasInvulnerablePlayer()) {
             return false;
         }
 
@@ -291,7 +291,7 @@ public final class SpawnerMobs {
             if (!player.isPlayerSleeping()) {
                 continue;
             }
-            if (player.getGamemode().isPlayerInvulnerable()) {
+            if (player.getGamemode().hasInvulnerablePlayer()) {
                 continue;
             }
 
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 f32271393..dc143df72 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
@@ -28,7 +28,25 @@ import java.util.*;
 public class Chunk {
     private static final Logger LOGGER = LogUtils.getLogger();
     public static final int CHUNK_SIZE_X = 16;
+    /**
+     * Bit mask to convert a world block X coordinate to a X block in chunk coordinate
+     */
+    public static final int CHUNK_MASK_X = 0xF;
+    /**
+     * Amount of bits to shift to convert a world block X coordinate to a chunk X coordinate
+     */
+    public static final int CHUNK_SHIFT_X = 4;
+
     public static final int CHUNK_SIZE_Z = 16;
+    /**
+     * Bit mask to convert a world block Z coordinate to a Z block in chunk coordinate
+     */
+    public static final int CHUNK_MASK_Z = 0xF;
+    /**
+     * Amount of bits to shift to convert a world block Z coordinate to a chunk Z coordinate
+     */
+    public static final int CHUNK_SHIFT_Z = 4;
+
     public static final int CHUNK_SECTIONS = 16;
     public static boolean isLit;
     public boolean isLoaded;
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/b173/DensityGeneratorOverworldB173.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/b173/DensityGeneratorOverworldB173.java
index 7c009e847..690fa335c 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/b173/DensityGeneratorOverworldB173.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/b173/DensityGeneratorOverworldB173.java
@@ -12,8 +12,8 @@ public class DensityGeneratorOverworldB173
 
     public DensityGeneratorOverworldB173(final @NotNull World world) {
         super(world,
-            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 0)),
-            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 16)),
+            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 0, ImprovedPerlinNoise.LegacyNoiseType.BETA)),
+            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 16, ImprovedPerlinNoise.LegacyNoiseType.BETA)),
             new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 8, 32)),
             new FractalNoise2D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 10, 48)),
             new FractalNoise2D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 58)),
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/retro/DensityGeneratorOverworldRetro.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/retro/DensityGeneratorOverworldRetro.java
index 64a4d79cd..b9133cd2b 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/retro/DensityGeneratorOverworldRetro.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/retro/DensityGeneratorOverworldRetro.java
@@ -11,8 +11,8 @@ public class DensityGeneratorOverworldRetro
     extends DensityGeneratorOverworld {
     public DensityGeneratorOverworldRetro(@NotNull World world) {
         super(world,
-            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 0)),
-            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 16)),
+            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 0, ImprovedPerlinNoise.LegacyNoiseType.ALPHA)),
+            new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 16, ImprovedPerlinNoise.LegacyNoiseType.ALPHA)),
             new FractalNoise3D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 8, 32)),
             new FractalNoise2D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 10, 48)),
             new FractalNoise2D<>(ImprovedPerlinNoise.genOctaves(world.getRandomSeed(), 16, 58)),
diff --git a/game/core/src/main/java/net/minecraft/core/world/noise/ImprovedPerlinNoise.java b/game/core/src/main/java/net/minecraft/core/world/noise/ImprovedPerlinNoise.java
index 954c6128b..e4bbccfef 100644
--- a/game/core/src/main/java/net/minecraft/core/world/noise/ImprovedPerlinNoise.java
+++ b/game/core/src/main/java/net/minecraft/core/world/noise/ImprovedPerlinNoise.java
@@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable;
 import org.joml.Vector2d;
 import org.joml.Vector2dc;
 
-import java.util.Arrays;
 import java.util.Random;
 
 // Derived from Ken Perlin's Improved Noise reference implementation: https://cs.nyu.edu/~perlin/noise/
@@ -41,16 +40,18 @@ public class ImprovedPerlinNoise
     }
 
     public enum LegacyNoiseType {
-        DEFAULT(true, true),
-        ALPHA(false, false),
-        BETA(true, false);
+        DEFAULT(true, true, false),
+        ALPHA(false, false, true),
+        BETA(true, false, true);
 
         public final boolean handleEdgeCaseY;
         public final boolean handleEdgeCaseZ;
+        public final boolean doFarLands;
 
-        LegacyNoiseType(final boolean handleEdgeCaseY, final boolean handleEdgeCaseZ) {
+        LegacyNoiseType(final boolean handleEdgeCaseY, final boolean handleEdgeCaseZ, final boolean doFarLands) {
             this.handleEdgeCaseY = handleEdgeCaseY;
             this.handleEdgeCaseZ = handleEdgeCaseZ;
+            this.doFarLands = doFarLands;
         }
     }
 
@@ -108,14 +109,14 @@ public class ImprovedPerlinNoise
     @Override
     public double getValue(double x, double y, double z) {
         // Find unit cube that contains point
-        final int X = (int) Math.floor(x) & 255;
-        final int Y = (int) Math.floor(y) & 255;
-        final int Z = (int) Math.floor(z) & 255;
+        final int X = (int) this.fastFloor(x) & 255;
+        final int Y = (int) this.fastFloor(y) & 255;
+        final int Z = (int) this.fastFloor(z) & 255;
 
         // Find relative XYZ of point in cube
-        x -= Math.floor(x);
-        y -= Math.floor(y);
-        z -= Math.floor(z);
+        x -= this.fastFloor(x);
+        y -= this.fastFloor(y);
+        z -= this.fastFloor(z);
 
         // Compute fade curves for each of X, Y, and Z
         final double u = this.fade(x);
@@ -161,7 +162,7 @@ public class ImprovedPerlinNoise
         );
     }
 
-    protected double grad2(final int hash, final double x, final double y) {
+    private double grad2(final int hash, final double x, final double y) {
         final int h = hash & 15;
         final double u = (double) (1 - ((h & 8) >> 3)) * x;
         final double v = h < 4 ? 0.0D : h == 12 || h == 14 ? x : y;
@@ -169,15 +170,15 @@ public class ImprovedPerlinNoise
         return ((h & 1) != 0 ? -u : u) + ((h & 2) != 0 ? -v : v);
     }
 
-    protected double fade(final double t) {
+    private double fade(final double t) {
         return t * t * t * (t * (t * 6 - 15) + 10);
     }
 
-    protected double lerp(final double t, final double a, final double b) {
+    private double lerp(final double t, final double a, final double b) {
         return a + t * (b - a);
     }
 
-    protected double grad(final int hash, final double x, final double y, final double z) {
+    private double grad(final int hash, final double x, final double y, final double z) {
         // Converts low 4 bits of hash code into 12 gradient directions.
         final int h = hash & 15;
         final double u = h < 8 ? x : y;
@@ -186,6 +187,19 @@ public class ImprovedPerlinNoise
         return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
     }
 
+    private double fastFloor(final double value) {
+        if (this.legacyNoiseType.doFarLands) {
+            int intComponent = (int) value;
+            if (value < intComponent) {
+                intComponent--;
+            }
+
+            return intComponent;
+        } else {
+            return Math.floor(value);
+        }
+    }
+
     @Override
     public double @NotNull [] addRegion(
         final double @Nullable [] out,
@@ -215,10 +229,10 @@ public class ImprovedPerlinNoise
                 double xx = (x + xi) * xScale + this.xo;
 
                 // Find X coordinate of unit square that contains point
-                final int X = (int) Math.floor(xx) & 255;
+                final int X = (int) this.fastFloor(xx) & 255;
 
                 // Find relative X of point in square
-                xx -= Math.floor(xx);
+                xx -= this.fastFloor(xx);
 
                 // Compute fade curve for X
                 final double u = this.fade(xx);
@@ -227,10 +241,10 @@ public class ImprovedPerlinNoise
                     double zz = (z + zi) * zScale + this.zo;
 
                     // Find Z coordinate of unit square that contains point
-                    final int Z = (int) Math.floor(zz) & 255;
+                    final int Z = (int) this.fastFloor(zz) & 255;
 
                     // Find relative Z of point in square
-                    zz -= Math.floor(zz);
+                    zz -= this.fastFloor(zz);
 
                     // Compute fade curve for Z
                     final double w = this.fade(zz);
@@ -265,10 +279,10 @@ public class ImprovedPerlinNoise
                 double xx = (x + xi) * xScale + this.xo;
 
                 // Find X coordinate of unit square that contains point
-                final int X = (int) Math.floor(xx) & 255;
+                final int X = (int) this.fastFloor(xx) & 255;
 
                 // Find relative X of point in square
-                xx -= Math.floor(xx);
+                xx -= this.fastFloor(xx);
 
                 // Compute fade curve for X
                 final double u = this.fade(xx);
@@ -277,10 +291,10 @@ public class ImprovedPerlinNoise
                     double yy = (y + yi) * yScale + this.zo;
 
                     // Find Y coordinate of unit square that contains point
-                    final int Y = (int) Math.floor(yy) & 255;
+                    final int Y = (int) this.fastFloor(yy) & 255;
 
                     // Find relative Y of point in cube
-                    yy -= Math.floor(yy);
+                    yy -= this.fastFloor(yy);
 
                     // Compute fade curve for Y
                     final double v = this.fade(yy);
@@ -321,10 +335,10 @@ public class ImprovedPerlinNoise
                 double xx = (x + xi) * xScale + this.xo;
 
                 // Find X coordinate of unit cube that contains point
-                final int X = (int) Math.floor(xx) & 255;
+                final int X = (int) this.fastFloor(xx) & 255;
 
                 // Find relative X of point in cube
-                xx -= Math.floor(xx);
+                xx -= this.fastFloor(xx);
 
                 // Compute fade curve for X
                 final double u = this.fade(xx);
@@ -333,10 +347,10 @@ public class ImprovedPerlinNoise
                     double zz = (z + zi) * zScale + this.zo;
 
                     // Find Z coordinate of unit cube that contains point
-                    final int Z = (int) Math.floor(zz) & 255;
+                    final int Z = (int) this.fastFloor(zz) & 255;
 
                     // Find relative Z of point in cube
-                    zz -= Math.floor(zz);
+                    zz -= this.fastFloor(zz);
 
                     // Compute fade curve for Z
                     final double w = this.fade(zz);
@@ -345,10 +359,10 @@ public class ImprovedPerlinNoise
                         double yy = (y + yi) * yScale + this.yo;
 
                         // Find Y coordinate of unit cube that contains point
-                        final int Y = (int) Math.floor(yy) & 255;
+                        final int Y = (int) this.fastFloor(yy) & 255;
 
                         // Find relative Y of point in cube
-                        yy -= Math.floor(yy);
+                        yy -= this.fastFloor(yy);
 
                         // Compute fade curve for Y
                         final double v = this.fade(yy);
diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
index 3d556c9ae..8fbb56fd2 100644
--- a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
+++ b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
@@ -30,9 +30,13 @@ public final class ChunkPos implements Externalizable, Cloneable, ChunkPosc {
 
     public ChunkPos(final @NotNull TilePosc tilePos) {
         this(
-            Math.floorDiv(tilePos.x(), Chunk.CHUNK_SIZE_X),
-            Math.floorDiv(tilePos.z(), Chunk.CHUNK_SIZE_Z)
+            tilePos.x() >> Chunk.CHUNK_SHIFT_X,
+            tilePos.z() >> Chunk.CHUNK_SHIFT_Z
         );
+//        this(
+//            Math.floorDiv(tilePos.x(), Chunk.CHUNK_SIZE_X),
+//            Math.floorDiv(tilePos.z(), Chunk.CHUNK_SIZE_Z)
+//        );
     }
 
     public ChunkPos(final @NotNull ChunkPosc chunkPos) {
diff --git a/game/core/src/main/java/net/minecraft/core/world/saveddata/maps/ItemMapSavedData.java b/game/core/src/main/java/net/minecraft/core/world/saveddata/maps/ItemMapSavedData.java
index 5ae8eb4ec..e90dcfe49 100644
--- a/game/core/src/main/java/net/minecraft/core/world/saveddata/maps/ItemMapSavedData.java
+++ b/game/core/src/main/java/net/minecraft/core/world/saveddata/maps/ItemMapSavedData.java
@@ -8,7 +8,6 @@ import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.tags.ListTag;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.chunk.ChunkPosition;
 import net.minecraft.core.world.saveddata.SavedData;
 import org.jetbrains.annotations.NotNull;
 
@@ -131,7 +130,7 @@ public class ItemMapSavedData extends SavedData
         for(int i = 0; i < carriedBy.size(); i++)
         {
             HoldingPlayer mapinfo1 = carriedBy.get(i);
-            if(mapinfo1.player.removed || !mapinfo1.player.inventory.func_28018_c(stack))
+            if(mapinfo1.player.removed || !mapinfo1.player.inventory.containsItem(stack))
             {
                 carriedByPlayers.remove(mapinfo1.player);
                 carriedBy.remove(mapinfo1);
diff --git a/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java b/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
index 2b4340dc8..a6c0f008d 100644
--- a/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
+++ b/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
@@ -3,12 +3,12 @@ package net.minecraft.core.world.settings;
 import net.minecraft.core.data.gamerule.GameRuleCollection;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.ChatAllowedCharacters;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.save.ISaveFormat;
 import net.minecraft.core.world.type.WorldTypeGroups;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import java.util.Random;
 
@@ -17,7 +17,7 @@ public class WorldConfiguration {
     private long numericSeed = new Random().nextLong();
     private @NotNull String stringSeed = "";
     private boolean cheatsEnabled = false;
-    private @NotNull Gamemode gamemode = Gamemode.survival;
+    private @NotNull Gamemode gamemode = Gamemodes.SURVIVAL;
     private @NotNull WorldTypeGroups.Group worldTypeGroup = WorldTypeGroups.DEFAULT;
     private final @NotNull GameRuleCollection gameRuleCollection = new GameRuleCollection();
 
diff --git a/game/server/src/main/java/net/minecraft/server/MinecraftServer.java b/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
index a845432f5..30570490f 100644
--- a/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -55,6 +55,7 @@ import net.minecraft.core.net.command.commands.CommandTestFor;
 import net.minecraft.core.net.command.commands.CommandTime;
 import net.minecraft.core.net.command.commands.CommandWeather;
 import net.minecraft.core.net.command.util.CommandHelper;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.pool.ObjectPool;
 import net.minecraft.core.util.helper.UUIDHelper;
 import net.minecraft.core.world.pos.TilePos;
@@ -69,7 +70,6 @@ import net.minecraft.core.util.helper.RestHandler;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
-import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.IChunkLoader;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
 import net.minecraft.core.world.save.ISaveConverter;
@@ -108,6 +108,7 @@ import net.minecraft.server.world.WorldManager;
 import net.minecraft.server.world.WorldServer;
 import net.minecraft.server.world.WorldServerMulti;
 import net.minecraft.server.world.chunk.provider.ChunkProviderServer;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
@@ -119,10 +120,7 @@ import java.io.InputStreamReader;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
 
 import static net.minecraft.core.Global.CURRENT_SAVE_VERSION;
 import static net.minecraft.core.Global.isServer;
@@ -281,21 +279,12 @@ public class MinecraftServer
         EntityItem.enableItemClumping = propertyManager.getBooleanProperty("enable-item-clumping", true);
         UUIDHelper.urlUUID = propertyManager.getStringProperty("uuid-service", "https://api.minecraftservices.com/minecraft/profile/lookup/name/%s");
 
-        String gamemodeProperty = propertyManager.getStringProperty("default-gamemode", "survival");
-        defaultGamemode = null;
-        for (Gamemode gamemode : Gamemode.gamemodesList){
-            if (gamemode.getLanguageKey().replace("gamemode.", "").equals(gamemodeProperty)){
-                defaultGamemode = gamemode;
-                break;
-            }
-        }
-        if (defaultGamemode == null){
-            try{
-                defaultGamemode = Gamemode.gamemodesList[Integer.parseInt(gamemodeProperty)];
-            } catch (Exception e){
-                defaultGamemode = Gamemode.survival;
-            }
+        String gamemodeProperty = propertyManager.getStringProperty("default-gamemode", "minecraft:gamemode/survival");
+        final @Nullable Gamemode gamemodeFromProperty = Registries.GAMEMODES.getItem(gamemodeProperty);
+        if (gamemodeFromProperty == null) {
+            LOGGER.warn("Unrecognised gamemode \"" + gamemodeProperty + "\"! Gamemodes must be in namespace ID format, e.g. \"minecraft:gamemode/survival\".");
         }
+        this.defaultGamemode = Objects.requireNonNullElse(gamemodeFromProperty, Gamemodes.SURVIVAL);
 
         if (defaultWorldType == null)
         {
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 3fbab845a..5ae372bd0 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
@@ -99,19 +99,19 @@ public class PlayerServer extends Player implements ContainerListener {
         mcServer.playerList.sendPacketToAllPlayers(new PacketPlayerGamemode(this.id, gamemode.getId()));
         this.gamemode = gamemode;
 
-        MenuInventory newContainer = gamemode.getContainer(this.inventory, !world.isClientSide);
+        MenuInventory newContainer = gamemode.getInventoryMenu(this.inventory);
         if (craftingInventory == inventorySlots)
         {
             craftingInventory = newContainer;
         }
         inventorySlots = newContainer;
         inventorySlots.addSlotListener(this);
-        if (!gamemode.canPlayerFly())
+        if (!gamemode.hasPlayerFlight())
         {
             noPhysics = false;
         }
 
-        fireImmune = gamemode.isImmuneToFire();
+        fireImmune = gamemode.hasFireImmunity();
     }
 
     @Override
@@ -306,7 +306,7 @@ public class PlayerServer extends Player implements ContainerListener {
                 else
                 {
                     timeInPortal += 0.0125F;
-                    if (timeInPortal >= 1.0F || getGamemode().instantPortalTravel())
+                    if (timeInPortal >= 1.0F || getGamemode().hasInstantPortalTravel())
                     {
                         timeInPortal = 1.0F;
                         timeUntilPortal = 10;
@@ -642,11 +642,6 @@ public class PlayerServer extends Player implements ContainerListener {
         playerNetServerHandler.sendPacket(new PacketContainerSetData(container.containerId, id, value));
     }
 
-    @Override
-	public void onItemStackChanged(ItemStack itemstack)
-    {
-    }
-
     public void usePersonalCraftingInventory()
     {
         playerNetServerHandler.sendPacket(new PacketContainerClose(craftingInventory.containerId));
@@ -751,7 +746,7 @@ public class PlayerServer extends Player implements ContainerListener {
 
         // Ensure slot is definitely synced
         playerNetServerHandler.sendPacket(new PacketSetHotbarOffset(inventory.getHotbarOffset()));
-        playerNetServerHandler.sendPacket(new PacketSetCarriedItem(inventory.getCurrentItemIndex()));
+        playerNetServerHandler.sendPacket(new PacketSetCarriedItem(inventory.getCurrentSlot()));
     }
 
     @Override
diff --git a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
index 24883401e..71d88812f 100644
--- a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
+++ b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
@@ -225,7 +225,7 @@ public class PacketHandlerLogin extends PacketHandler
             player.playerNetServerHandler.sendPacket(new PacketCommandManager(this.mcServer.getDimensionWorld(player.dimension).getCommandManager().getDispatcher(), new ServerCommandSource(this.mcServer, player), "", 0));
             player.playerNetServerHandler.sendPacket(new PacketSetHeldObject(player.id, player.getHeldObject()));
             player.playerNetServerHandler.sendPacket(new PacketSetHotbarOffset(player.inventory.getHotbarOffset()));
-            player.playerNetServerHandler.sendPacket(new PacketSetCarriedItem(player.inventory.getCurrentItemIndex()));
+            player.playerNetServerHandler.sendPacket(new PacketSetCarriedItem(player.inventory.getCurrentSlot()));
         }
         finishedProcessing = true;
     }
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 6a56aba7f..e9ffef8a7 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
@@ -19,13 +19,13 @@ import net.minecraft.core.net.ChatEmotes;
 import net.minecraft.core.net.ICommandListener;
 import net.minecraft.core.net.NetworkManager;
 import net.minecraft.core.net.command.TextFormatting;
+import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.player.inventory.container.ContainerInventory;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.server.net.command.ServerCommandSource;
 import net.minecraft.core.net.handler.PacketHandler;
 import net.minecraft.core.net.packet.*;
-import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.player.inventory.menu.MenuFlag;
 import net.minecraft.core.player.inventory.menu.MenuInventoryCreative;
 import net.minecraft.core.player.inventory.slot.Slot;
@@ -43,7 +43,6 @@ import org.jetbrains.annotations.NotNull;
 import org.joml.Vector3d;
 import org.joml.Vector3dc;
 import org.joml.primitives.AABBd;
-import org.joml.primitives.AABBdc;
 import org.slf4j.Logger;
 
 import java.nio.charset.StandardCharsets;
@@ -105,7 +104,7 @@ public class PacketHandlerServer extends PacketHandler
     @Override
     public void handleSetMobSpawner(@NotNull PacketSetMobSpawner packet) {
         WorldServer world = this.mcServer.getDimensionWorld(this.playerEntity.dimension);
-        if (this.playerEntity.getGamemode() == Gamemode.creative && world.isBlockLoaded(packet.tilePos)) {
+        if (this.playerEntity.getGamemode() == Gamemodes.CREATIVE && world.isBlockLoaded(packet.tilePos)) {
             TileEntity tileentity = world.getTileEntity(packet.tilePos);
             if (tileentity instanceof TileEntityMobSpawner spawner) {
                 spawner.setMobId(packet.dispatcherEntry == null ? "none" : packet.dispatcherEntry.stringID);
@@ -234,7 +233,7 @@ public class PacketHandlerServer extends PacketHandler
         velSquared = dx * dx + ndy * ndy + dz * dz;
         boolean movedWrong = false;
         // TODO: Check if the player is flying instead of if they can fly, this information should be synced as in BTA flying is more than just no gravity
-        if (this.playerEntity.pushTime < 0.1f && !this.playerEntity.getGamemode().canPlayerFly() && velSquared > 0.0625D && !this.playerEntity.isPlayerSleeping()) {
+        if (this.playerEntity.pushTime < 0.1f && !this.playerEntity.getGamemode().hasPlayerFlight() && velSquared > 0.0625D && !this.playerEntity.isPlayerSleeping()) {
             movedWrong = true;
             LOGGER.warn("{} moved wrongly!", this.playerEntity.username);
             LOGGER.warn("Got position {}, {}, {}", newPosX, newPosY, newPosZ);
@@ -242,7 +241,7 @@ public class PacketHandlerServer extends PacketHandler
         }
         this.playerEntity.absMoveTo(newPosX, newPosY, newPosZ, yRot, xRot);
         boolean insideBlockNew = worldserver.getCubes(this.playerEntity, MathHelper.aabbInsetBoundingBox(this.playerEntity.bb, bb_expand, bb_expand, bb_expand, new AABBd())).isEmpty();
-        if (this.playerEntity.pushTime < 0.1f && !this.playerEntity.getGamemode().canPlayerFly() && insideBlockOld && (movedWrong || !insideBlockNew) && !this.playerEntity.isPlayerSleeping()) {
+        if (this.playerEntity.pushTime < 0.1f && !this.playerEntity.getGamemode().hasPlayerFlight() && insideBlockOld && (movedWrong || !insideBlockNew) && !this.playerEntity.isPlayerSleeping()) {
             // If the player:
             // - Is inside a block and wasn't on the last tick
             // - Moved wrongly
@@ -255,7 +254,7 @@ public class PacketHandlerServer extends PacketHandler
         // Falling and ground collision
         AABBd aabb = MathHelper.aabbGrow(this.playerEntity.bb, bb_expand, bb_expand, bb_expand, new AABBd());
         MathHelper.aabbExpand(aabb, 0.0D, -0.55D, 0.0D, aabb);
-        if (!this.playerEntity.getGamemode().canPlayerFly() && !this.mcServer.allowFlight && !worldserver.getIsAnySolidGround(aabb)) {
+        if (!this.playerEntity.getGamemode().hasPlayerFlight() && !this.mcServer.allowFlight && !worldserver.getIsAnySolidGround(aabb)) {
             // Don't tick fly counter if they are falling
             if (dy > -0.03125D) {
                 this.playerInAirTime++;
@@ -429,15 +428,15 @@ public class PacketHandlerServer extends PacketHandler
         }
         itemstack = this.playerEntity.inventory.getCurrentItem();
         if (itemstack != null && itemstack.stackSize <= 0) {
-            this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.getCurrentItemIndex()] = null;
+            this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.getCurrentSlot()] = null;
         }
         this.playerEntity.isChangingQuantityOnly = true;
-        this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.getCurrentItemIndex()] = ItemStack.copyItemStack(this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.getCurrentItemIndex()]);
-        Slot slot = this.playerEntity.craftingInventory.getSlotFor(this.playerEntity.inventory, this.playerEntity.inventory.getCurrentItemIndex());
+        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();
         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.getCurrentItemIndex(), 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.craftingInventory.getClass().getSimpleName());
             return;
         }
         if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), packet.itemStack)) {
@@ -471,11 +470,11 @@ public class PacketHandlerServer extends PacketHandler
 
     @Override
     public void handleSetCarriedItem(@NotNull PacketSetCarriedItem packetSetCarriedItem) {
-        if (packetSetCarriedItem.id < 0 || packetSetCarriedItem.id > ContainerInventory.playerMainInventorySize()) {
+        if (packetSetCarriedItem.id < 0 || packetSetCarriedItem.id > ContainerInventory.MAIN_INVENTORY_SIZE) {
             LOGGER.warn("{} tried to set an invalid carried item", this.playerEntity.username);
         } else {
-            this.playerEntity.inventory.setCurrentItemIndex(packetSetCarriedItem.id, false);
-            if (packetSetCarriedItem.id != this.playerEntity.inventory.getCurrentItemIndex()) { // If client tried to set current item while locked then send a packet back attempting to resync them
+            this.playerEntity.inventory.setCurrentSlot(packetSetCarriedItem.id, false);
+            if (packetSetCarriedItem.id != this.playerEntity.inventory.getCurrentSlot()) { // If client tried to set current item while locked then send a packet back attempting to resync them
                 sendPacket(new PacketSetCarriedItem(packetSetCarriedItem.id));
             }
         }
diff --git a/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java b/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java
index bd853354b..d79dcb677 100644
--- a/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java
+++ b/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java
@@ -48,7 +48,7 @@ public class ServerPlayerController
     }
 
 	public void startMining(int x, int y, int z, Side side) {
-		if(!player.getGamemode().doBlockBreakingAnim()) {
+		if(!player.getGamemode().hasBlockBreakingAnimation()) {
 			mineBlock(x, y, z, side);
 			return;
 		}
@@ -127,7 +127,7 @@ public class ServerPlayerController
         		block.onBlockDestroyedByPlayer(thisWorld, x, y, z, side, meta, player, heldItem);
         	}
         }
-        if(flag && player.canHarvestBlock(Blocks.blocksList[id]) && player.getGamemode().dropBlockOnBreak())
+        if(flag && player.canHarvestBlock(Blocks.blocksList[id]) && player.getGamemode().hasItemDrops())
         {
             Blocks.blocksList[id].harvestBlock(thisWorld, player, x, y, z, meta, tileEntity);
             ((PlayerServer) player).playerNetServerHandler.sendPacket(new PacketBlockUpdate(x, y, z, thisWorld));
@@ -221,10 +221,10 @@ public class ServerPlayerController
         ItemStack itemstack1 = itemstack.useItemRightClick(world, entityplayer);
         if(itemstack1 != itemstack || itemstack1 != null && itemstack1.stackSize != i)
         {
-            entityplayer.inventory.mainInventory[entityplayer.inventory.getCurrentItemIndex()] = itemstack1;
+            entityplayer.inventory.mainInventory[entityplayer.inventory.getCurrentSlot()] = itemstack1;
             if(itemstack1.stackSize <= 0)
             {
-                entityplayer.inventory.mainInventory[entityplayer.inventory.getCurrentItemIndex()] = null;
+                entityplayer.inventory.mainInventory[entityplayer.inventory.getCurrentSlot()] = null;
             }
             return true;
         } else
diff --git a/util/nbt/src/main/java/com/mojang/nbt/tags/ListTag.java b/util/nbt/src/main/java/com/mojang/nbt/tags/ListTag.java
index b5d84173b..0b4ffe9f0 100644
--- a/util/nbt/src/main/java/com/mojang/nbt/tags/ListTag.java
+++ b/util/nbt/src/main/java/com/mojang/nbt/tags/ListTag.java
@@ -131,7 +131,7 @@ public class ListTag
         getValue().add(tag);
     }
 
-    public Tag<?> tagAt(int index)
+    public @NotNull Tag<?> tagAt(int index)
     {
         return getValue().get(index);
     }
