diff --git a/game/client/src/main/java/net/minecraft/client/option/GameSettings.java b/game/client/src/main/java/net/minecraft/client/option/GameSettings.java
index 5c89f61b9..8ea3fa761 100644
--- a/game/client/src/main/java/net/minecraft/client/option/GameSettings.java
+++ b/game/client/src/main/java/net/minecraft/client/option/GameSettings.java
@@ -236,10 +236,10 @@ public final class GameSettings {
                 return percent + "%";
             }
         }));
-    public static final @NotNull OptionFloat CLOUD_RENDER_DISTANCE = register(new OptionFloat("cloudRenderDistance", 1f)
+    public static final @NotNull OptionFloat CLOUD_RENDER_DISTANCE = register(new OptionFloat("cloudRenderDistance", 2f)
         .withDisplayStringProvider((mc, i18n, option) -> {
             int percent = MathHelper.round(option.value * 100.0f);
-            if (percent == 100) {
+            if (percent == 200) {
                 return i18n.translateKey("options.cloudRenderDistance.default");
             } else {
                 return percent + "%";
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 266ea7636..b1ca717e0 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
@@ -44,4 +44,8 @@ public abstract class BlockModel<T extends BlockLogic> {
     public boolean isRetro() {
         return Minecraft.getMinecraft().currentWorld != null && Minecraft.getMinecraft().currentWorld.getWorldType().hasTag(WorldTypeTags.RETRO);
     }
+
+    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/BlockModelDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelDispatcher.java
index b05d1763a..0627c4fa7 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
@@ -230,20 +230,12 @@ public final class BlockModelDispatcher
         addDispatch(new BlockModelGenericFullyRotatable<>(Blocks.BONESHALE,
                 loadDataModel("minecraft:block/bone_shale")));
 
-        addDispatch(new BlockModelFluid<>(Blocks.FLUID_WATER_FLOWING)
-            .onRenderLayer(1)
-            .setAllTextures("minecraft:block/water_flowing")
-            .setTex("minecraft:block/water_still", Side.TOP));
-        addDispatch(new BlockModelFluid<>(Blocks.FLUID_WATER_STILL)
-            .onRenderLayer(1)
-            .setTex("minecraft:block/water_still", Side.TOP, Side.BOTTOM)
-            .setTex("minecraft:block/water_flowing", Side.NORTH, Side.EAST, Side.SOUTH, Side.WEST));
-        addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_FLOWING)
-            .setAllTextures("minecraft:block/lava_flowing")
-            .setTex("minecraft:block/lava_still", Side.TOP));
-        addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_STILL)
-            .setTex("minecraft:block/lava_still", Side.TOP, Side.BOTTOM)
-            .setTex("minecraft:block/lava_flowing", Side.NORTH, Side.EAST, Side.SOUTH, Side.WEST));
+        addDispatch(new BlockModelFluid<>(Blocks.FLUID_WATER_FLOWING, "minecraft:block/water_still", "minecraft:block/water_flowing")
+            .onRenderLayer(1));
+        addDispatch(new BlockModelFluid<>(Blocks.FLUID_WATER_STILL, "minecraft:block/water_still", "minecraft:block/water_flowing")
+            .onRenderLayer(1));
+        addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_FLOWING, "minecraft:block/lava_still", "minecraft:block/lava_flowing"));
+        addDispatch(new BlockModelFluid<>(Blocks.FLUID_LAVA_STILL, "minecraft:block/lava_still", "minecraft:block/lava_flowing"));
 
         addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_OAK, loadDataModel("minecraft:block/log/oak")));
         addDispatch(new BlockModelGenericAxis<>(Blocks.LOG_PINE, loadDataModel("minecraft:block/log/pine")));
@@ -339,10 +331,10 @@ public final class BlockModelDispatcher
         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.RUBYGLASS, loadDataModel("minecraft:block/rubyglass/block")));
-        addDispatch(new BlockModelGeneric<>(Blocks.RUBYGLASS_PURE, loadDataModel("minecraft:block/rubyglass/block_pure")).forceCullSelf(true));
+        addDispatch(new BlockModelGeneric<>(Blocks.RUBYGLASS_COLUMN, loadDataModel("minecraft:block/rubyglass/column")));
+        addDispatch(new BlockModelGeneric<>(Blocks.RUBYGLASS_NODE, loadDataModel("minecraft:block/rubyglass/node")));
+        addDispatch(new BlockModelGeneric<>(Blocks.BLOCK_RUBYGLASS, loadDataModel("minecraft:block/rubyglass/block")).forceCullSelf(true));
         addDispatch(new BlockModelCrystalBud<>(Blocks.RUBYGLASS_SPROUT, loadDataModel("minecraft:block/rubyglass/sprout")));
-        addDispatch(new BlockModelGenericRubyglassBud<>(Blocks.RUBYGLASS_BUD));
         addDispatch(new BlockModelGeneric<>(Blocks.RUBYGLASS_CIRCUIT, loadDataModel("minecraft:block/rubyglass/circuit")));
 
         addDispatch(new BlockModelGeneric<>(Blocks.ORE_NETHERCOAL_NETHERRACK, loadDataModel("minecraft:block/ore/nethercoal/netherrack")));
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
index 1d7e5ed30..bae1ed67b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
@@ -3,23 +3,47 @@ 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.BlockLogicFluid;
+import net.minecraft.core.block.BlockLogicFluidFlowing;
+import net.minecraft.core.block.FluidWater;
 import net.minecraft.core.block.material.Material;
 import net.minecraft.core.block.material.Materials;
+import net.minecraft.core.util.helper.Color;
 import net.minecraft.core.util.helper.LightIndexHelper;
 import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
+import net.minecraft.core.world.type.tag.WorldTypeTags;
 import org.jetbrains.annotations.NotNull;
 import org.joml.Math;
 import org.joml.Vector3d;
 import org.joml.primitives.AABBdc;
 
+import java.util.Random;
+
 public class BlockModelFluid<T extends BlockLogicFluid> extends BlockModelStandard<T> {
-    public BlockModelFluid(Block<T> block) {
+    public final Random random = new Random();
+    public final IconCoordinate flowing;
+    public final IconCoordinate still;
+    public final IconCoordinate bubbles;
+
+    public BlockModelFluid(Block<T> block, @NotNull String still, @NotNull String flowing) {
         super(block);
+        this.still = TextureRegistry.getTexture(still);
+        this.flowing = TextureRegistry.getTexture(flowing);
+        this.bubbles = TextureRegistry.getTexture("minecraft:block/water_overlay_boiling");
+
+        if (block.getLogic() instanceof BlockLogicFluidFlowing) {
+            setAllTextures(this.flowing);
+            setTex(this.still, Side.TOP);
+        } else {
+            setTex(this.still, Side.TOP, Side.BOTTOM);
+            setTex(this.flowing, Side.NORTH, Side.EAST, Side.SOUTH, Side.WEST);
+        }
     }
 
     private final @NotNull Vector3d br = new Vector3d();
@@ -32,7 +56,8 @@ public class BlockModelFluid<T extends BlockLogicFluid> extends BlockModelStanda
 
     @Override
     public boolean render(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos) {
-        tessellator.setColor1i(BlockColorDispatcher.getInstance().getDispatch(this.block).getWorldColor(worldSource, tilePos, 0));
+        int color = BlockColorDispatcher.getInstance().getDispatch(this.block).getWorldColor(worldSource, tilePos, 0);
+        tessellator.setColor1i(color);
 
         TilePos queryPos = new TilePos();
         final int x = tilePos.x();
@@ -72,7 +97,7 @@ public class BlockModelFluid<T extends BlockLogicFluid> extends BlockModelStanda
             byte lightUp = this.block.getLightIndex(worldSource, tilePos.up(queryPos));
 
             tessellator.setLightmapCoord1i(LightIndexHelper.max(light, lightUp));
-            if (tex.namespaceId.toString().contains("_flowing")) {
+            if (tex == this.flowing) {
                 float cos = Math.cos(-rotation + Math.PI_OVER_2_f);
                 float sin = Math.sin(-rotation + Math.PI_OVER_2_f);
 
@@ -108,6 +133,49 @@ public class BlockModelFluid<T extends BlockLogicFluid> extends BlockModelStanda
                 tessellator.addVertexWithUV(x, (float) y + hs, z + 1, tex.getIconUMax(), tex.getIconVMax());
                 tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1, tex.getIconUMax(), tex.getIconVMin());
                 tessellator.addVertexWithUV(x + 1, (float) y + he, z, tex.getIconUMin(), tex.getIconVMin());
+
+                if (worldSource.getWorldType().hasTag(WorldTypeTags.NETHER) && this.block.getLogic().fluid instanceof FluidWater) {
+                    tessellator.setColorOpaque3i(
+                        ((Color.redFromInt(color) * 3) / 4) + (255/4),
+                        ((Color.greenFromInt(color) * 3) / 4) + (255/4),
+                        ((Color.blueFromInt(color) * 3) / 4) + (255/4));
+
+                    random.setSeed(getPositionalSeed(tilePos));
+
+                    switch (random.nextInt(4)) {
+                        case 0: {
+                            tessellator.addVertexWithUV(x, (float) y + h, z, this.bubbles.getIconUMin(), this.bubbles.getIconVMax());
+                            tessellator.addVertexWithUV(x, (float) y + hs, z + 1, this.bubbles.getIconUMax(), this.bubbles.getIconVMax());
+                            tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1, this.bubbles.getIconUMax(), this.bubbles.getIconVMin());
+                            tessellator.addVertexWithUV(x + 1, (float) y + he, z, this.bubbles.getIconUMin(), this.bubbles.getIconVMin());
+                            break;
+                        }
+                        case 1: {
+                            tessellator.addVertexWithUV(x, (float) y + h, z, this.bubbles.getIconUMin(), this.bubbles.getIconVMin());
+                            tessellator.addVertexWithUV(x, (float) y + hs, z + 1, this.bubbles.getIconUMin(), this.bubbles.getIconVMax());
+                            tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1, this.bubbles.getIconUMax(), this.bubbles.getIconVMax());
+                            tessellator.addVertexWithUV(x + 1, (float) y + he, z, this.bubbles.getIconUMax(), this.bubbles.getIconVMin());
+                            break;
+                        }
+                        case 2: {
+                            tessellator.addVertexWithUV(x, (float) y + h, z, this.bubbles.getIconUMax(), this.bubbles.getIconVMin());
+                            tessellator.addVertexWithUV(x, (float) y + hs, z + 1, this.bubbles.getIconUMin(), this.bubbles.getIconVMin());
+                            tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1, this.bubbles.getIconUMin(), this.bubbles.getIconVMax());
+                            tessellator.addVertexWithUV(x + 1, (float) y + he, z, this.bubbles.getIconUMax(), this.bubbles.getIconVMax());
+                            break;
+                        }
+                        case 3: {
+                            tessellator.addVertexWithUV(x, (float) y + h, z, this.bubbles.getIconUMax(), this.bubbles.getIconVMax());
+                            tessellator.addVertexWithUV(x, (float) y + hs, z + 1, this.bubbles.getIconUMax(), this.bubbles.getIconVMin());
+                            tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1, this.bubbles.getIconUMin(), this.bubbles.getIconVMin());
+                            tessellator.addVertexWithUV(x + 1, (float) y + he, z, this.bubbles.getIconUMin(), this.bubbles.getIconVMax());
+                            break;
+                        }
+                    }
+
+
+                    tessellator.setColor1i(color);
+                }
             }
 
         }
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
index a2f9296e2..f5eb59693 100644
--- 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
@@ -26,7 +26,5 @@ public class BlockModelGenericMatcher<T extends BlockLogic> extends BlockModelGe
         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/item/model/ItemModelDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelDispatcher.java
index d134b8853..546314a3c 100644
--- a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelDispatcher.java
@@ -424,8 +424,8 @@ public class ItemModelDispatcher extends Dispatcher<Item, ItemModel> {
 
         addDispatch(new ItemModelStandard(Items.FOOD_VENISON_RAW, "minecraft"));
         addDispatch(new ItemModelStandard(Items.FOOD_VENISON_COOKED, "minecraft"));
-        addDispatch(new ItemModelStandard(Items.RUBYGLASS_CRYSTAL_CRACKED, "minecraft"));
-        addDispatch(new ItemModelStandard(Items.RUBYGLASS_CRYSTAL_PURE, "minecraft"));
+        addDispatch(new ItemModelStandard(Items.RUBYGLASS_DUST, "minecraft"));
+        addDispatch(new ItemModelStandard(Items.RUBYGLASS_CRYSTAL, "minecraft"));
 
         addDispatch(new ItemModelStandard(Items.DOUGH, "minecraft"));
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleBubbleBoiling.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleBubbleBoiling.java
new file mode 100644
index 000000000..b36d3fe5f
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleBubbleBoiling.java
@@ -0,0 +1,69 @@
+package net.minecraft.client.render.particle;
+
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
+import net.minecraft.core.block.material.Materials;
+import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.pos.TilePos;
+import org.joml.primitives.AABBd;
+
+public class ParticleBubbleBoiling extends Particle {
+    private float sinTimer = 0;
+    private boolean isReversed = false;
+    private final boolean needsWater;
+//    private final AABBd aabbd = new AABBd();
+    private final TilePos qpos = new TilePos();
+
+    public ParticleBubbleBoiling(World world, double x, double y, double z, double xa, double ya, double za, boolean needsWater) {
+        super(world, x, y, z, xa, ya, za);
+        this.needsWater = needsWater;
+        this.rCol = 1.0F;
+        this.gCol = 1.0F;
+        this.bCol = 1.0F;
+        this.tex = TextureRegistry.getTexture("minecraft:particle/bubble_boiling");
+        this.size = this.size * (random.nextFloat() * 0.7F + 0.3F);
+        this.xd = xa * 0.2D + (Math.random() * 2D - 1.0D) * 0.02F;
+        this.yd = ya * 0.2D + (Math.random() * 2D - 1.0D) * 0.02F;
+        this.zd = za * 0.2D + (Math.random() * 2D - 1.0D) * 0.02F;
+        this.lifetime = (int) (16D / (Math.random() * 0.4D + 0.1D));
+
+        this.isReversed = random.nextInt(2) == 0;
+    }
+
+    @Override
+    public void tick() {
+        this.sinTimer++;
+        if (this.sinTimer > 100) {
+            this.sinTimer = 0;
+        }
+
+        this.cachedLightmapCoord = calcLightIndex(1f);
+        this.xo = this.x;
+        this.yo = this.y;
+        this.zo = this.z;
+        final double expand = 0.05;
+//        this.aabbd.setMin(this.x - expand, this.y - expand, this.z - expand).setMax(this.x + expand, this.y, this.z + expand);
+//        boolean inWater = this.world.isAABBInMaterial(this.qpos, Materials.WATER);
+        boolean inWater = this.world.getBlockMaterial(this.qpos.set((int) this.x, (int) (this.y), (int) this.z)) == Materials.WATER;
+        if (inWater) {
+            this.yd = 0.20D;
+
+            this.xd = ((MathHelper.sin(this.sinTimer * 0.95f)) / 30f) * (this.isReversed ? -1 : 1);
+            this.zd = ((MathHelper.cos(this.sinTimer * 0.95f)) / 30f) * (this.isReversed ? -1 : 1);
+        } else {
+            this.yd = MathHelper.clamp(this.yd, -0.05, 0.005);
+        }
+        this.move(this.xd, this.yd, this.zd);
+        this.xd *= 0.85D;
+        this.yd *= 0.85D;
+        this.zd *= 0.85D;
+        if (this.needsWater && !inWater) {
+            this.lifetime = MathHelper.clamp(this.lifetime, 0, 8);
+        }
+        if (this.lifetime-- <= 0) {
+            remove();
+            world.spawnParticle("smoke", x, y, z, 0.0D, 0.0D, 0.0D, 1);
+        }
+    }
+
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java
index ec06a71e3..955c11139 100644
--- a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java
@@ -50,6 +50,12 @@ public final class ParticleDispatcher extends Dispatcher<String, ParticleEntry>
                 return new ParticleBubble(world, x, y, z, motionX, motionY, motionZ, true);
             }
         });
+        addDispatch("bubbleboiling", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleBubbleBoiling(world, x, y, z, motionX, motionY, motionZ, true);
+            }
+        });
         addDispatch("smoke", new ParticleEntry() {
             @Override
             public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java b/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java
index e4c1bf876..e7f023344 100644
--- a/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java
+++ b/game/client/src/main/java/net/minecraft/client/render/renderer/Shaders.java
@@ -25,7 +25,7 @@ public final class Shaders {
     public static final @NotNull Shader WORLD = register("world", new Shader());
     public static final @NotNull Shader AURORA = register("aurora", new Shader());
     public static final @NotNull Shader ENTITY = register("entity", new Shader());
-    public static final @NotNull Shader TERRAIN = register("terrain", new ShaderGeometry());
+    public static final @NotNull Shader TERRAIN = register("terrain", new Shader());
     public static final @NotNull Shader ITEM = register("item", new Shader());
     public static final @NotNull Shader INTERFACE = register("interface", new Shader());
     public static final @NotNull Shader COLOR = register("color", new Shader());
diff --git a/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTerrainImpl.java b/game/client/src/main/java/net/minecraft/client/render/tessellator/TessellatorTerrainImpl.java
index d898f2e42..b75834a5c 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
@@ -20,6 +20,7 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
 
 
     public final @NotNull TerrainVertexData data;
+    private final int vertSize;
 
     public boolean drawing;
 
@@ -43,6 +44,7 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
 
     public TessellatorTerrainImpl(final int bufferSize) {
         this.data = new TerrainVertexData(bufferSize);
+        this.vertSize = this.data.config.getVertexSize();
     }
 
     @Override
@@ -78,62 +80,27 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
     @Override
     public void addVertex(final double x, final double y, final double z) {
         this.checkIsDrawing();
+        this.data.resizeIfNeeded(256);
 
-        int index = this.quadVertCount % 4;
-        this.quadPoses[index * 3] = this.offsetX + x;
-        this.quadPoses[index * 3 + 1] = this.offsetY + y;
-        this.quadPoses[index * 3 + 2] = this.offsetZ + z;
+        var buffer = this.data.getBuffer();
 
-        this.quadColors[index] = this.color;
+        buffer.putFloat((float) (this.offsetX + x)).putFloat((float) (this.offsetY + y)).putFloat((float) (this.offsetZ + z));
+        buffer.put((byte) Color.blueFromInt(this.color)).put((byte) Color.greenFromInt(this.color)).put((byte) Color.redFromInt(this.color));
+        buffer.put(this.normalX).put(this.normalY).put(this.normalZ);
 
-        this.quadUVs[index * 2] = (float) this.textureU;
-        this.quadUVs[index * 2 + 1] = (float) this.textureV;
+        buffer.putFloat((float) this.textureU).putFloat((float) this.textureV);
+        buffer.put(this.shade).put(this.lightIndex);
 
-        this.quadLightMap[index] = this.lightIndex;
-        this.quadShade[index] = this.shade;
+        this.data.vertexCount++;
 
-        this.quadNormals[index * 3] = this.normalX;
-        this.quadNormals[index * 3 + 1] = this.normalY;
-        this.quadNormals[index * 3 + 2] = this.normalZ;
+        if ((this.quadVertCount & 0b11) == 2) {
+            buffer.put(buffer.position(), buffer, buffer.position() - this.vertSize * 3, this.vertSize);
+            buffer.put(buffer.position() + this.vertSize, buffer, buffer.position() - this.vertSize, this.vertSize);
+            buffer.position(buffer.position() + this.vertSize * 2);
+            this.data.vertexCount += 2;
+        }
 
         this.quadVertCount++;
-
-        if (index == 3) { // Emit compressed quad
-            this.data.resizeIfNeeded(128);
-            ByteBuffer buffer = this.data.getBuffer();
-
-            double spX = this.quadPoses[0];
-            double spY = this.quadPoses[1];
-            double spZ = this.quadPoses[2];
-
-            // Average normals for quad
-            byte nX = (byte) ((this.quadNormals[0] + this.quadNormals[3] + this.quadNormals[6] + this.quadNormals[9])/4);
-            byte nY = (byte) ((this.quadNormals[1] + this.quadNormals[4] + this.quadNormals[7] + this.quadNormals[10])/4);
-            byte nZ = (byte) ((this.quadNormals[2] + this.quadNormals[5] + this.quadNormals[8] + this.quadNormals[11])/4);
-
-            int color = this.quadColors[0];
-
-            buffer.putFloat((float) spX).putFloat((float) spY).putFloat((float) spZ);
-            buffer.put((byte) Color.blueFromInt(color)).put((byte) Color.greenFromInt(color)).put((byte) Color.redFromInt(color));
-            buffer.put(nX).put(nY).put(nZ);
-
-            buffer.putShort((short) (this.quadUVs[0] * 0xFFFF)).putShort((short) (this.quadUVs[1] * 0xFFFF));
-            buffer.put(this.quadShade[0]).put(this.quadLightMap[0]);
-
-            buffer.putShort(MathHelper.toHalfFloat((float) (this.quadPoses[3] - spX))).putShort(MathHelper.toHalfFloat((float) (this.quadPoses[4] - spY))).putShort(MathHelper.toHalfFloat((float) (this.quadPoses[5] - spZ)));
-            buffer.putShort((short) (this.quadUVs[2] * 0xFFFF)).putShort((short) (this.quadUVs[3] * 0xFFFF));
-            buffer.put(this.quadShade[1]).put(this.quadLightMap[1]);
-
-            buffer.putShort(MathHelper.toHalfFloat((float) (this.quadPoses[6] - spX))).putShort(MathHelper.toHalfFloat((float) (this.quadPoses[7] - spY))).putShort(MathHelper.toHalfFloat((float) (this.quadPoses[8] - spZ)));
-            buffer.putShort((short) (this.quadUVs[4] * 0xFFFF)).putShort((short) (this.quadUVs[5] * 0xFFFF));
-            buffer.put(this.quadShade[2]).put(this.quadLightMap[2]);
-
-            buffer.putShort(MathHelper.toHalfFloat((float) (this.quadPoses[9] - spX))).putShort(MathHelper.toHalfFloat((float) (this.quadPoses[10] - spY))).putShort(MathHelper.toHalfFloat((float) (this.quadPoses[11] - spZ)));
-            buffer.putShort((short) (this.quadUVs[6] * 0xFFFF)).putShort((short) (this.quadUVs[7] * 0xFFFF));
-            buffer.put(this.quadShade[3]).put(this.quadLightMap[3]);
-
-            this.data.vertexCount++;
-        }
     }
 
     @Override
@@ -204,11 +171,12 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
 
     private int getUncompressVertexSize() {
         int size = 0;
-        size += Float.BYTES * 3;
-        size += Byte.BYTES * 4;
-        size += Float.BYTES * 2;
-        size += Byte.BYTES;
-        size += Byte.BYTES * 3;
+        size += 3 * Float.BYTES; // Pos
+        size += 3; // Color
+        size += 3; // Normal
+
+        size += 2 * Float.BYTES; // UV
+        size += 2; // LightShade
         return size;
     }
 
@@ -228,7 +196,7 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
     public static class TerrainVertexConfig implements VertexConfig<TerrainVertexConfig> {
         @Override
         public @NotNull DrawMode drawMode() {
-            return DrawMode.POINTS;
+            return DrawMode.TRIANGLES;
         }
 
         public void enable(final int vao, final int vbo) {
@@ -237,24 +205,11 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
 
             final int vertexSize = this.getVertexSize();
             int offset = 0;
-            GL41.glVertexAttribPointer(0, 3, GL41.GL_FLOAT, false, vertexSize, offset); offset += 3 * Float.BYTES; // Source Pos
-            GL41.glVertexAttribPointer(1, 3, GL41.GL_UNSIGNED_BYTE, true, vertexSize, offset); offset += 3; // Source Color
-            GL41.glVertexAttribPointer(2, 3, GL41.GL_BYTE, true, vertexSize, offset); offset += 3; // Source Normal
-
-            GL41.glVertexAttribPointer(3, 2, GL41.GL_UNSIGNED_SHORT, true, vertexSize, offset); offset += 2 * Short.BYTES; // V1 UV
-            GL41.glVertexAttribPointer(4, 2, GL41.GL_UNSIGNED_BYTE, false, vertexSize, offset); offset += 2; // V1 LightShade
-
-            GL41.glVertexAttribPointer(5, 3, GL41.GL_HALF_FLOAT, false, vertexSize, offset); offset += 3 * (Float.BYTES/2); // V2 Pos Offset
-            GL41.glVertexAttribPointer(6, 2, GL41.GL_UNSIGNED_SHORT, true, vertexSize, offset); offset += 2 * Short.BYTES; // V2 UV
-            GL41.glVertexAttribPointer(7, 2, GL41.GL_UNSIGNED_BYTE, false, vertexSize, offset); offset += 2; // V2 LightShade
-
-            GL41.glVertexAttribPointer(8, 3, GL41.GL_HALF_FLOAT, false, vertexSize, offset); offset += 3 * (Float.BYTES/2); // V3 Pos Offset
-            GL41.glVertexAttribPointer(9, 2, GL41.GL_UNSIGNED_SHORT, true, vertexSize, offset); offset += 2 * Short.BYTES; // V3 UV
-            GL41.glVertexAttribPointer(10, 2, GL41.GL_UNSIGNED_BYTE, false, vertexSize, offset); offset += 2; // V3 LightShade
-
-            GL41.glVertexAttribPointer(11, 3, GL41.GL_HALF_FLOAT, false, vertexSize, offset); offset += 3 * (Float.BYTES/2); // V4 Pos Offset
-            GL41.glVertexAttribPointer(12, 2, GL41.GL_UNSIGNED_SHORT, true, vertexSize, offset); offset += 2 * Short.BYTES; // V4 UV
-            GL41.glVertexAttribPointer(13, 2, GL41.GL_UNSIGNED_BYTE, false, vertexSize, offset); offset += 2; // V4 LightShade
+            GL41.glVertexAttribPointer(0, 3, GL41.GL_FLOAT, false, vertexSize, offset); offset += 3 * Float.BYTES; // Pos
+            GL41.glVertexAttribPointer(1, 3, GL41.GL_UNSIGNED_BYTE, true, vertexSize, offset); offset += 3; // Color
+            GL41.glVertexAttribPointer(2, 3, GL41.GL_BYTE, true, vertexSize, offset); offset += 3; // Normal
+            GL41.glVertexAttribPointer(3, 2, GL41.GL_FLOAT, true, vertexSize, offset); offset += 2 * Float.BYTES; // UV
+            GL41.glVertexAttribPointer(4, 2, GL41.GL_UNSIGNED_BYTE, false, vertexSize, offset); offset += 2; // LightShade
 
             assert  offset == vertexSize;
 
@@ -263,15 +218,6 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
             GL41.glEnableVertexAttribArray(2);
             GL41.glEnableVertexAttribArray(3);
             GL41.glEnableVertexAttribArray(4);
-            GL41.glEnableVertexAttribArray(5);
-            GL41.glEnableVertexAttribArray(6);
-            GL41.glEnableVertexAttribArray(7);
-            GL41.glEnableVertexAttribArray(8);
-            GL41.glEnableVertexAttribArray(9);
-            GL41.glEnableVertexAttribArray(10);
-            GL41.glEnableVertexAttribArray(11);
-            GL41.glEnableVertexAttribArray(12);
-            GL41.glEnableVertexAttribArray(13);
         }
 
         public void disable() {
@@ -280,15 +226,6 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
             GL41.glDisableVertexAttribArray(2);
             GL41.glDisableVertexAttribArray(3);
             GL41.glDisableVertexAttribArray(4);
-            GL41.glDisableVertexAttribArray(5);
-            GL41.glDisableVertexAttribArray(6);
-            GL41.glDisableVertexAttribArray(7);
-            GL41.glDisableVertexAttribArray(8);
-            GL41.glDisableVertexAttribArray(9);
-            GL41.glDisableVertexAttribArray(10);
-            GL41.glDisableVertexAttribArray(11);
-            GL41.glDisableVertexAttribArray(12);
-            GL41.glDisableVertexAttribArray(13);
 
             GL41.glBindBuffer(GL41.GL_ARRAY_BUFFER, 0);
             GL41.glBindVertexArray(0);
@@ -296,24 +233,12 @@ public class TessellatorTerrainImpl implements TessellatorGeneral {
 
         public int getVertexSize() {
             int size = 0;
-            size += 3 * Float.BYTES; // Source Pos
-            size += 3; // Source Color
-            size += 3; // Source Normal
-
-            size += 2 * Short.BYTES; // V1 UV
-            size += 2; // V1 LightShade
-
-            size += 3 * (Float.BYTES/2); // V2 Pos Offset
-            size += 2 * Short.BYTES; // V2 UV
-            size += 2; // V2 LightShade
-
-            size += 3 * (Float.BYTES/2); // V3 Pos Offset
-            size += 2 * Short.BYTES; // V3 UV
-            size += 2; // V3 LightShade
+            size += 3 * Float.BYTES; // Pos
+            size += 3; // Color
+            size += 3; // Normal
 
-            size += 3 * (Float.BYTES/2); // V4 Pos Offset
-            size += 2 * Short.BYTES; // V4 UV
-            size += 2; // V4 LightShade
+            size += 2 * Float.BYTES; // UV
+            size += 2; // LightShade
             return size;
         }
 
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 e198d6534..2e0aec760 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
@@ -108,7 +108,7 @@ public class BlockModelMojangData implements BlockModelData {
         @NotNull final TexturePackList texturePackList,
         @NotNull final NamespaceID id,
         @Nullable final String parent,
-        final boolean ambientOcclusion,
+        final @Nullable Boolean ambientOcclusion,
         @Nullable final Integer renderLayer,
         @Nullable final Map<@NotNull String, @NotNull DisplayPos> displayPositions,
         @Nullable final Map<@NotNull String, @NotNull String> textures,
@@ -119,8 +119,8 @@ public class BlockModelMojangData implements BlockModelData {
         this.parent = parent;
         if (parent != null) {
             final BlockModelMojangData parentData = BlockModelMojangData.Cache.loadModelData(texturePackList, parent);
-            this.ambientOcclusion = ambientOcclusion;
             if (parentData != null) {
+                this.ambientOcclusion = ambientOcclusion == null ? parentData.ambientOcclusion : ambientOcclusion;
                 this.displayPositions = new HashMap<>();
                 this.textures = new HashMap<>();
                 this.particleIndices = new Object2IntArrayMap<>();
@@ -135,6 +135,7 @@ public class BlockModelMojangData implements BlockModelData {
                 if (parentData.particleIndices != null) this.particleIndices.putAll(parentData.particleIndices);
                 if (particleIndices != null) this.particleIndices.putAll(particleIndices);
             } else {
+                this.ambientOcclusion = ambientOcclusion == null ? DEFAULT_AMBIENT_OCCLUSION : ambientOcclusion;
                 this.displayPositions = displayPositions;
                 this.particleIndices = particleIndices;
                 this.renderLayer = renderLayer;
@@ -142,7 +143,7 @@ public class BlockModelMojangData implements BlockModelData {
                 this.elements = elements;
             }
         } else {
-            this.ambientOcclusion = ambientOcclusion;
+            this.ambientOcclusion = ambientOcclusion == null ? DEFAULT_AMBIENT_OCCLUSION : ambientOcclusion;
             this.displayPositions = displayPositions;
             this.particleIndices = particleIndices;
             this.renderLayer = renderLayer;
@@ -178,7 +179,7 @@ public class BlockModelMojangData implements BlockModelData {
     @SuppressWarnings("unused")
     public static class Builder {
         protected @Nullable String parent = DEFAULT_PARENT;
-        protected boolean ambientOcclusion = DEFAULT_AMBIENT_OCCLUSION;
+        protected @Nullable Boolean ambientOcclusion = null;
         protected @Nullable Integer renderLayer = null;
         protected @Nullable Map<@NotNull String, @NotNull DisplayPos> displayPosMap = null;
         protected @Nullable Map<@NotNull String, @NotNull String> textures = null;
@@ -190,7 +191,7 @@ public class BlockModelMojangData implements BlockModelData {
             return this;
         }
 
-        public @NotNull Builder setAO(final boolean ao) {
+        public @NotNull Builder setAO(final @Nullable Boolean ao) {
             this.ambientOcclusion = ao;
             return this;
         }
diff --git a/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java b/game/client/src/main/java/org/useless/dragonfly/models/block/mojang/StaticBlockModelMojang.java
index 6087bb80a..0b7b5cb8e 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
@@ -233,7 +233,7 @@ public class StaticBlockModelMojang implements StaticBlockModel {
                 }
 
                 final boolean useAO = this.compiled.data.ambientOcclusion && GameSettings.AMBIENT_OCCLUSION.value && element.shade;
-                final boolean isFullCube = depth <= FULL_CUBE_THRESHOLD && element.shade;
+                final boolean isFullCube = depth <= FULL_CUBE_THRESHOLD;
 
                 final float r;
                 final float g;
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/cube_lit.json b/game/client/src/main/resources/assets/minecraft/models/block/cube_lit.json
new file mode 100644
index 000000000..9b4d05645
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/cube_lit.json
@@ -0,0 +1,33 @@
+{
+  "ambientocclusion": false,
+  "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 ],
+      "shade": false,
+      "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" }
+      }
+    }
+  ]
+}
\ 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
index 64b05023d..64c9c341a 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/glowstone.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/glowstone.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/glowstone"
   }
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
index 59ecd8f95..fad84c23b 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/black_active"
   }
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
index 54e80ee1a..b74c7288e 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/blue_active"
   }
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
index c8bca46ba..6097b6169 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/brown_active"
   }
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
index cc3cbc1fe..5ed6902ef 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/cyan_active"
   }
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
index 0117404d6..fd210db14 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/gray_active"
   }
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
index 4cf59ad9e..2b1bef7c1 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/green_active"
   }
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
index 5bd09d21e..725068503 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/lightblue_active"
   }
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
index 6d2bcdf46..3643f57f6 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/lime_active"
   }
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
index 687949c1f..996f13c7b 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/magenta_active"
   }
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
index 258dcabd7..9278a0fec 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/orange_active"
   }
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
index fb9494a3d..f50b70888 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/pink_active"
   }
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
index e26cf943e..544163848 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/purple_active"
   }
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
index c5ddd68c3..9b0408436 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/red_active"
   }
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
index b76c188c9..35d0ed06b 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/silver_active"
   }
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
index 9c5d8ff91..73d928157 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/white_active"
   }
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
index 846dbbe52..b881cbd33 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/yellow_active"
   }
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
index 59ecd8f95..fad84c23b 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/black_active"
   }
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
index 54e80ee1a..b74c7288e 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/blue_active"
   }
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
index c8bca46ba..6097b6169 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/brown_active"
   }
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
index cc3cbc1fe..5ed6902ef 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/cyan_active"
   }
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
index 0117404d6..fd210db14 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/gray_active"
   }
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
index 4cf59ad9e..2b1bef7c1 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/green_active"
   }
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
index 5bd09d21e..725068503 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/lightblue_active"
   }
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
index 6d2bcdf46..3643f57f6 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/lime_active"
   }
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
index 687949c1f..996f13c7b 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/magenta_active"
   }
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
index 258dcabd7..9278a0fec 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/orange_active"
   }
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
index fb9494a3d..f50b70888 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/pink_active"
   }
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
index e26cf943e..544163848 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/purple_active"
   }
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
index c5ddd68c3..9b0408436 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/red_active"
   }
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
index b76c188c9..35d0ed06b 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/silver_active"
   }
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
index 9c5d8ff91..73d928157 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/white_active"
   }
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
index 846dbbe52..b881cbd33 100644
--- 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
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/cube_all",
+  "parent": "minecraft:block/cube_lit",
   "textures": {
     "all": "minecraft:block/lamp/yellow_active"
   }
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
index 9f8aa67c1..c9b3c3550 100644
--- 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
@@ -14,6 +14,7 @@
 	},
 	"elements": [
 		{
+            "light_emission": 15,
 			"from": [0, 0, 0],
 			"to": [16, 16, 16],
 			"faces": {
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/block.json b/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/block.json
index 8347c9b0c..6ae39a4d7 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/block.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/block.json
@@ -1,6 +1,7 @@
 {
-  "parent": "minecraft:block/tinted_cube_all",
+  "parent": "minecraft:block/cube_all",
+  "renderlayer": 1,
   "textures": {
-    "all": "minecraft:block/rubyglass/block"
+    "all": "minecraft:block/rubyglass/block_pure"
   }
 }
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/block_pure.json b/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/block_pure.json
deleted file mode 100644
index 09878b374..000000000
--- a/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/block_pure.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "parent": "minecraft:block/tinted_cube_all",
-  "renderlayer": 1,
-  "textures": {
-    "all": "minecraft:block/rubyglass/block_pure"
-  }
-}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/column.json b/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/column.json
new file mode 100644
index 000000000..61e5c9a68
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/column.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/cube_all",
+  "textures": {
+    "all": "minecraft:block/rubyglass/block"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/node.json b/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/node.json
new file mode 100644
index 000000000..cbf87e704
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/rubyglass/node.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/tinted_cube_all",
+  "textures": {
+    "all": "minecraft:block/rubyglass/node"
+  }
+}
\ 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
index ddb91caff..c5219626a 100644
--- 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
@@ -1,18 +1,24 @@
-{   "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" }
-            }
-        }
-    ]
-}
+{
+	"format_version": "1.21.11",
+	"credit": "Made with Blockbench",
+	"parent": "block/block_thin",
+	"textures": {
+		"particle": "block/trapdoor/steel/top",
+		"texture": "block/trapdoor/steel/top",
+		"side": "block/trapdoor/steel/side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 3, 16],
+			"faces": {
+				"north": {"uv": [16, 16, 0, 13], "rotation": 180, "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": "#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/trapdoor/glass/bottom.json b/game/client/src/main/resources/assets/minecraft/models/block/trapdoor/glass/bottom.json
index d4fc8d6ca..2c8f8b536 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/glass/top"
+    "texture": "minecraft:block/trapdoor/glass/top",
+    "side": "minecraft:block/trapdoor/glass/side"
   }
 }
\ 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
index c61fb150a..29780e055 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/glass/top"
+    "texture": "minecraft:block/trapdoor/glass/top",
+    "side": "minecraft:block/trapdoor/glass/side"
   }
 }
\ 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
index cd6052033..db8275f33 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/glass/top"
+    "texture": "minecraft:block/trapdoor/glass/top",
+    "side": "minecraft:block/trapdoor/glass/side"
   }
 }
\ 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
index 2521efc51..c5290d228 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/iron/top"
+    "texture": "minecraft:block/trapdoor/iron/top",
+    "side": "minecraft:block/trapdoor/iron/side"
   }
 }
\ 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
index 6ccf008a2..be4b7dcaf 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/iron/top"
+    "texture": "minecraft:block/trapdoor/iron/top",
+    "side": "minecraft:block/trapdoor/iron/side"
   }
 }
\ 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
index c2e8153a9..9ed5d3f6b 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/iron/top"
+    "texture": "minecraft:block/trapdoor/iron/top",
+    "side": "minecraft:block/trapdoor/iron/side"
   }
 }
\ 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
index b301619c2..2058f8dc2 100644
--- 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
@@ -1,18 +1,23 @@
 {
-    "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" }
-            }
-        }
-    ]
-}
+	"format_version": "1.21.11",
+	"credit": "Made with Blockbench",
+	"textures": {
+		"particle": "block/trapdoor/steel/top",
+		"texture": "block/trapdoor/steel/top",
+		"side": "block/trapdoor/steel/side"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 13],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#texture"},
+				"east": {"uv": [16, 13, 0, 16], "rotation": 90, "texture": "#side", "cullface": "east"},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#texture", "cullface": "south"},
+				"west": {"uv": [0, 16, 16, 13], "rotation": 90, "texture": "#side", "cullface": "west"},
+				"up": {"uv": [16, 13, 0, 16], "texture": "#side", "cullface": "up"},
+				"down": {"uv": [0, 16, 16, 13], "texture": "#side", "cullface": "down"}
+			}
+		}
+	]
+}
\ No newline at end of file
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
index 1bedfb69f..f0e48dc0a 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_black/top"
+    "texture": "minecraft:block/trapdoor/planks_black/top",
+    "side": "minecraft:block/trapdoor/planks_black/side"
   }
 }
\ 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
index 2bcd38b62..cf5015e5d 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_black/top"
+    "texture": "minecraft:block/trapdoor/planks_black/top",
+    "side": "minecraft:block/trapdoor/planks_black/side"
   }
 }
\ 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
index 6361ab404..a663bfeb7 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_black/top"
+    "texture": "minecraft:block/trapdoor/planks_black/top",
+    "side": "minecraft:block/trapdoor/planks_black/side"
   }
 }
\ 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
index add442be4..303f0caa8 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_blue/top"
+    "texture": "minecraft:block/trapdoor/planks_blue/top",
+    "side": "minecraft:block/trapdoor/planks_blue/side"
   }
 }
\ 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
index e2cff455e..d875efc21 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_blue/top"
+    "texture": "minecraft:block/trapdoor/planks_blue/top",
+    "side": "minecraft:block/trapdoor/planks_blue/side"
   }
 }
\ 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
index f6abd8704..d08f15b4f 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_blue/top"
+    "texture": "minecraft:block/trapdoor/planks_blue/top",
+    "side": "minecraft:block/trapdoor/planks_blue/side"
   }
 }
\ 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
index dd9ec274c..967e76f16 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_brown/top"
+    "texture": "minecraft:block/trapdoor/planks_brown/top",
+    "side": "minecraft:block/trapdoor/planks_brown/side"
   }
 }
\ 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
index 7130f5e04..d825d9e48 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_brown/top"
+    "texture": "minecraft:block/trapdoor/planks_brown/top",
+    "side": "minecraft:block/trapdoor/planks_brown/side"
   }
 }
\ 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
index 01390b202..d67017ae5 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_brown/top"
+    "texture": "minecraft:block/trapdoor/planks_brown/top",
+    "side": "minecraft:block/trapdoor/planks_brown/side"
   }
 }
\ 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
index 6da63681f..aff4e9981 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_cyan/top"
+    "texture": "minecraft:block/trapdoor/planks_cyan/top",
+    "side": "minecraft:block/trapdoor/planks_cyan/side"
   }
 }
\ 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
index f1538ee12..3d2ad8b01 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_cyan/top"
+    "texture": "minecraft:block/trapdoor/planks_cyan/top",
+    "side": "minecraft:block/trapdoor/planks_cyan/side"
   }
 }
\ 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
index e276c4585..098bcfe43 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_cyan/top"
+    "texture": "minecraft:block/trapdoor/planks_cyan/top",
+    "side": "minecraft:block/trapdoor/planks_cyan/side"
   }
 }
\ 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
index 0090266a6..175f3025a 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_gray/top"
+    "texture": "minecraft:block/trapdoor/planks_gray/top",
+    "side": "minecraft:block/trapdoor/planks_gray/side"
   }
 }
\ 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
index cf25693a4..17a338711 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_gray/top"
+    "texture": "minecraft:block/trapdoor/planks_gray/top",
+    "side": "minecraft:block/trapdoor/planks_gray/side"
   }
 }
\ 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
index 9b8aea9b4..4d11aebc1 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_gray/top"
+    "texture": "minecraft:block/trapdoor/planks_gray/top",
+    "side": "minecraft:block/trapdoor/planks_gray/side"
   }
 }
\ 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
index 90c2b1819..0a339301f 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_green/top"
+    "texture": "minecraft:block/trapdoor/planks_green/top",
+    "side": "minecraft:block/trapdoor/planks_green/side"
   }
 }
\ 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
index bf68ae8ab..819bd7402 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_green/top"
+    "texture": "minecraft:block/trapdoor/planks_green/top",
+    "side": "minecraft:block/trapdoor/planks_green/side"
   }
 }
\ 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
index 9b8f513d7..2c79b41de 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_green/top"
+    "texture": "minecraft:block/trapdoor/planks_green/top",
+    "side": "minecraft:block/trapdoor/planks_green/side"
   }
 }
\ 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
index 3b6ad5c94..f44e9ec76 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_lightblue/top"
+    "texture": "minecraft:block/trapdoor/planks_lightblue/top",
+    "side": "minecraft:block/trapdoor/planks_lightblue/side"
   }
 }
\ 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
index a6fffb6d7..232e8ab0c 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_lightblue/top"
+    "texture": "minecraft:block/trapdoor/planks_lightblue/top",
+    "side": "minecraft:block/trapdoor/planks_lightblue/side"
   }
 }
\ 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
index 1944ceb3e..ca33560cc 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_lightblue/top"
+    "texture": "minecraft:block/trapdoor/planks_lightblue/top",
+    "side": "minecraft:block/trapdoor/planks_lightblue/side"
   }
 }
\ 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
index e486edade..d7fc9286d 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_lime/top"
+    "texture": "minecraft:block/trapdoor/planks_lime/top",
+    "side": "minecraft:block/trapdoor/planks_lime/side"
   }
 }
\ 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
index d3006cca7..faa5354e7 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_lime/top"
+    "texture": "minecraft:block/trapdoor/planks_lime/top",
+    "side": "minecraft:block/trapdoor/planks_lime/side"
   }
 }
\ 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
index 58887e97e..a8e62312b 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_lime/top"
+    "texture": "minecraft:block/trapdoor/planks_lime/top",
+    "side": "minecraft:block/trapdoor/planks_lime/side"
   }
 }
\ 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
index a76786273..f756dfd95 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_magenta/top"
+    "texture": "minecraft:block/trapdoor/planks_magenta/top",
+    "side": "minecraft:block/trapdoor/planks_magenta/side"
   }
 }
\ 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
index 32f133ab3..20d522a9b 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_magenta/top"
+    "texture": "minecraft:block/trapdoor/planks_magenta/top",
+    "side": "minecraft:block/trapdoor/planks_magenta/side"
   }
 }
\ 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
index eb3f3ef2f..45039555d 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_magenta/top"
+    "texture": "minecraft:block/trapdoor/planks_magenta/top",
+    "side": "minecraft:block/trapdoor/planks_magenta/side"
   }
 }
\ 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
index 9e9032a05..762b8ebe8 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks/top"
+    "texture": "minecraft:block/trapdoor/planks/top",
+    "side": "minecraft:block/trapdoor/planks/side"
   }
 }
\ 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
index 5f3da6a8c..18860b877 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks/top"
+    "texture": "minecraft:block/trapdoor/planks/top",
+    "side": "minecraft:block/trapdoor/planks/side"
   }
 }
\ 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
index e6844c41e..8e9dfcc17 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks/top"
+    "texture": "minecraft:block/trapdoor/planks/top",
+    "side": "minecraft:block/trapdoor/planks/side"
   }
 }
\ 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
index f26b70c13..e0645ab68 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_orange/top"
+    "texture": "minecraft:block/trapdoor/planks_orange/top",
+    "side": "minecraft:block/trapdoor/planks_orange/side"
   }
 }
\ 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
index a39d3a210..b1ca89702 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_orange/top"
+    "texture": "minecraft:block/trapdoor/planks_orange/top",
+    "side": "minecraft:block/trapdoor/planks_orange/side"
   }
 }
\ 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
index f7ef46351..337ed4c0b 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_orange/top"
+    "texture": "minecraft:block/trapdoor/planks_orange/top",
+    "side": "minecraft:block/trapdoor/planks_orange/side"
   }
 }
\ 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
index 771e210f2..e53e153fb 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_pink/top"
+    "texture": "minecraft:block/trapdoor/planks_pink/top",
+    "side": "minecraft:block/trapdoor/planks_pink/side"
   }
 }
\ 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
index 8f89e2141..4dd0b2066 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_pink/top"
+    "texture": "minecraft:block/trapdoor/planks_pink/top",
+    "side": "minecraft:block/trapdoor/planks_pink/side"
   }
 }
\ 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
index a5032f249..bebf4074e 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_pink/top"
+    "texture": "minecraft:block/trapdoor/planks_pink/top",
+    "side": "minecraft:block/trapdoor/planks_pink/side"
   }
 }
\ 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
index 732a8c9b7..2c0b535cb 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_purple/top"
+    "texture": "minecraft:block/trapdoor/planks_purple/top",
+    "side": "minecraft:block/trapdoor/planks_purple/side"
   }
 }
\ 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
index d216fe930..bdc0f055a 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_purple/top"
+    "texture": "minecraft:block/trapdoor/planks_purple/top",
+    "side": "minecraft:block/trapdoor/planks_purple/side"
   }
 }
\ 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
index b92d6709b..34020e444 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_purple/top"
+    "texture": "minecraft:block/trapdoor/planks_purple/top",
+    "side": "minecraft:block/trapdoor/planks_purple/side"
   }
 }
\ 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
index 7fa536de8..1777c7bc1 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_red/top"
+    "texture": "minecraft:block/trapdoor/planks_red/top",
+    "side": "minecraft:block/trapdoor/planks_red/side"
   }
 }
\ 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
index af3e79d50..d4b61eb85 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_red/top"
+    "texture": "minecraft:block/trapdoor/planks_red/top",
+    "side": "minecraft:block/trapdoor/planks_red/side"
   }
 }
\ 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
index aeceb4557..853742d54 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_red/top"
+    "texture": "minecraft:block/trapdoor/planks_red/top",
+    "side": "minecraft:block/trapdoor/planks_red/side"
   }
 }
\ 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
index f76ce7242..9884ad6a1 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_silver/top"
+    "texture": "minecraft:block/trapdoor/planks_silver/top",
+    "side": "minecraft:block/trapdoor/planks_silver/side"
   }
 }
\ 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
index dcb435512..ae761e894 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_silver/top"
+    "texture": "minecraft:block/trapdoor/planks_silver/top",
+    "side": "minecraft:block/trapdoor/planks_silver/side"
   }
 }
\ 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
index 6fd35ca76..4d6bf9881 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_silver/top"
+    "texture": "minecraft:block/trapdoor/planks_silver/top",
+    "side": "minecraft:block/trapdoor/planks_silver/side"
   }
 }
\ 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
index ad474e2a1..fde432cba 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_white/top"
+    "texture": "minecraft:block/trapdoor/planks_white/top",
+    "side": "minecraft:block/trapdoor/planks_white/side"
   }
 }
\ 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
index 532545489..9945364ed 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_white/top"
+    "texture": "minecraft:block/trapdoor/planks_white/top",
+    "side": "minecraft:block/trapdoor/planks_white/side"
   }
 }
\ 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
index d92e5d7a9..0bf1f8f5c 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_white/top"
+    "texture": "minecraft:block/trapdoor/planks_white/top",
+    "side": "minecraft:block/trapdoor/planks_white/side"
   }
 }
\ 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
index 4655d86e1..68f666f32 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_yellow/top"
+    "texture": "minecraft:block/trapdoor/planks_yellow/top",
+    "side": "minecraft:block/trapdoor/planks_yellow/side"
   }
 }
\ 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
index 8ae910c0d..dae2fb07c 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_yellow/top"
+    "texture": "minecraft:block/trapdoor/planks_yellow/top",
+    "side": "minecraft:block/trapdoor/planks_yellow/side"
   }
 }
\ 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
index 94505e1af..e17b38082 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/planks_yellow/top"
+    "texture": "minecraft:block/trapdoor/planks_yellow/top",
+    "side": "minecraft:block/trapdoor/planks_yellow/side"
   }
 }
\ 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
index a5d750434..db24c33c2 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/bottom",
   "textures": {
-    "texture": "minecraft:block/trapdoor/steel/top"
+    "texture": "minecraft:block/trapdoor/steel/top",
+    "side": "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
index d94c76882..0f0f8de18 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/open",
   "textures": {
-    "texture": "minecraft:block/trapdoor/steel/top"
+    "texture": "minecraft:block/trapdoor/steel/top",
+    "side": "minecraft:block/trapdoor/steel/side"
   }
 }
\ 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
index 6c2e618c3..0c911de4b 100644
--- 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
@@ -1,6 +1,7 @@
 {
   "parent": "minecraft:block/trapdoor/top",
   "textures": {
-    "texture": "minecraft:block/trapdoor/steel/top"
+    "texture": "minecraft:block/trapdoor/steel/top",
+    "side": "minecraft:block/trapdoor/steel/side"
   }
 }
\ 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
index 036aeb7b9..2a02a8598 100644
--- 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
@@ -8,10 +8,10 @@
             "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" }
+                "north": { "uv": [ 0, 16, 16, 13 ], "texture": "#side", "cullface": "north" },
+                "south": { "uv": [ 0, 16, 16, 13 ], "texture": "#side", "cullface": "south" },
+                "west":  { "uv": [ 0, 16, 16, 13 ], "texture": "#side", "cullface": "west" },
+                "east":  { "uv": [ 0, 16, 16, 13 ], "texture": "#side", "cullface": "east" }
             }
         }
     ]
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/crystalline.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/crystalline.emiss.png
index da21eabfe..2d4e3fa6d 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/crystalline.emiss.png and b/game/client/src/main/resources/assets/minecraft/textures/block/cobbled_netherrack/crystalline.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/magma.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/magma.emiss.png
index d6e363303..6241874e0 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/magma.emiss.png and b/game/client/src/main/resources/assets/minecraft/textures/block/magma.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block_pure.png b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block_pure.png
index 9a35b9804..f4722740d 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block_pure.png and b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block_pure.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block_pure.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block_pure.png.mcmeta
new file mode 100644
index 000000000..af30dc0cf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block_pure.png.mcmeta
@@ -0,0 +1,6 @@
+{
+  "animation": {
+    "interpolate": true,
+    "frametime": 16
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.emiss.png
new file mode 100644
index 000000000..bd13a0e2f
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.emiss.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.png b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.png
new file mode 100644
index 000000000..5e7094598
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.png.mcmeta
new file mode 100644
index 000000000..af30dc0cf
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/node.png.mcmeta
@@ -0,0 +1,6 @@
+{
+  "animation": {
+    "interpolate": true,
+    "frametime": 16
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png b/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png
index f26906ddb..6cd25d35b 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png and b/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png.mcmeta b/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png.mcmeta
new file mode 100644
index 000000000..926199644
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png.mcmeta
@@ -0,0 +1,6 @@
+{
+  "animation": {
+    "interpolate": true,
+    "frametime": 3
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/rubyglass_crystal_pure.png b/game/client/src/main/resources/assets/minecraft/textures/item/rubyglass_crystal_pure.png
index 3670407e6..2f43804f0 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/item/rubyglass_crystal_pure.png and b/game/client/src/main/resources/assets/minecraft/textures/item/rubyglass_crystal_pure.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/particle/bubble_boiling.png b/game/client/src/main/resources/assets/minecraft/textures/particle/bubble_boiling.png
new file mode 100644
index 000000000..7ec9f1156
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/particle/bubble_boiling.png differ
diff --git a/game/client/src/main/resources/shaders/post/post.fsh b/game/client/src/main/resources/shaders/post/post.fsh
index bc044ee4d..7bbf4f5df 100644
--- a/game/client/src/main/resources/shaders/post/post.fsh
+++ b/game/client/src/main/resources/shaders/post/post.fsh
@@ -124,7 +124,7 @@ void Bloom(inout vec3 color) {
 	
 	blur /= allStrengths;
 	
-	color.rgb *= 1.0 - (bloom * 0.1);
+	blur.rgb *= 1.0 - (bloom * 0.1);
 	color.rgb += blur.rgb * 0.15 * bloom;
 }
 
@@ -137,8 +137,8 @@ void HeatHaze(inout vec2 coord, float amount) {
 	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.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.0001;
diff --git a/game/client/src/main/resources/shaders/terrain.fsh b/game/client/src/main/resources/shaders/terrain.fsh
index 8c75124a7..e8c27cc5c 100644
--- a/game/client/src/main/resources/shaders/terrain.fsh
+++ b/game/client/src/main/resources/shaders/terrain.fsh
@@ -78,7 +78,10 @@ void main() {
 
     vec4 c = vec4(mix(vec3(1, 1, 1), Color.rgb, maskColor.r), 1) * uColor;
 
-    vec4 postColor = texColor * c * vec4(Shade, Shade, Shade, 1) * lightColor;
+    float shadeEffect = 1 - max(emissiveColor.r, emissiveColor.g);
+    float s = mix(1, Shade, shadeEffect);
+
+    vec4 postColor = texColor * c * vec4(s, s, s, 1) * lightColor;
     vec4 litColor = vec4(postColor.rgb * clamp(Light, 0, 1), postColor.a);
 //    vec4 litColor = vec4(abs(Norm), 1f);
 
diff --git a/game/client/src/main/resources/shaders/terrain.gsh b/game/client/src/main/resources/shaders/terrain.gsh.disabled
similarity index 100%
rename from game/client/src/main/resources/shaders/terrain.gsh
rename to game/client/src/main/resources/shaders/terrain.gsh.disabled
diff --git a/game/client/src/main/resources/shaders/terrain.vsh b/game/client/src/main/resources/shaders/terrain.vsh
index 53d29cb43..15e3df320 100644
--- a/game/client/src/main/resources/shaders/terrain.vsh
+++ b/game/client/src/main/resources/shaders/terrain.vsh
@@ -1,64 +1,51 @@
 #version 410 core
-// Only guranteed 16 4 comp locations, so some attributes are packed together to save count, see (https://docs.gl/gl4/glGet @ GL_MAX_VERTEX_ATTRIBS)
-// Can combine uv and light shade in future if number needs further reduction
-layout (location = 0) in vec3 aSourcePos;
-layout (location = 1) in vec3 aSourceColor;
-layout (location = 2) in vec3 aSourceNormal;
 
-// Vertex one uses the position of the source pos
-layout (location = 3) in vec2 aV1UV;
-layout (location = 4) in vec2 aV1LightShade;
-
-layout (location = 5) in vec3 aV2PosOffset;
-layout (location = 6) in vec2 aV2UV;
-layout (location = 7) in vec2 aV2LightShade;
-
-layout (location = 8) in vec3 aV3PosOffset;
-layout (location = 9) in vec2 aV3UV;
-layout (location = 10) in vec2 aV3LightShade;
-
-layout (location = 11) in vec3 aV4PosOffset;
-layout (location = 12) in vec2 aV4UV;
-layout (location = 13) in vec2 aV4LightShade;
-
-out VS_OUT {
-    vec3 sourcePos;
-    vec3 sourceColor;
-    vec3 sourceNormal;
-
-    vec2 V1UV;
-    vec2 V1LightShade;
-
-    vec3 V2PosOffset;
-    vec2 V2UV;
-    vec2 V2LightShade;
-
-    vec3 V3PosOffset;
-    vec2 V3UV;
-    vec2 V3LightShade;
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec3 aColor;
+layout (location = 2) in vec3 aNormal;
+layout (location = 3) in vec2 aUV;
+layout (location = 4) in vec2 aLightShade;
+
+uniform mat4 model;
+layout (std140) uniform Matrices {
+    mat4 projection;
+    mat4 projectionInv;
+    mat4 view;
+    mat4 viewInv;
+} matrices;
+
+uniform mat4 normalTransform;
+uniform vec4 lightModelAmbient;
+uniform vec4 lightSourcePosition1;
+uniform vec4 lightSourcePosition2;
+uniform vec4 lightSourceDiffuse1;
+uniform vec4 lightSourceDiffuse2;
+
+out vec4 Color;
+out float Shade;
+out vec2 TexCoord;
+out vec2 LightMapCoord;
+out vec3 Light;
+out vec4 Norm;
+
+vec2 unpackLightCoord(vec2 lightShade) {
+    int asInt = int(lightShade.y);
+    return vec2(((asInt & 0xF) + 0.5)/16.0, (((asInt & 0xF0) >> 4) + 0.5)/16.0);
+}
 
-    vec3 V4PosOffset;
-    vec2 V4UV;
-    vec2 V4LightShade;
-} vs_out;
+float unpackShade(vec2 lightShade) {
+    return lightShade.x/256;
+}
 
 void main() {
-    vs_out.sourcePos = aSourcePos;
-    vs_out.sourceColor = aSourceColor;
-    vs_out.sourceNormal = aSourceNormal;
-
-    vs_out.V1UV = aV1UV;
-    vs_out.V1LightShade = aV1LightShade;
-
-    vs_out.V2PosOffset = aV2PosOffset;
-    vs_out.V2UV = aV2UV;
-    vs_out.V2LightShade = aV2LightShade;
-
-    vs_out.V3PosOffset = aV3PosOffset;
-    vs_out.V3UV = aV3UV;
-    vs_out.V3LightShade = aV3LightShade;
-
-    vs_out.V4PosOffset = aV4PosOffset;
-    vs_out.V4UV = aV4UV;
-    vs_out.V4LightShade = aV4LightShade;
-}
+    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;
+
+    Color = vec4(aColor, 1);
+    Shade = unpackShade(aLightShade);
+    TexCoord = aUV;
+    LightMapCoord = unpackLightCoord(aLightShade);
+    gl_Position = matrices.projection * matrices.view * model * vec4(aPos, 1);
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/shaders/terrain.vsh.disabled b/game/client/src/main/resources/shaders/terrain.vsh.disabled
new file mode 100644
index 000000000..53d29cb43
--- /dev/null
+++ b/game/client/src/main/resources/shaders/terrain.vsh.disabled
@@ -0,0 +1,64 @@
+#version 410 core
+// Only guranteed 16 4 comp locations, so some attributes are packed together to save count, see (https://docs.gl/gl4/glGet @ GL_MAX_VERTEX_ATTRIBS)
+// Can combine uv and light shade in future if number needs further reduction
+layout (location = 0) in vec3 aSourcePos;
+layout (location = 1) in vec3 aSourceColor;
+layout (location = 2) in vec3 aSourceNormal;
+
+// Vertex one uses the position of the source pos
+layout (location = 3) in vec2 aV1UV;
+layout (location = 4) in vec2 aV1LightShade;
+
+layout (location = 5) in vec3 aV2PosOffset;
+layout (location = 6) in vec2 aV2UV;
+layout (location = 7) in vec2 aV2LightShade;
+
+layout (location = 8) in vec3 aV3PosOffset;
+layout (location = 9) in vec2 aV3UV;
+layout (location = 10) in vec2 aV3LightShade;
+
+layout (location = 11) in vec3 aV4PosOffset;
+layout (location = 12) in vec2 aV4UV;
+layout (location = 13) in vec2 aV4LightShade;
+
+out VS_OUT {
+    vec3 sourcePos;
+    vec3 sourceColor;
+    vec3 sourceNormal;
+
+    vec2 V1UV;
+    vec2 V1LightShade;
+
+    vec3 V2PosOffset;
+    vec2 V2UV;
+    vec2 V2LightShade;
+
+    vec3 V3PosOffset;
+    vec2 V3UV;
+    vec2 V3LightShade;
+
+    vec3 V4PosOffset;
+    vec2 V4UV;
+    vec2 V4LightShade;
+} vs_out;
+
+void main() {
+    vs_out.sourcePos = aSourcePos;
+    vs_out.sourceColor = aSourceColor;
+    vs_out.sourceNormal = aSourceNormal;
+
+    vs_out.V1UV = aV1UV;
+    vs_out.V1LightShade = aV1LightShade;
+
+    vs_out.V2PosOffset = aV2PosOffset;
+    vs_out.V2UV = aV2UV;
+    vs_out.V2LightShade = aV2LightShade;
+
+    vs_out.V3PosOffset = aV3PosOffset;
+    vs_out.V3UV = aV3UV;
+    vs_out.V3LightShade = aV3LightShade;
+
+    vs_out.V4PosOffset = aV4PosOffset;
+    vs_out.V4UV = aV4UV;
+    vs_out.V4LightShade = aV4LightShade;
+}
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
index 0859e3683..3406d37cc 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
@@ -24,7 +24,7 @@ import org.joml.primitives.AABBdc;
 import java.util.Random;
 
 public abstract class BlockLogicFluid extends BlockLogic {
-    protected final @NotNull Fluid fluid;
+    public final @NotNull Fluid fluid;
     protected static final Direction[] CHECK_HARDEN_DIRECTIONS = new Direction[] {Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, Direction.UP};
 
     public BlockLogicFluid(final @NotNull Block<?> block, final @NotNull Material material, final @NotNull Fluid fluid) {
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRubyglass.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRubyglass.java
new file mode 100644
index 000000000..8a32ca537
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRubyglass.java
@@ -0,0 +1,29 @@
+package net.minecraft.core.block;
+
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
+import net.minecraft.core.block.entity.TileEntity;
+import net.minecraft.core.enums.EnumDropCause;
+import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.item.Items;
+import net.minecraft.core.world.World;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class BlockLogicOreRubyglass extends BlockLogicRubyglass
+{
+    public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
+
+    public BlockLogicOreRubyglass(@NotNull Block<?> block){
+        super(block);
+        variantMap.put(Blocks.RUBYGLASS_COLUMN.id(), block.id());
+    }
+
+    @Override
+    public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int data, @Nullable TileEntity tileEntity) {
+        return switch (dropCause) {
+            case SILK_TOUCH, PICK_BLOCK -> new ItemStack[]{new ItemStack(this)};
+            case EXPLOSION, PROPER_TOOL, PISTON_CRUSH -> new ItemStack[]{new ItemStack(Items.RUBYGLASS_CRYSTAL)};
+            default -> null;
+        };
+    }
+}
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java
index 0f5b1f45c..6d879d1de 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglass.java
@@ -26,19 +26,6 @@ public class BlockLogicRubyglass extends BlockLogic
         block.setTicking(true);
     }
 
-    @Override
-    public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int meta, TileEntity tileEntity)
-    {
-        switch (dropCause)
-        {
-            case PICK_BLOCK:
-            case SILK_TOUCH:
-                return new ItemStack[] { new ItemStack(this) };
-            default:
-                return new ItemStack[] { new ItemStack(Items.RUBYGLASS_CRYSTAL_CRACKED, world.rand.nextInt(3)) };
-        }
-    }
-
     @Override
     public float getAmbientOcclusionStrength(final @NotNull WorldSource source, final @NotNull TilePosc tilePos) {
         return 0.0f;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassCrop.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassCrop.java
index 5b7d27d88..49f8d4040 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassCrop.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassCrop.java
@@ -6,7 +6,6 @@ import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.Items;
-import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.pos.TilePos;
@@ -143,9 +142,9 @@ public class BlockLogicRubyglassCrop extends BlockLogic {
     @Override
     public @NotNull ItemStack @Nullable [] getBreakResult(final @NotNull World world, final @NotNull EnumDropCause dropCause, final int data, final @Nullable TileEntity tileEntity) {
         if (data != MAX_GROWTH_STATE) {
-            return new ItemStack[] { new ItemStack(Items.RUBYGLASS_CRYSTAL_CRACKED) };
+            return new ItemStack[] { new ItemStack(Items.RUBYGLASS_DUST) };
         } else {
-            return new ItemStack[] { new ItemStack(Items.RUBYGLASS_CRYSTAL_PURE) };
+            return new ItemStack[] { new ItemStack(Items.RUBYGLASS_CRYSTAL) };
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassGrowth.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassSprout.java
similarity index 95%
rename from game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassGrowth.java
rename to game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassSprout.java
index 6c0b4c963..8f259f1b5 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassGrowth.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRubyglassSprout.java
@@ -2,8 +2,6 @@ package net.minecraft.core.block;
 
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.material.Materials;
-import net.minecraft.core.block.tag.BlockTags;
-import net.minecraft.core.data.tag.Tag;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.Items;
@@ -17,8 +15,8 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.joml.primitives.AABBd;
 
-public class BlockLogicRubyglassGrowth extends BlockLogic {
-    public BlockLogicRubyglassGrowth(Block<?> block) {
+public class BlockLogicRubyglassSprout extends BlockLogic {
+    public BlockLogicRubyglassSprout(Block<?> block) {
         super(block, Materials.PLANT);
         block.setTicking(true);
     }
@@ -177,7 +175,11 @@ public class BlockLogicRubyglassGrowth extends BlockLogic {
 
     @Override
     public ItemStack[] getBreakResult(@NotNull World world, @NotNull EnumDropCause dropCause, int meta, TileEntity tileEntity) {
-        return new ItemStack[] { new ItemStack(Items.RUBYGLASS_CRYSTAL_CRACKED) };
+        // Buds have a 1/50 chance to drop pure Rubyglass.
+        if(world.rand.nextInt(50) == 0) {
+            return new ItemStack[] { new ItemStack(Items.RUBYGLASS_CRYSTAL) };
+        }
+        return null;
     }
 
     public static Direction metaToDirection(int meta) {
diff --git a/game/core/src/main/java/net/minecraft/core/block/Blocks.java b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
index 3397ae039..ed57f4a23 100644
--- a/game/core/src/main/java/net/minecraft/core/block/Blocks.java
+++ b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
@@ -1121,27 +1121,28 @@ public final class Blocks {
     public static final @NotNull Block<?> GLOWSTONE = register("glowstone", "minecraft:block/glowstone", 820, (b) -> new BlockLogicGlowStone(b, Materials.STONE))
         .withSound(BlockSounds.GLASS).withHardness(0.3F).withLightEmission(1.0F).withOverrideColor(MaterialColor.paintedYellow)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
-    public static final Block<?> RUBYGLASS = register("rubyglass", "minecraft:block/rubyglass", 821, (b) -> new BlockLogicRubyglass(b))
-        .withSound(BlockSounds.GLASS).withHardness(0.3F)
+
+    public static final Block<?> RUBYGLASS_COLUMN = register("rubyglass.column", "minecraft:block/rubyglass_column", 821, (b) -> new BlockLogicRubyglass(b))
+        .withSound(BlockSounds.GLASS).withHardness(3F).withLightEmission(0.8F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE)
         .withOverrideColor(MaterialColor.rubyglass);
-    public static final Block<?> RUBYGLASS_PURE = register("rubyglass.pure", "minecraft:block/rubyglass_pure", 822, (b) -> new BlockLogicTransparent(b, Materials.STONE))
-        .withSound(BlockSounds.GLASS).withHardness(0.3F)
+    public static final Block<?> BLOCK_RUBYGLASS = register("block.rubyglass", "minecraft:block/block_rubyglass", 822, (b) -> new BlockLogicTransparent(b, Materials.STONE))
+        .withSound(BlockSounds.GLASS).withHardness(3F).withLightEmission(0.8F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE)
         .withOverrideColor(MaterialColor.rubyglass);
-    public static final Block<?> RUBYGLASS_SPROUT = register("rubyglass.growth", "minecraft:block/rubyglass_growth", 823, (b) -> new BlockLogicRubyglassGrowth(b))
+    public static final Block<?> RUBYGLASS_SPROUT = register("rubyglass.sprout", "minecraft:block/rubyglass_sprout", 823, (b) -> new BlockLogicRubyglassSprout(b))
         .withSound(BlockSounds.GLASS).withDisabledNeighborNotifyOnMetadataChange().withLightEmission(0.8F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE)
         .withOverrideColor(MaterialColor.rubyglass);
     public static final Block<?> RUBYGLASS_CIRCUIT = register("rubyglass.circuit", "minecraft:block/rubyglass_circuit", 824, (b) -> new BlockLogic(b, Materials.STONE))
-        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withHardness(0.5F)
+        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withHardness(1F)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.INFINITE_BURN, BlockTags.CAVES_CUT_THROUGH, BlockTags.NETHER_MOBS_SPAWN)
         .withOverrideColor(MaterialColor.rubyglass);
 
-    public static final Block<?> RUBYGLASS_BUD = register("rubyglass.bud", "minecraft:block/rubyglass_bud", 825, (b) -> new BlockLogicRubyglassCrop(b))
-            .withSound(BlockSounds.GLASS).withDisabledNeighborNotifyOnMetadataChange().withLightEmission(0.8F)
-            .withTags(BlockTags.MINEABLE_BY_PICKAXE, BlockTags.NOT_IN_CREATIVE_MENU)
-        .withOverrideColor(MaterialColor.rubyglass);
+    public static final Block<?> RUBYGLASS_NODE = register("rubyglass.node", "minecraft:block/rubyglass_node", 826, (b) -> new BlockLogicOreRubyglass(b))
+            .withSound(BlockSounds.GLASS).withHardness(3F).withLightEmission(0.5F)
+            .withTags(BlockTags.MINEABLE_BY_PICKAXE)
+            .withOverrideColor(MaterialColor.rubyglass);
 
     public static final @NotNull Block<BlockLogicPortal> PORTAL_NETHER = register("portal.nether", "minecraft:block/portal_nether", 830, (BlockLogicSupplier<BlockLogicPortal>) b -> new BlockLogicPortal(b, Dimension.NETHER, Blocks.OBSIDIAN, Blocks.FIRE))
         .withSound(BlockSounds.GLASS).withHardness(-1F).withLightEmission(0.75F).withOverrideColor(MaterialColor.paintedPurple).withDisabledStats()
diff --git a/game/core/src/main/java/net/minecraft/core/block/FluidWater.java b/game/core/src/main/java/net/minecraft/core/block/FluidWater.java
index e9484a1fa..f7ea21c99 100644
--- a/game/core/src/main/java/net/minecraft/core/block/FluidWater.java
+++ b/game/core/src/main/java/net/minecraft/core/block/FluidWater.java
@@ -23,15 +23,21 @@ public class FluidWater
     @Override
     public void animationTick(final @NotNull BlockLogicFluid logicFluid, final @NotNull World world, final @NotNull TilePosc tilePos, final @NotNull Random rand) {
         final int data = world.getBlockData(tilePos) & 0x0F;
-        TilePos up = tilePos.up(new TilePos());
-        final boolean isTop = world.getBlockMaterial(up) == Materials.AIR && !world.isBlockOpaqueCube(up);
+        TilePos queryPos = new TilePos();
+        final boolean isTop = world.getBlockMaterial(tilePos.up(queryPos)) == Materials.AIR && !world.isBlockOpaqueCube(tilePos.up(queryPos));
+        final boolean isBottom = world.isBlockOpaqueCube(tilePos.down(queryPos));
         if (data > 0 && data < 8) {
             if (rand.nextInt(64) == 0) {
                 world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, (float) tilePos.x() + 0.5F, (float) tilePos.y() + 0.5F, (float) tilePos.z() + 0.5F, "liquid.water", rand.nextFloat() * 0.25F + 0.75F, rand.nextFloat() * 1.0F + 0.5F);
             }
         }
-        if (world.getWorldType().hasTag(WorldTypeTags.NETHER) && isTop && data == 0 && rand.nextInt(4) == 0) {
-            world.spawnParticle("smoke", tilePos.x() + Math.random(), tilePos.y() + (14f / 16f), tilePos.z() + Math.random(), 0.0D, 0.0D, 0.0D, 1);
+        if (world.getWorldType().hasTag(WorldTypeTags.NETHER)) {
+//            if (isTop && data == 0 && rand.nextInt(4) == 0) {
+//                world.spawnParticle("smoke", tilePos.x() + Math.random(), tilePos.y() + (14f / 16f), tilePos.z() + Math.random(), 0.0D, 0.0D, 0.0D, 1);
+//            }
+            if ((isBottom || rand.nextInt(16) == 0) && data == 0 && rand.nextInt(2) == 0) {
+                world.spawnParticle("bubbleboiling", tilePos.x() + Math.random(), tilePos.y() + 0.05f, tilePos.z() + Math.random(), 0, 0, 0, 0);
+            }
         }
 
         if (rand.nextInt(4) == 0 && world.getBlockType(tilePos.down(new TilePos())).solid() && !world.getBlockType(tilePos.down(new TilePos()).down()).solid()) {
diff --git a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
index 5dda2658f..d6199334e 100644
--- a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
+++ b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
@@ -17,8 +17,8 @@ public abstract class GameRules
     public static GameRuleBoolean DO_FIRE_SPREAD = register(new GameRuleBoolean("doFireSpread", "gamerule.do_fire_spread", true));
     public static GameRuleBoolean INSTANT_HEALING = register(new GameRuleBoolean("instantHealing", "gamerule.instant_healing", false));
     public static GameRuleInteger RANDOM_TICK_SPEED = register(new GameRuleInteger("randomTickSpeed", "gamerule.random_tick_speed", 4));
-    public static GameRuleInteger ITEM_DESPAWN_DELAY = register(new GameRuleInteger("itemDespawnDelay", "gamerule.item_despawn_delay", 6000));
-    public static GameRuleInteger DROPPED_ITEM_DESPAWN_DELAY = register(new GameRuleInteger("droppedItemDespawnDelay", "gamerule.dropped_item_despawn_delay", 6000));
+    public static GameRuleInteger ITEM_DESPAWN_DELAY = register(new GameRuleInteger("itemDespawnDelay", "gamerule.item_despawn_delay", 12000));
+    public static GameRuleInteger DROPPED_ITEM_DESPAWN_DELAY = register(new GameRuleInteger("droppedItemDespawnDelay", "gamerule.dropped_item_despawn_delay", 12000));
 
     public static <T extends GameRule<?>> T register(T gameRule)
     {
diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java b/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java
index ead3acd26..b21344618 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/EntityItem.java
@@ -14,6 +14,7 @@ import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemDiscMusic;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.item.tag.ItemTags;
 import net.minecraft.core.util.helper.DamageType;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
@@ -92,18 +93,24 @@ public class EntityItem extends Entity
         {
             this.pickupDelay--;
         }
+        boolean inLava = isInLava();
         this.xo = this.x;
         this.yo = this.y;
         this.zo = this.z;
-        this.yd -= 0.04D;
-        if(isInLava())
-        {
-            this.yd = 0.2D;
-            this.xd = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
-            this.zd = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
-            this.world.playSoundAtEntity(null, this, "random.fizz", 0.4F, 2.0F + this.random.nextFloat() * 0.4F);
-        }
 
+        if (item.getItem().hasTag(ItemTags.IS_FIRE_PROOF)) {
+            this.yd += (this.wasInWater || inLava) ? 0.02D : -0.04D;
+        } else {
+            this.yd += this.wasInWater ? 0.02D : -0.04D;
+
+            if(isInLava())
+            {
+                this.yd = 0.2D;
+                this.xd = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
+                this.zd = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
+                this.world.playSoundAtEntity(null, this, "random.fizz", 0.4F, 2.0F + this.random.nextFloat() * 0.4F);
+            }
+        }
         checkAndPushInTile(this.x, (this.bb.minY + this.bb.maxY) / 2D, this.z);
         move(this.xd, this.yd, this.zd);
         
@@ -143,7 +150,7 @@ public class EntityItem extends Entity
             this.yd *= -0.5D;
         }
         this.age++;
-        if(this.age >= this.lifetime && this.lifetime >= 0) // Negative lifetime indicates items should last forever
+        if(this.age >= this.lifetime && this.lifetime >= 0 && !this.item.getItem().hasTag(ItemTags.IS_PERSISTENT)) // Negative lifetime indicates items should last forever
         {
             remove();
         }
@@ -158,12 +165,22 @@ public class EntityItem extends Entity
     @Override
 	protected void burn(int damage)
     {
-        hurt(null, damage, DamageType.FIRE);
+        if (!this.item.getItem().hasTag(ItemTags.IS_FIRE_PROOF)) {
+            hurt(null, damage, DamageType.FIRE);
+        }
     }
 
     @Override
     public boolean hurt(Entity entity, int i, DamageType type)
     {
+        if (this.item.getItem().hasTag(ItemTags.IS_INDESTRUCTIBLE)) {
+            return false;
+        }
+        else if (type == DamageType.FIRE && this.item.getItem().hasTag(ItemTags.IS_FIRE_PROOF)) {
+            return false;
+        } else if (type == DamageType.BLAST && this.item.getItem().hasTag(ItemTags.IS_BLAST_PROOF)) {
+            return false;
+        }
         markHurt();
         this.health -= i;
         if(this.health <= 0)
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemCrystalBud.java b/game/core/src/main/java/net/minecraft/core/item/ItemCrystalBud.java
deleted file mode 100644
index f68293d96..000000000
--- a/game/core/src/main/java/net/minecraft/core/item/ItemCrystalBud.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package net.minecraft.core.item;
-
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.BlockLogicFarmland;
-import net.minecraft.core.block.BlockLogicRotatable;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.block.entity.TileEntityActivator;
-import net.minecraft.core.block.tag.BlockTags;
-import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.enums.EnumBlockSoundEffectType;
-import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.World;
-import net.minecraft.core.world.pos.TilePos;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Random;
-
-public class ItemCrystalBud extends Item {
-
-    public ItemCrystalBud(@NotNull String name, @NotNull String namespaceId, int id) {
-        super(name, namespaceId, id);
-    }
-
-    @Override
-    public boolean onUseOnBlock(@NotNull ItemStack selfStack, @NotNull World world, @Nullable Player player, @NotNull TilePosc blockPos, @NotNull Side side, double xHit, double yHit) {
-        if (!world.canPlaceInsideBlock(blockPos)) {
-            blockPos = blockPos.add(side.getDirection(), new TilePos());
-        }
-
-        TilePos queryPos = new TilePos();
-
-        if (world.getBlockType(blockPos.down(queryPos)).hasTag(BlockTags.GROWS_RUBYGLASS)) {
-            if (world.setBlockType(blockPos, Blocks.RUBYGLASS_BUD)) {
-                world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, Blocks.RUBYGLASS_BUD, EnumBlockSoundEffectType.PLACE);
-                selfStack.consumeItem(player);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void onUseByActivator(@NotNull ItemStack selfStack, @NotNull World world, @NotNull TileEntityActivator activator, @NotNull Random random, @NotNull TilePosc blockPos, @NotNull Direction direction, double offX, double offY, double offZ) {
-        blockPos = blockPos.add(direction, new TilePos());
-        Block<?> b = world.getBlockType(blockPos);
-        boolean canGrowRubyglass = world.getBlockType(blockPos).hasTag(BlockTags.GROWS_RUBYGLASS);
-        if (b == null || canGrowRubyglass || BlockTags.PLACE_OVERWRITES.appliesTo(b)) {
-            onUseOnBlock(selfStack, world, null, blockPos.add(0, canGrowRubyglass ? 1 : 0, 0, new TilePos()), direction.getSide(), 0.5, 0.5);
-        }
-    }
-}
diff --git a/game/core/src/main/java/net/minecraft/core/item/Items.java b/game/core/src/main/java/net/minecraft/core/item/Items.java
index c01f9a317..cdb68cf16 100644
--- a/game/core/src/main/java/net/minecraft/core/item/Items.java
+++ b/game/core/src/main/java/net/minecraft/core/item/Items.java
@@ -205,8 +205,8 @@ public final class Items {
     public static Item SIGN_PAINTED;
     public static Item DOUGH;
     public static Item WAND_NBT;
-    public static Item RUBYGLASS_CRYSTAL_CRACKED;
-    public static Item RUBYGLASS_CRYSTAL_PURE;
+    public static Item RUBYGLASS_DUST;
+    public static Item RUBYGLASS_CRYSTAL;
 
 
     private static boolean hasInit = false;
@@ -252,7 +252,7 @@ public final class Items {
         TOOL_BOW = (new ItemBow("tool.bow", "minecraft:item/tool_bow", 16389));
         AMMO_ARROW = (new Item("ammo.arrow", "minecraft:item/ammo_arrow", 16390));
         COAL = (new ItemCoal("coal", "minecraft:item/coal", 16391));
-        DIAMOND = (new Item("diamond", "minecraft:item/diamond", 16392));
+        DIAMOND = (new Item("diamond", "minecraft:item/diamond", 16392)).withTags(ItemTags.IS_FIRE_PROOF);
         INGOT_IRON = (new Item("ingot.iron", "minecraft:item/ingot_iron", 16393));
         INGOT_GOLD = (new Item("ingot.gold", "minecraft:item/ingot_gold", 16394));
         TOOL_SWORD_IRON = (new ItemToolSword("tool.sword.iron", "minecraft:item/tool_sword_iron", 16395, ToolMaterial.iron)).withTags(ItemTags.PREVENT_CREATIVE_MINING);
@@ -264,10 +264,10 @@ public final class Items {
         TOOL_SHOVEL_STONE = (new ItemToolShovel("tool.shovel.stone", "minecraft:item/tool_shovel_stone", 16401, ToolMaterial.stone));
         TOOL_PICKAXE_STONE = (new ItemToolPickaxe("tool.pickaxe.stone", "minecraft:item/tool_pickaxe_stone", 16402, ToolMaterial.stone));
         TOOL_AXE_STONE = (new ItemToolAxe("tool.axe.stone", "minecraft:item/tool_axe_stone", 16403, ToolMaterial.stone));
-        TOOL_SWORD_DIAMOND = (new ItemToolSword("tool.sword.diamond", "minecraft:item/tool_sword_diamond", 16404, ToolMaterial.diamond)).withTags(ItemTags.PREVENT_CREATIVE_MINING);
-        TOOL_SHOVEL_DIAMOND = (new ItemToolShovel("tool.shovel.diamond", "minecraft:item/tool_shovel_diamond", 16405, ToolMaterial.diamond));
-        TOOL_PICKAXE_DIAMOND = (new ItemToolPickaxe("tool.pickaxe.diamond", "minecraft:item/tool_pickaxe_diamond", 16406, ToolMaterial.diamond));
-        TOOL_AXE_DIAMOND = (new ItemToolAxe("tool.axe.diamond", "minecraft:item/tool_axe_diamond", 16407, ToolMaterial.diamond));
+        TOOL_SWORD_DIAMOND = (new ItemToolSword("tool.sword.diamond", "minecraft:item/tool_sword_diamond", 16404, ToolMaterial.diamond)).withTags(ItemTags.PREVENT_CREATIVE_MINING, ItemTags.IS_FIRE_PROOF);
+        TOOL_SHOVEL_DIAMOND = (new ItemToolShovel("tool.shovel.diamond", "minecraft:item/tool_shovel_diamond", 16405, ToolMaterial.diamond)).withTags(ItemTags.IS_FIRE_PROOF);
+        TOOL_PICKAXE_DIAMOND = (new ItemToolPickaxe("tool.pickaxe.diamond", "minecraft:item/tool_pickaxe_diamond", 16406, ToolMaterial.diamond)).withTags(ItemTags.IS_FIRE_PROOF);
+        TOOL_AXE_DIAMOND = (new ItemToolAxe("tool.axe.diamond", "minecraft:item/tool_axe_diamond", 16407, ToolMaterial.diamond)).withTags(ItemTags.IS_FIRE_PROOF);
         STICK = (new Item("stick", "minecraft:item/stick", 16408));
         BOWL = (new Item("bowl", "minecraft:item/bowl", 16409));
         FOOD_STEW_MUSHROOM = (new ItemSoup("food.stew.mushroom", "minecraft:item/food_stew_mushroom", 16410, 10, 16));
@@ -281,7 +281,7 @@ public final class Items {
         TOOL_HOE_WOOD = (new ItemToolHoe("tool.hoe.wood", "minecraft:item/tool_hoe_wood", 16418, ToolMaterial.wood));
         TOOL_HOE_STONE = (new ItemToolHoe("tool.hoe.stone", "minecraft:item/tool_hoe_stone", 16419, ToolMaterial.stone));
         TOOL_HOE_IRON = (new ItemToolHoe("tool.hoe.iron", "minecraft:item/tool_hoe_iron", 16420, ToolMaterial.iron));
-        TOOL_HOE_DIAMOND = (new ItemToolHoe("tool.hoe.diamond", "minecraft:item/tool_hoe_diamond", 16421, ToolMaterial.diamond));
+        TOOL_HOE_DIAMOND = (new ItemToolHoe("tool.hoe.diamond", "minecraft:item/tool_hoe_diamond", 16421, ToolMaterial.diamond)).withTags(ItemTags.IS_FIRE_PROOF);
         TOOL_HOE_GOLD = (new ItemToolHoe("tool.hoe.gold", "minecraft:item/tool_hoe_gold", 16422, ToolMaterial.gold));
         SEEDS_WHEAT = (new ItemSeeds("seeds.wheat", "minecraft:item/seeds_wheat", 16423, Blocks.CROPS_WHEAT)).withTags(ItemTags.CHICKENS_FAVOURITE_ITEM);
         WHEAT = (new Item("wheat", "minecraft:item/wheat", 16424)).withTags(ItemTags.COWS_FAVOURITE_ITEM);
@@ -302,10 +302,10 @@ public final class Items {
         ARMOR_LEGGINGS_IRON = (new ItemArmor("armor.leggings.iron", "minecraft:item/armor_leggings_iron", 16436, ArmorMaterial.IRON, HumanArmorShape.LEGS));
         ARMOR_BOOTS_IRON = (new ItemArmor("armor.boots.iron", "minecraft:item/armor_boots_iron", 16437, ArmorMaterial.IRON, HumanArmorShape.BOOTS));
 
-        ARMOR_HELMET_DIAMOND = (new ItemArmor("armor.helmet.diamond", "minecraft:item/armor_helmet_diamond", 16438, ArmorMaterial.DIAMOND, HumanArmorShape.HEAD));
-        ARMOR_CHESTPLATE_DIAMOND = (new ItemArmor("armor.chestplate.diamond", "minecraft:item/armor_chestplate_diamond", 16439, ArmorMaterial.DIAMOND, HumanArmorShape.CHEST));
-        ARMOR_LEGGINGS_DIAMOND = (new ItemArmor("armor.leggings.diamond", "minecraft:item/armor_leggings_diamond", 16440, ArmorMaterial.DIAMOND, HumanArmorShape.LEGS));
-        ARMOR_BOOTS_DIAMOND = (new ItemArmor("armor.boots.diamond", "minecraft:item/armor_boots_diamond", 16441, ArmorMaterial.DIAMOND, HumanArmorShape.BOOTS));
+        ARMOR_HELMET_DIAMOND = (new ItemArmor("armor.helmet.diamond", "minecraft:item/armor_helmet_diamond", 16438, ArmorMaterial.DIAMOND, HumanArmorShape.HEAD)).withTags(ItemTags.IS_FIRE_PROOF);
+        ARMOR_CHESTPLATE_DIAMOND = (new ItemArmor("armor.chestplate.diamond", "minecraft:item/armor_chestplate_diamond", 16439, ArmorMaterial.DIAMOND, HumanArmorShape.CHEST)).withTags(ItemTags.IS_FIRE_PROOF);
+        ARMOR_LEGGINGS_DIAMOND = (new ItemArmor("armor.leggings.diamond", "minecraft:item/armor_leggings_diamond", 16440, ArmorMaterial.DIAMOND, HumanArmorShape.LEGS)).withTags(ItemTags.IS_FIRE_PROOF);
+        ARMOR_BOOTS_DIAMOND = (new ItemArmor("armor.boots.diamond", "minecraft:item/armor_boots_diamond", 16441, ArmorMaterial.DIAMOND, HumanArmorShape.BOOTS)).withTags(ItemTags.IS_FIRE_PROOF);
 
         ARMOR_HELMET_GOLD = (new ItemArmor("armor.helmet.gold", "minecraft:item/armor_helmet_gold", 16442, ArmorMaterial.GOLD, HumanArmorShape.HEAD));
         ARMOR_CHESTPLATE_GOLD = (new ItemArmor("armor.chestplate.gold", "minecraft:item/armor_chestplate_gold", 16443, ArmorMaterial.GOLD, HumanArmorShape.CHEST));
@@ -366,18 +366,18 @@ public final class Items {
         RECORD_WAIT = (new ItemDiscMusic("record.wait", "minecraft:item/record_wait", 18394, "record.wait", "C418"));
         RECORD_DOG = (new ItemDiscMusic("record.dog", "minecraft:item/record_dog", 18395, "record.dog", "C418"));
         NETHERCOAL = (new Item("nethercoal", "minecraft:item/nethercoal", 16488));
-        ARMOR_HELMET_STEEL = (new ItemArmor("armor.helmet.steel", "minecraft:item/armor_helmet_steel", 16489, ArmorMaterial.STEEL, HumanArmorShape.HEAD));
-        ARMOR_CHESTPLATE_STEEL = (new ItemArmor("armor.chestplate.steel", "minecraft:item/armor_chestplate_steel", 16490, ArmorMaterial.STEEL, HumanArmorShape.CHEST));
-        ARMOR_LEGGINGS_STEEL = (new ItemArmor("armor.leggings.steel", "minecraft:item/armor_leggings_steel", 16491, ArmorMaterial.STEEL, HumanArmorShape.LEGS));
-        ARMOR_BOOTS_STEEL = (new ItemArmor("armor.boots.steel", "minecraft:item/armor_boots_steel", 16492, ArmorMaterial.STEEL, HumanArmorShape.BOOTS));
+        ARMOR_HELMET_STEEL = (new ItemArmor("armor.helmet.steel", "minecraft:item/armor_helmet_steel", 16489, ArmorMaterial.STEEL, HumanArmorShape.HEAD)).withTags(ItemTags.IS_BLAST_PROOF);
+        ARMOR_CHESTPLATE_STEEL = (new ItemArmor("armor.chestplate.steel", "minecraft:item/armor_chestplate_steel", 16490, ArmorMaterial.STEEL, HumanArmorShape.CHEST)).withTags(ItemTags.IS_BLAST_PROOF);
+        ARMOR_LEGGINGS_STEEL = (new ItemArmor("armor.leggings.steel", "minecraft:item/armor_leggings_steel", 16491, ArmorMaterial.STEEL, HumanArmorShape.LEGS)).withTags(ItemTags.IS_BLAST_PROOF);
+        ARMOR_BOOTS_STEEL = (new ItemArmor("armor.boots.steel", "minecraft:item/armor_boots_steel", 16492, ArmorMaterial.STEEL, HumanArmorShape.BOOTS)).withTags(ItemTags.IS_BLAST_PROOF);
 
-        TOOL_SWORD_STEEL = (new ItemToolSword("tool.sword.steel", "minecraft:item/tool_sword_steel", 16493, ToolMaterial.steel)).withTags(ItemTags.PREVENT_CREATIVE_MINING);
-        TOOL_SHOVEL_STEEL = (new ItemToolShovel("tool.shovel.steel", "minecraft:item/tool_shovel_steel", 16494, ToolMaterial.steel));
-        TOOL_PICKAXE_STEEL = (new ItemToolPickaxe("tool.pickaxe.steel", "minecraft:item/tool_pickaxe_steel", 16495, ToolMaterial.steel));
-        TOOL_AXE_STEEL = (new ItemToolAxe("tool.axe.steel", "minecraft:item/tool_axe_steel", 16496, ToolMaterial.steel));
-        TOOL_HOE_STEEL = (new ItemToolHoe("tool.hoe.steel", "minecraft:item/tool_hoe_steel", 16497, ToolMaterial.steel));
+        TOOL_SWORD_STEEL = (new ItemToolSword("tool.sword.steel", "minecraft:item/tool_sword_steel", 16493, ToolMaterial.steel)).withTags(ItemTags.PREVENT_CREATIVE_MINING, ItemTags.IS_BLAST_PROOF);
+        TOOL_SHOVEL_STEEL = (new ItemToolShovel("tool.shovel.steel", "minecraft:item/tool_shovel_steel", 16494, ToolMaterial.steel)).withTags(ItemTags.IS_BLAST_PROOF);
+        TOOL_PICKAXE_STEEL = (new ItemToolPickaxe("tool.pickaxe.steel", "minecraft:item/tool_pickaxe_steel", 16495, ToolMaterial.steel)).withTags(ItemTags.IS_BLAST_PROOF);
+        TOOL_AXE_STEEL = (new ItemToolAxe("tool.axe.steel", "minecraft:item/tool_axe_steel", 16496, ToolMaterial.steel)).withTags(ItemTags.IS_BLAST_PROOF);
+        TOOL_HOE_STEEL = (new ItemToolHoe("tool.hoe.steel", "minecraft:item/tool_hoe_steel", 16497, ToolMaterial.steel)).withTags(ItemTags.IS_BLAST_PROOF);
 
-        INGOT_STEEL = (new Item("ingot.steel", "minecraft:item/ingot_steel", 16498));
+        INGOT_STEEL = (new Item("ingot.steel", "minecraft:item/ingot_steel", 16498)).withTags(ItemTags.IS_BLAST_PROOF);
         INGOT_STEEL_CRUDE = (new Item("ingot.steel.crude", "minecraft:item/ingot_steel_crude", 16499));
         AMMO_FIREBALL = (new Item("ammo.fireball", "minecraft:item/ammo_fireball", 16500)).withTags(ItemTags.NOT_IN_CREATIVE_MENU);
         ARMOR_QUIVER_GOLD = (new ItemQuiverEndless("armor.quiver.gold", "minecraft:item/armor_quiver_gold", 16501));
@@ -407,8 +407,8 @@ public final class Items {
         BASKET = new ItemPlaceable("basket", "minecraft:item/basket", 16525, Blocks.BASKET);
         FLAG = new ItemFlag("flag", "minecraft:item/flag", 16526);
         ARMOR_BOOTS_ICESKATES = new ItemIceSkates("armor.boots.iceskates", "minecraft:item/armor_boots_iceskates", 16527);
-        TOOL_SHEARS_STEEL = (ItemToolShears)(new ItemToolShears("tool.shears.steel", "minecraft:item/tool_shears_steel", 16528, ToolMaterial.steel)).setMaxDamage(ToolMaterial.steel.getDurability());
-        TOOL_FIRESTRIKER_STEEL = (new ItemFireStriker("tool.firestriker.steel", "minecraft:item/tool_firestriker_steel", 16529)).setMaxDamage(ToolMaterial.steel.getDurability());
+        TOOL_SHEARS_STEEL = (ItemToolShears)(new ItemToolShears("tool.shears.steel", "minecraft:item/tool_shears_steel", 16528, ToolMaterial.steel)).setMaxDamage(ToolMaterial.steel.getDurability()).withTags(ItemTags.IS_BLAST_PROOF);
+        TOOL_FIRESTRIKER_STEEL = (new ItemFireStriker("tool.firestriker.steel", "minecraft:item/tool_firestriker_steel", 16529)).setMaxDamage(ToolMaterial.steel.getDurability()).withTags(ItemTags.IS_BLAST_PROOF);
         SEEDS_PUMPKIN = (new ItemSeeds("seeds.pumpkin", "minecraft:item/seeds_pumpkin", 16530, Blocks.CROPS_PUMPKIN)).withTags(ItemTags.CHICKENS_FAVOURITE_ITEM);
         SEAT = new ItemPlaceable("seat", "minecraft:item/seat", 16531, Blocks.SEAT).setMaxStackSize(64);
         DOOR_OAK_PAINTED = (new ItemDoorPainted("door.oak.painted", "minecraft:item/door_oak_painted", 16532, Blocks.DOOR_PLANKS_PAINTED_BOTTOM, Blocks.DOOR_PLANKS_PAINTED_TOP));
@@ -416,7 +416,7 @@ public final class Items {
         ROPE = new ItemRope("rope", "minecraft:item/rope", 16534, Blocks.ROPE);
         FOOD_PUMPKIN_PIE = (new ItemPlaceable("food.pumpkin_pie", "minecraft:item/food_pumpkin_pie", 16535, Blocks.PUMPKIN_PIE)).setMaxStackSize(1);
         WAND_MONSTER_SPAWNER = (new ItemWandSpawner("wand.monster", "minecraft:item/wand_monster", 16536)).setMaxStackSize(1);
-        DOOR_STEEL = (new ItemDoor("door.steel", "minecraft:item/door_steel", 16537, Blocks.DOOR_STEEL_BOTTOM, Blocks.DOOR_STEEL_TOP));
+        DOOR_STEEL = (new ItemDoor("door.steel", "minecraft:item/door_steel", 16537, Blocks.DOOR_STEEL_BOTTOM, Blocks.DOOR_STEEL_TOP)).withTags(ItemTags.IS_BLAST_PROOF);
         PAINTBRUSH = new ItemPaintBrush("paintbrush", "minecraft:item/paintbrush", 16538);
         JAR_BUTTERFLY_BLUE = new ItemPlaceable("jar.butterfly.blue", "minecraft:item/jar_butterfly_blue", 16539, Blocks.JAR_BUTTERFLY_BLUE);
         JAR_BUTTERFLY_ORANGE = new ItemPlaceable("jar.butterfly.orange", "minecraft:item/jar_butterfly_orange", 16540, Blocks.JAR_BUTTERFLY_ORANGE);
@@ -433,7 +433,7 @@ public final class Items {
         FOOD_VENISON_COOKED = (new ItemFood("food.venison.cooked", "minecraft:item/food_venison_cooked", 16551, 12, 8, true, 4));
         DOUGH = (new Item("dough", "minecraft:item/dough", 16552));
         WAND_NBT = new ItemWandNBT("wand.nbt", "minecraft:item/wand_nbt", 16553);
-        RUBYGLASS_CRYSTAL_CRACKED = (new ItemCrystalBud("rubyglass.crystal.cracked", "minecraft:item/rubyglass_crystal_cracked", 16554));
-        RUBYGLASS_CRYSTAL_PURE = (new ItemCrystalBud("rubyglass.crystal.pure", "minecraft:item/rubyglass_crystal_pure", 16555));
+        RUBYGLASS_DUST = (new Item("rubyglass.crystal.cracked", "minecraft:item/rubyglass_crystal_cracked", 16554));
+        RUBYGLASS_CRYSTAL = (new Item("rubyglass.crystal.pure", "minecraft:item/rubyglass_crystal_pure", 16555));
     }
 }
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 e4edf7f3d..82f2cbd54 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
@@ -38,6 +38,26 @@ public abstract class ItemTags
      */
     public static final @NotNull Tag<Item> COWS_FAVOURITE_ITEM = Tag.of("cows_favourite_item");
 
+    /**
+     * Items with this tag will not burn in fire or lava
+     */
+    public static final @NotNull Tag<Item> IS_FIRE_PROOF = Tag.of("is_fire_proof");
+
+    /**
+     * Items with this tag will not be destroyed by explosions
+     */
+    public static final @NotNull Tag<Item> IS_BLAST_PROOF = Tag.of("is_blast_proof");
+
+    /**
+     * Item entities with this tag will be able to be killed
+     */
+    public static final @NotNull Tag<Item> IS_INDESTRUCTIBLE = Tag.of("is_indestructible");
+
+    /**
+     * Items with this tag won't despawn
+     */
+    public static final @NotNull Tag<Item> IS_PERSISTENT = Tag.of("is_persistent");
+
     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/ArgumentTypeParticleId.java b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeParticleId.java
index 4291996c8..fe3cbdcf2 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeParticleId.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeParticleId.java
@@ -29,6 +29,7 @@ public class ArgumentTypeParticleId implements ArgumentType<String> {
         particleIds.add("reddust");
         particleIds.add("soulflame");
         particleIds.add("bubble");
+        particleIds.add("bubbleboiling");
         particleIds.add("explode");
         particleIds.add("slimechunk");
         particleIds.add("block");
@@ -48,6 +49,7 @@ public class ArgumentTypeParticleId implements ArgumentType<String> {
         particleIds.add("fireflyRed");
         particleIds.add("splash");
         particleIds.add("ashmote");
+        particleIds.add("ventsmoke");
     }
 
     private static final List<String> EXAMPLES = Arrays.asList("fireflyGreen", "explode", "soulflame");
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/ChunkDecoratorNether.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/ChunkDecoratorNether.java
index 2c2707ee7..36153bc53 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/ChunkDecoratorNether.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/ChunkDecoratorNether.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.world.generate.chunk.perlin.nether;
 
 import net.minecraft.core.block.BlockLogicOreNetherCoal;
+import net.minecraft.core.block.BlockLogicOreRubyglass;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.Biome;
@@ -71,6 +72,13 @@ public class ChunkDecoratorNether
                         .withPlacementMethod(new PlacementMethod.TriesPerChunk(4))
         );
 
+        this.register("minecraft:decoration/nether/default/rubyglass_node",
+                new ChunkDecorationBuilder(new WorldFeatureOre(BlockLogicOreRubyglass.variantMap, 5))
+                        .withBiomeMask(new Biome[]{ Biomes.NETHER_CRYSTAL_FOREST, Biomes.NETHER_CRYSTAL_PLAINS})
+                        .withPositionSelector(PositionSelectors.HeightRangeUniform)
+                        .withPlacementMethod(new PlacementMethod.TriesPerChunk(10))
+        );
+
         this.register("minecraft:decoration/nether/default/rubyglass_sprout_patch",
                 new ChunkDecorationBuilder(new WorldFeatureRubyglassSproutPatch())
                         .withBiomeMask(new Biome[]{ Biomes.NETHER_CRYSTAL_FOREST, Biomes.NETHER_CRYSTAL_PLAINS})
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassCrystal.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassCrystal.java
index 59bb9911e..50415b5d2 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassCrystal.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassCrystal.java
@@ -161,16 +161,18 @@ public class WorldFeatureRubyglassCrystal implements WorldFeatureInterface {
                     return null;
                 }
 
+                boolean ore = random.nextInt(50) == 0;
+
                 final float distancePctg = faceDistances[0] / length;
                 if (distancePctg < BASE_PCTG) {
                     final float innerDistancePctg = distancePctg / BASE_PCTG;
                     if (innerDistancePctg < random.nextFloat()) {
                         return Blocks.COBBLE_NETHERRACK_CRYSTALLINE;
                     } else {
-                        return Blocks.RUBYGLASS;
+                        return ore ? Blocks.RUBYGLASS_NODE : Blocks.RUBYGLASS_COLUMN;
                     }
                 } else {
-                    return Blocks.RUBYGLASS;
+                    return ore ? Blocks.RUBYGLASS_NODE : Blocks.RUBYGLASS_COLUMN;
                 }
             }
         );
@@ -184,7 +186,7 @@ public class WorldFeatureRubyglassCrystal implements WorldFeatureInterface {
         for (ti.y = tilePos.y(); ti.y < tilePos.y() + base; ti.y++) {
             for (ti.x = tilePos.x() - base; ti.x < tilePos.x() + base; ti.x++) {
                 for (ti.z = tilePos.z() - base; ti.z < tilePos.z() + base; ti.z++) {
-                    if (world.getBlockType(ti) == Blocks.RUBYGLASS)
+                    if (world.getBlockType(ti) == Blocks.RUBYGLASS_COLUMN)
                         return false;
                 }
             }
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassSproutPatch.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassSproutPatch.java
index eacb8d7bb..9eca06b81 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassSproutPatch.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureRubyglassSproutPatch.java
@@ -1,6 +1,6 @@
 package net.minecraft.core.world.generate.feature;
 
-import net.minecraft.core.block.BlockLogicRubyglassGrowth;
+import net.minecraft.core.block.BlockLogicRubyglassSprout;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
@@ -27,7 +27,7 @@ public class WorldFeatureRubyglassSproutPatch extends WorldFeature
             if(world.isAirBlock(x1, y1, z1) && Blocks.blocksList[blockId].canBlockStay(world, x1, y1, z1))
             {
                 world.setBlock(x1, y1, z1, blockId);
-                BlockLogicRubyglassGrowth.setDefaultDirection(world, new TilePos(x1, y1, z1));
+                BlockLogicRubyglassSprout.setDefaultDirection(world, new TilePos(x1, y1, z1));
             }
         }
 
diff --git a/game/core/src/main/resources/lang/en_US/item.lang b/game/core/src/main/resources/lang/en_US/item.lang
index 5b98af2c2..0368825e8 100644
--- a/game/core/src/main/resources/lang/en_US/item.lang
+++ b/game/core/src/main/resources/lang/en_US/item.lang
@@ -491,10 +491,10 @@ item.statue.pigman.desc=An ancient marble statue found in a long-forgotten place
 item.dough.name=Dough
 item.dough.desc=Uncooked dough. Can be baked into bread.
 
-item.rubyglass.crystal.cracked.name=Cracked Rubyglass Crystal
-item.rubyglass.crystal.cracked.desc=Cracked open and full of impurities. Must planted in Netherrack to purify.
-item.rubyglass.crystal.pure.name=Rubyglass Crystal
-item.rubyglass.crystal.pure.desc=A shard of sanguine crystal, perfectly intact and slightly translucent.
+item.rubyglass.crystal.cracked.name=Rubyglass Shards
+item.rubyglass.crystal.cracked.desc=Cracked and full of impurities. But still aesthetically pleasing.
+item.rubyglass.crystal.pure.name=Rubyglass
+item.rubyglass.crystal.pure.desc=A shard of charged Rubyglass crystal, brimming with energy. Perfectly intact and slightly translucent.
 
 item.sulfur.name=Sulfur
 item.sulfur.desc=Highly flammable and yellow. Packs a punch.
\ No newline at end of file
diff --git a/game/core/src/main/resources/lang/en_US/tile.lang b/game/core/src/main/resources/lang/en_US/tile.lang
index 163bee0e0..883ef3b6a 100644
--- a/game/core/src/main/resources/lang/en_US/tile.lang
+++ b/game/core/src/main/resources/lang/en_US/tile.lang
@@ -1409,13 +1409,17 @@ tile.glass.steel.desc=Like glass, but without the fragility.
 tile.rope.name=Rope
 tile.rope.desc=Rope, rope, rope your boat.
 
-tile.rubyglass.name=Block of Rubyglass
-tile.rubyglass.desc=A bright, iridescent crystal brimming with energy.
-tile.rubyglass.pure.name=Block of Pure Rubyglass
-tile.rubyglass.pure.desc=A bright, iridescent crystal brimming with energy. Contains fewer impurities than normal rubyglass.
+tile.rubyglass.column.name=Rubyglass Column
+tile.rubyglass.column.desc=A column of tightly packed Rubyglass. Breaks into dust when broken, but can be reassembled.
 
-tile.rubyglass.growth.name=Rubyglass Sprout
-tile.rubyglass.growth.desc=A small sprout of rubyglass, branching out in many directions.
+tile.rubyglass.node.name=Rubyglass Node
+tile.rubyglass.node.desc=A dense outcrop of Rubyglass. Crystals harvested from this node are purer and more durable than usual.
+
+tile.block.rubyglass.name=Block of Rubyglass
+tile.block.rubyglass.desc=A translucent glass-like crystal brimming with energy.
+
+tile.rubyglass.sprout.name=Rubyglass Bud
+tile.rubyglass.sprout.desc=A small bud of rubyglass, branching out in many directions. Can sprout from Crystalline Netherrack in the right conditions.
 
 tile.rubyglass.circuit.name=Rubyglass Circuit
 tile.rubyglass.circuit.desc=Netherrack etched with lines of rubyglass. It resonates with latent power.
diff --git a/util/datagen/src/main/java/net/minecraft/datagen/TrommelGenerator.java b/util/datagen/src/main/java/net/minecraft/datagen/TrommelGenerator.java
index 0aa619ea1..d6ba57395 100644
--- a/util/datagen/src/main/java/net/minecraft/datagen/TrommelGenerator.java
+++ b/util/datagen/src/main/java/net/minecraft/datagen/TrommelGenerator.java
@@ -78,7 +78,7 @@ public class TrommelGenerator {
             .addEntry(new WeightedRandomLootObject(new ItemStack(Items.ORE_RAW_GOLD), 1), 2)
             .addEntry(new WeightedRandomLootObject(new ItemStack(Items.ORE_RAW_IRON), 1), 1)
             .addEntry(new WeightedRandomLootObject(new ItemStack(Items.DUST_GLOWSTONE), 1, 6), 5)
-            .addEntry(new WeightedRandomLootObject(new ItemStack(Items.RUBYGLASS_CRYSTAL_CRACKED), 1, 3), 5)
+            .addEntry(new WeightedRandomLootObject(new ItemStack(Items.RUBYGLASS_DUST), 1, 3), 5)
             .addEntry(new WeightedRandomLootObject(new ItemStack(Items.NETHERCOAL), 1), 2)
             .create("soul_sand");
 
diff --git a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
index c498bb641..944946b8d 100644
--- a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
+++ b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
@@ -154,7 +154,7 @@ class WorkbenchGenerator {
                 "#R#")
             .addInput('#', Blocks.COBBLE_NETHERRACK)
             .addInput('S', Blocks.SOULSAND)
-            .addInput('N', Items.RUBYGLASS_CRYSTAL_PURE)
+            .addInput('N', Items.RUBYGLASS_CRYSTAL)
             .addInput('R', Items.DUST_REDSTONE)
             .create("activator", Blocks.ACTIVATOR_COBBLE_NETHERRACK.getDefaultStack());
 
@@ -1304,30 +1304,24 @@ class WorkbenchGenerator {
             )
             .addInput('#', Blocks.COBBLE_NETHERRACK)
             .addInput('Q', Items.QUARTZ)
-            .addInput('R', Items.RUBYGLASS_CRYSTAL_PURE)
+            .addInput('R', Items.RUBYGLASS_CRYSTAL)
             .addInput('S', Blocks.SOULSAND)
             .create("matcher", new ItemStack(Blocks.MATCHER, 1));
 
         RecipeBuilder.Shaped(CORE_NAMESPACE)
                 .setShape(
-                        "XX",
-                        "XX")
-                .addInput('X', Items.RUBYGLASS_CRYSTAL_CRACKED)
-                .create("rubyglass", new ItemStack(Blocks.RUBYGLASS, 1));
-
-        RecipeBuilder.Shaped(CORE_NAMESPACE)
-                .setShape(
-                        "XX",
-                        "XX")
-                .addInput('X', Items.RUBYGLASS_CRYSTAL_PURE)
-                .create("rubyglass_pure", new ItemStack(Blocks.RUBYGLASS_PURE, 1));
+                        "XXX",
+                        "XXX",
+                        "XXX")
+                .addInput('X', Items.RUBYGLASS_CRYSTAL)
+                .create("block_rubyglass", new ItemStack(Blocks.BLOCK_RUBYGLASS, 1));
 
         RecipeBuilder.Shaped(CORE_NAMESPACE)
                 .setShape(
                         "XOX",
                         "OOO",
                         "XOX")
-                .addInput('O', Items.RUBYGLASS_CRYSTAL_PURE)
+                .addInput('O', Items.RUBYGLASS_CRYSTAL)
                 .addInput('X', Blocks.COBBLE_NETHERRACK)
                 .create("rubyglass_circuit", new ItemStack(Blocks.RUBYGLASS_CIRCUIT, 1));
 
@@ -1337,7 +1331,7 @@ class WorkbenchGenerator {
                         "#RB",
                         "###")
                 .addInput('#', Blocks.COBBLE_NETHERRACK)
-                .addInput('R', Items.RUBYGLASS_CRYSTAL_PURE)
+                .addInput('R', Items.RUBYGLASS_CRYSTAL)
                 .addInput('B', Items.BONE)
                 .create("motion_sensor", Blocks.MOTION_SENSOR_IDLE.getDefaultStack());
     }
