diff --git a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
index 521dad50d..22dd15002 100644
--- a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
+++ b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
@@ -108,7 +108,7 @@ public class TextureManager {
 	}
 
 	protected void addNativeDynamicTextures(@NotNull TextureAnimation state) {
-		if (state != TextureAnimation.OFF) {addDynamicTexture(new DynamicTextureWaterStill(TextureRegistry.getTexture("minecraft:block/water_still")));
+		if (state != TextureAnimation.OFF) {addDynamicTexture(new DynamicTextureWaterStill(TextureRegistry.getTexture("minecraft:block/water_still"), TextureRegistry.getTexture("minecraft:block/water_overlay_boiling")));
 			addDynamicTexture(new DynamicTextureWaterFlow(TextureRegistry.getTexture("minecraft:block/water_flowing")));
 			addDynamicTexture(new DynamicTextureLavaStill(TextureRegistry.getTexture("minecraft:block/lava_still")));
 			addDynamicTexture(new DynamicTextureLavaFlowing(TextureRegistry.getTexture("minecraft:block/lava_flowing")));
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
index 70dab5980..14f8493b7 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
@@ -48,9 +48,6 @@ public final class BlockColorDispatcher
         addDispatch(Blocks.WIRE_REDSTONE, new BlockColorWireRedstone());
         addDispatch(Blocks.TALLGRASS, new BlockColorCustom(Colorizers.grass));
         addDispatch(Blocks.TALLGRASS_FERN, new BlockColorCustom(Colorizers.grass));
-        addDispatch(Blocks.RUBYGLASS, new BlockColorRubyglass(Colorizers.crystal));
-        addDispatch(Blocks.RUBYGLASS_PURE, new BlockColorRubyglass(Colorizers.crystal));
-        addDispatch(Blocks.RUBYGLASS_SPROUT, new BlockColorRubyglass(Colorizers.crystal));
     }
 
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorRubyglass.java b/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorRubyglass.java
deleted file mode 100644
index 0d4b712e7..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorRubyglass.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.minecraft.client.render.block.color;
-
-import net.minecraft.client.render.colorizer.Colorizer;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.noise.ImprovedPerlinNoise;
-import net.minecraft.core.world.pos.TilePosc;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Random;
-
-public class BlockColorRubyglass extends BlockColorCustom{
-
-    public BlockColorRubyglass(Colorizer colorizer) {
-        super(colorizer);
-    }
-
-    @Override
-    public int getFallbackColor(int meta, int tintIndex) {
-        return 0xFFC40E26;
-    }
-
-    @Override
-    public int getWorldColor(@NotNull WorldSource source, @NotNull TilePosc tilePos, int tintIndex) {
-
-        int color = 0xFFC40E26;
-        return color;
-    }
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java b/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
index e0557a2bf..c621582f7 100644
--- a/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
+++ b/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
@@ -42,7 +42,6 @@ public class Colorizers {
 	public static Colorizer cacao;
 	public static Colorizer thorn;
 	public static Colorizer palm;
-	public static Colorizer crystal;
 
 	private static Dimension lastDimension;
 	private static Season lastSeason;
@@ -88,7 +87,6 @@ public class Colorizers {
 		cacao = add(new Colorizer("cacao"));
 		thorn = add(new Colorizer("thorn"));
 		palm = add(new Colorizer("palm"));
-		crystal = add(new Colorizer("crystal"));
 	}
 	
 	public static void update(boolean force) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
index 17c8a725f..037cce9b5 100644
--- a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
+++ b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
@@ -3,6 +3,7 @@ package net.minecraft.client.render.dynamictexture;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
+import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.Dimension;
 import org.jetbrains.annotations.NotNull;
 
@@ -10,10 +11,10 @@ public class DynamicTextureWaterFlow extends DynamicTexture {
 	
 	private final Minecraft mc = Minecraft.getMinecraft();
 	
-	private float[] arr1;
-	private float[] arr2;
-	private float[] arr3;
-	private float[] arr4;
+	private float[] current;
+	private float[] next;
+	private float[] heat;
+	private float[] heata;
 	private int ticks = 0;
 
 	public DynamicTextureWaterFlow(@NotNull IconCoordinate targetTexture) {
@@ -24,78 +25,77 @@ public class DynamicTextureWaterFlow extends DynamicTexture {
 	public void postInit() {
 		initTexture();
 
-        this.arr1 = new float[this.targetTexture.getArea()];
-        this.arr2 = new float[this.targetTexture.getArea()];
-        this.arr3 = new float[this.targetTexture.getArea()];
-        this.arr4 = new float[this.targetTexture.getArea()];
+        this.current = new float[this.targetTexture.getArea()];
+        this.next = new float[this.targetTexture.getArea()];
+        this.heat = new float[this.targetTexture.getArea()];
+        this.heata = new float[this.targetTexture.getArea()];
 	}
 
 	@Override
 	public void update() {
 		this.ticks++;
 
-		float bright;
 		for (int x = 0; x < this.targetTexture.width; ++x) {
 			for (int y = 0; y < this.targetTexture.height; ++y) {
-				bright = 0.0F;
+				float pow = 0.0F;
 
 				for (int k = y - 2; k <= y; ++k) {
-					int r = pmod(x, this.targetTexture.width);
-					int g = pmod(k, this.targetTexture.height);
-					bright += this.arr1[r + g * this.targetTexture.width];
+					int xi = pmod(x, this.targetTexture.width);
+					int yi = pmod(k, this.targetTexture.height);
+					pow += this.current[xi + yi * this.targetTexture.width];
 				}
 
-				this.arr2[x + y * this.targetTexture.width] = bright / 3.2F + this.arr3[x + y * this.targetTexture.width] * 0.8F;
+				this.next[x + y * this.targetTexture.width] = pow / 3.2F + this.heat[x + y * this.targetTexture.width] * 0.8F;
 			}
 		}
 
 		for (int x = 0; x < this.targetTexture.width; ++x) {
 			for (int y = 0; y < this.targetTexture.height; ++y) {
-				this.arr3[x + y * this.targetTexture.width] += this.arr4[x + y * this.targetTexture.width] * 0.05F;
-				if (this.arr3[x + y * this.targetTexture.width] < 0.0F) {
-					this.arr3[x + y * this.targetTexture.width] = 0.0F;
+				this.heat[x + y * this.targetTexture.width] += this.heata[x + y * this.targetTexture.width] * 0.05F;
+				if (this.heat[x + y * this.targetTexture.width] < 0.0F) {
+					this.heat[x + y * this.targetTexture.width] = 0.0F;
 				}
 
-				this.arr4[x + y * this.targetTexture.width] -= 0.3F;
+				this.heata[x + y * this.targetTexture.width] -= 0.3F;
 				if (Math.random() < 0.2D) {
-					this.arr4[x + y * this.targetTexture.width] = 0.5F;
+					this.heata[x + y * this.targetTexture.width] = 0.5F;
 				}
 			}
 		}
 
-		float[] var12 = this.arr2;
-		this.arr2 = this.arr1;
-		this.arr1 = var12;
+		float[] tmp = this.next;
+		this.next = this.current;
+		this.current = tmp;
 
 		for (int i = 0; i < this.targetTexture.getArea(); ++i) {
-			bright = this.arr1[pmod(i - this.ticks * this.targetTexture.width, this.targetTexture.getArea())];
-			if (bright > 1.0F) {
-				bright = 1.0F;
+			float pow = this.current[pmod(i - this.ticks * this.targetTexture.width, this.targetTexture.getArea())];
+			if (pow > 1.0F) {
+				pow = 1.0F;
 			}
 
-			if (bright < 0.0F) {
-				bright = 0.0F;
+			if (pow < 0.0F) {
+				pow = 0.0F;
 			}
 
-			float var13 = bright * bright;
+			float pp = pow * pow;
 
-			int colorMax = 255;
-			int colorMid = (int) (50.0F + var13 * 64.0F);
-			int colorMin = (int) (32.0F + var13 * 32.0F);
-
-			int r = colorMin;
-			int g = colorMid;
-			int b = colorMax;
-			int a = (int) (146.0F + var13 * 50.0F);
+			int r = (int) (32.0F + pp * 32.0F);
+			int g = (int) (50.0F + pp * 64.0F);
+			int b = 255;
+			int a = (int) (146.0F + pp * 50.0F);
 
 			if (this.mc.currentWorld != null && this.mc.currentWorld.dimension == Dimension.NETHER) {
-				float brightness = 0.75F;
-				r = (int) (255 * brightness);
-				g = (int) (colorMin * brightness);
-				b = (int) (colorMin * brightness);
-				a = (int) (225.0F + var13 * 25.0F);
+				r = 255;
+				g = (int) (110.0F + pp * 64.0F);
+				b = (int) (32.0F + pp * 32.0F);
+				a = (int) (225.0F + pp * 50.0F);
 			}
 
+			r = MathHelper.clamp(r, 0, 255);
+			g = MathHelper.clamp(g, 0, 255);
+			b = MathHelper.clamp(b, 0, 255);
+			a = MathHelper.clamp(a, 0, 255);
+
 			if (GameSettings.BIOME_WATER.value && !(this.mc.currentWorld != null && this.mc.currentWorld.isRetro())) {
 				r = g = b = (r + g + b) / 3;
 			}
diff --git a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
index c0298615b..20f951f0f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
+++ b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
@@ -3,98 +3,111 @@ package net.minecraft.client.render.dynamictexture;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
+import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.Dimension;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.image.BufferedImage;
 
 public class DynamicTextureWaterStill extends DynamicTexture {
 	
 	private final Minecraft mc = Minecraft.getMinecraft();
 
-	private float[] arr1;
-	private float[] arr2;
-	private float[] arr3;
-	private float[] arr4;
+	private float @NotNull [] current;
+	private float @NotNull [] next;
+	private float @NotNull [] heat;
+	private float @NotNull [] heata;
+
+	private final @NotNull IconCoordinate boilingTexture;
 
-	public DynamicTextureWaterStill(IconCoordinate targetTexture) {
+	public DynamicTextureWaterStill(
+		final @NotNull IconCoordinate targetTexture,
+		final @NotNull IconCoordinate boilingTexture
+	) {
 		super(targetTexture);
-	}
+
+		this.boilingTexture = boilingTexture;
+
+        this.current = new float[0];
+		this.next = new float[0];
+		this.heat = new float[0];
+		this.heata = new float[0];
+    }
 
 	@Override
 	public void postInit() {
-		initTexture();
+		this.initTexture();
 
-        this.arr1 = new float[this.targetTexture.getArea()];
-        this.arr2 = new float[this.targetTexture.getArea()];
-        this.arr3 = new float[this.targetTexture.getArea()];
-        this.arr4 = new float[this.targetTexture.getArea()];
+        this.current = new float[this.targetTexture.getArea()];
+        this.next = new float[this.targetTexture.getArea()];
+        this.heat = new float[this.targetTexture.getArea()];
+        this.heata = new float[this.targetTexture.getArea()];
 	}
 
 	@Override
 	public void update() {
-		int y;
-		float bright;
-		int a_;
-		int b_;
 		for (int x = 0; x < this.targetTexture.width; ++x) {
-			for (y = 0; y < this.targetTexture.height; ++y) {
-				bright = 0.0F;
+			for (int y = 0; y < this.targetTexture.height; ++y) {
+				float pow = 0.0F;
 
-				for (int k = x - 1; k <= x + 1; ++k) {
-					a_ = pmod(k, this.targetTexture.width);
-					b_ = pmod(y, this.targetTexture.height);
-					bright += this.arr1[a_ + b_ * this.targetTexture.width];
+				for (int xx = x - 1; xx <= x + 1; ++xx) {
+					final int xi = pmod(xx, this.targetTexture.width);
+					final int yi = pmod(y, this.targetTexture.height);
+					pow += this.current[xi + yi * this.targetTexture.width];
 				}
 
-				this.arr2[x + y * this.targetTexture.width] = bright / 3.3F + this.arr3[x + y * this.targetTexture.width] * 0.8F;
+				this.next[x + y * this.targetTexture.width] = pow / 3.3F + this.heat[x + y * this.targetTexture.width] * 0.8F;
 			}
 		}
 
 		for (int x = 0; x < this.targetTexture.width; ++x) {
-			for (y = 0; y < this.targetTexture.height; ++y) {
-				this.arr3[x + y * this.targetTexture.width] += this.arr4[x + y * this.targetTexture.width] * 0.05F;
-				if (this.arr3[x + y * this.targetTexture.width] < 0.0F) {
-					this.arr3[x + y * this.targetTexture.width] = 0.0F;
+			for (int y = 0; y < this.targetTexture.height; ++y) {
+				this.heat[x + y * this.targetTexture.width] += this.heata[x + y * this.targetTexture.width] * 0.05F;
+				if (this.heat[x + y * this.targetTexture.width] < 0.0F) {
+					this.heat[x + y * this.targetTexture.width] = 0.0F;
 				}
 
-				this.arr4[x + y * this.targetTexture.width] -= 0.1F;
+				this.heata[x + y * this.targetTexture.width] -= 0.1F;
 				if (Math.random() < 0.05D) {
-					this.arr4[x + y * this.targetTexture.width] = 0.5F;
+					this.heata[x + y * this.targetTexture.width] = 0.5F;
 				}
 			}
 		}
 
-		float[] var12 = this.arr2;
-		this.arr2 = this.arr1;
-		this.arr1 = var12;
+		final float[] tmp = this.next;
+		this.next = this.current;
+		this.current = tmp;
 
 		for (int i = 0; i < this.targetTexture.getArea(); ++i) {
-			bright = this.arr1[i];
-			if (bright > 1.0F) {
-				bright = 1.0F;
+			float pow = this.current[i];
+			if (pow > 1.0F) {
+				pow = 1.0F;
 			}
 
-			if (bright < 0.0F) {
-				bright = 0.0F;
+			if (pow < 0.0F) {
+				pow = 0.0F;
 			}
 
-			float var13 = bright * bright;
-
-			int colorMax = 255;
-			int colorMid = (int) (50.0F + var13 * 64.0F);
-			int colorMin = (int) (32.0F + var13 * 32.0F);
+			float pp = pow * pow;
 
-			int r = colorMin;
-			int g = colorMid;
-			int b = colorMax;
-			int a = (int) (146.0F + var13 * 50.0F);
+			int r = (int) (32.0F + pp * 32.0F);
+			int g = (int) (50.0F + pp * 64.0F);
+			int b = 255;
+			int a = (int) (146.0F + pp * 50.0F);
 
 			if (this.mc.currentWorld != null && this.mc.currentWorld.dimension == Dimension.NETHER) {
-				float brightness = 0.75F;
-				r = (int) (255 * brightness);
-				g = (int) (colorMin * brightness);
-				b = (int) (colorMin * brightness);
-				a = (int) (225.0F + var13 * 25.0F);
+				r = 255;
+				g = (int) (110.0F + pp * 64.0F);
+				b = (int) (32.0F + pp * 32.0F);
+				a = (int) (225.0F + pp * 50.0F);
 			}
 
+			r = MathHelper.clamp(r, 0, 255);
+			g = MathHelper.clamp(g, 0, 255);
+			b = MathHelper.clamp(b, 0, 255);
+			a = MathHelper.clamp(a, 0, 255);
+
 			if (GameSettings.BIOME_WATER.value && !(this.mc.currentWorld != null && this.mc.currentWorld.isRetro())) {
 				r = g = b = (r + g + b) / 3;
 			}
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
new file mode 100644
index 000000000..da21eabfe
Binary files /dev/null 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/rubyglass/block.png b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block.png
index bdd770de5..6c83619ef 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block.png and b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/block.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 b2bffdea0..9a35b9804 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/growth.png b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/growth.png
deleted file mode 100644
index 84818536a..000000000
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/growth.png and /dev/null differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/growth.emiss.png b/game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/sprout.emiss.png
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/growth.emiss.png
rename to game/client/src/main/resources/assets/minecraft/textures/block/rubyglass/sprout.emiss.png
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
new file mode 100644
index 000000000..f26906ddb
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/block/water_overlay_boiling.png differ
