diff --git a/game/client/src/main/java/net/minecraft/client/Minecraft.java b/game/client/src/main/java/net/minecraft/client/Minecraft.java
index 2eac4866e..5e23a8e05 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -3,7 +3,6 @@ package net.minecraft.client;
 import static org.lwjgl.opengl.GL11.*;
 
 import java.awt.Cursor;
-import java.awt.Desktop;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.io.File;
@@ -24,15 +23,19 @@ import net.minecraft.client.gui.*;
 import net.minecraft.client.gui.achievements.ScreenAchievements;
 import net.minecraft.client.gui.chat.ScreenChat;
 import net.minecraft.client.gui.chat.ScreenSleepMP;
+import net.minecraft.client.gui.error.ScreenBadJavaArch;
+import net.minecraft.client.gui.error.ScreenConflictWarning;
+import net.minecraft.client.gui.error.ScreenMissingJCE;
+import net.minecraft.client.gui.error.ScreenMissingMinecraft;
+import net.minecraft.client.gui.error.ScreenOutOfMemory;
 import net.minecraft.client.gui.options.data.OptionsPages;
 import net.minecraft.client.gui.toasts.GuiElementToastsHud;
 import net.minecraft.client.holiday.Holidays;
 import net.minecraft.client.net.handler.PacketHandlerClient;
 import net.minecraft.client.render.block.model.BlockModelGrass;
-import net.minecraft.client.render.font.FontDefault;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.font.FontRendererDefault;
-import net.minecraft.client.render.font.Fonts;
+import net.minecraft.client.util.helper.UrlHelper;
 import net.minecraft.client.world.WorldClient;
 import net.minecraft.client.world.chunk.provider.ChunkProviderStatic;
 import net.minecraft.core.achievement.Achievements;
@@ -70,6 +73,7 @@ import net.minecraft.core.net.command.commands.CommandTestFor;
 import net.minecraft.core.net.command.commands.CommandTime;
 import net.minecraft.core.net.command.commands.CommandWeather;
 import net.minecraft.core.net.command.util.CommandHelper;
+import net.minecraft.core.util.helper.AES;
 import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.util.helper.LoggedPrintStream;
 import net.minecraft.core.util.helper.UUIDHelper;
@@ -444,11 +448,7 @@ public class Minecraft
                             addMouseListener(new MouseAdapter() {
                                 @Override
                                 public void mouseClicked(MouseEvent e) {
-                                    try {
-                                        Desktop.getDesktop().browse(new URL("https://www.betterthanadventure.net/installation-guide/").toURI());
-                                    } catch (Exception ex) {
-                                        LOGGER.error("Exception occurred when attempting to open URL 'https://www.betterthanadventure.net/installation-guide/'!", ex);
-                                    }
+                                    UrlHelper.openURL("https://www.betterthanadventure.net/installation-guide/");
                                 }
                             });
                         }
@@ -665,11 +665,20 @@ public class Minecraft
         } catch (Exception e){
             hasBeta173 = false;
         }
+        
+        boolean hasJCE;
+        try {
+            AES.encrypt("I hate that prism defaults BTA to 8u51.", AES.generateKey());
+            hasJCE = true;
+        }catch (final Exception ignored) {
+            hasJCE = false;
+        }
 
         if (!hasBeta173) {
             displayScreen(new ScreenMissingMinecraft());
-        }
-        else if (System.getProperty("sun.arch.data.model").equals("32"))
+        } else if (!hasJCE) {
+            displayScreen(new ScreenMissingJCE());
+        } else if (System.getProperty("sun.arch.data.model").equals("32"))
         {
             displayScreen(new ScreenBadJavaArch());
         }
diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
index 9421d05ab..106146013 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
@@ -8,6 +8,7 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.entity.particle.ParticlePickupAnimation;
 import net.minecraft.client.gui.container.ScreenActivator;
 import net.minecraft.client.gui.container.ScreenContainer;
+import net.minecraft.client.gui.container.ScreenContainerAbstract;
 import net.minecraft.client.gui.container.ScreenCrafting;
 import net.minecraft.client.gui.container.ScreenDispenser;
 import net.minecraft.client.gui.container.ScreenFlagEditor;
@@ -158,7 +159,7 @@ public class PlayerLocal extends Player
             {
                 startRiding(null);
             }
-            if(mc.currentScreen != null)
+            if(mc.currentScreen instanceof ScreenContainerAbstract) // Close out of containers like the inventory
             {
                 mc.displayScreen(null);
             }
diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
index fd45c7366..08aa7c4c9 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
@@ -240,18 +240,6 @@ public class PlayerLocalMultiplayer extends PlayerLocal implements Player.Player
         }
     }
 
-    @Override
-	public void addStat(Stat stat, int i)
-    {
-        if(stat == null) {
-            return;
-        }
-        if(!stat.clientside)
-        {
-            super.addStat(stat, i);
-        }
-    }
-    
     @Override
 	public int getStat(Stat stat)
     {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java
index 75f028ae1..748b1fce5 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenMainMenu.java
@@ -1,11 +1,9 @@
 package net.minecraft.client.gui;
 
-import java.awt.Desktop;
 import java.awt.image.BufferedImage;
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.net.URI;
 import java.nio.charset.StandardCharsets;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -23,6 +21,7 @@ import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.client.util.helper.UrlHelper;
 import net.minecraft.core.Version;
 import org.lwjgl.input.Keyboard;
 import org.lwjgl.opengl.GL11;
@@ -229,39 +228,17 @@ public class ScreenMainMenu extends Screen
         if(button.id == 10){
             mc.displayScreen(new ScreenOptions(this, OptionsPages.DEBUG));
         }
-        Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
-        if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE))
+        if (button.id == 6) // Website
         {
-            if (button.id == 6) // Website
-            {
-                try
-                {
-                    desktop.browse(URI.create("https://betterthanadventure.net"));
-                } catch (Exception e)
-                {
-                    LOGGER.error("Exception occurred when attempting to open URL 'https://betterthanadventure.net'!", e);
-                }
-            }
-            if (button.id == 7) // Discord
-            {
-                try
-                {
-                    desktop.browse(URI.create("https://betterthanadventure.net/discord"));
-                } catch (Exception e)
-                {
-                    LOGGER.error("Exception occurred when attempting to open URL 'https://betterthanadventure.net/discord'!", e);
-                }
-            }
-            if (button.id == 8) // YouTube
-            {
-                try
-                {
-                    desktop.browse(URI.create("https://www.youtube.com/channel/UC_GT4t8Io87-UTzaGNnsuMg"));
-                } catch (Exception e)
-                {
-                    LOGGER.error("Exception occurred when attempting to open URL 'https://www.youtube.com/channel/UC_GT4t8Io87-UTzaGNnsuMg'!", e);
-                }
-            }
+            UrlHelper.openURL("https://betterthanadventure.net");
+        }
+        if (button.id == 7) // Discord
+        {
+            UrlHelper.openURL("https://betterthanadventure.net/discord");
+        }
+        if (button.id == 8) // YouTube
+        {
+            UrlHelper.openURL("https://www.youtube.com/channel/UC_GT4t8Io87-UTzaGNnsuMg");
         }
     }
 
@@ -378,9 +355,11 @@ public class ScreenMainMenu extends Screen
     		b = b * 0.2 + 0.8;
     		int ib = (int) java.lang.Math.round(b * 255);
     		int color = 0xFF000000 + (ib << 16) + (ib << 8) + (ib);
-            drawStringCenteredShadow(mc.font,
-                i18n.translateKeyAndFormat("gui.main_menu.label.downloading_resources", mc.downloadResourcesThread.downloadProgress.get(), mc.downloadResourcesThread.toDownload),
-                width / 2, 16, color);
+
+            drawStringCenteredShadow(
+                mc.font, i18n.translateKeyAndFormat("gui.main_menu.label.downloading_resources.1", mc.downloadResourcesThread.downloadProgress.get(), mc.downloadResourcesThread.toDownload),
+                width / 2, 8, color);
+            drawStringCenteredShadow(mc.font, i18n.translateKey("gui.main_menu.label.downloading_resources.2"), width / 2, 17, color);
     	}
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenPhotoMode.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenPhotoMode.java
index e26e6b12b..119fc21d8 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenPhotoMode.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenPhotoMode.java
@@ -444,7 +444,7 @@ public class ScreenPhotoMode extends Screen
         if(Shaders.enableShaders) {
             if (sliderIntensity.dragging)
             {
-                intensityValue = sliderIntensity.sliderValue;
+                intensityValue = (float) sliderIntensity.sliderValue;
                 updateButtonsText();
             }
         }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/SliderElement.java b/game/client/src/main/java/net/minecraft/client/gui/SliderElement.java
index 0f323dda2..4f47c75eb 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/SliderElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/SliderElement.java
@@ -2,6 +2,7 @@ package net.minecraft.client.gui;
 
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
+import org.lwjgl.input.Mouse;
 import org.lwjgl.opengl.GL11;
 
 import net.minecraft.client.Minecraft;
@@ -9,7 +10,7 @@ import net.minecraft.client.option.OptionFloat;
 
 public class SliderElement extends ButtonElement {
 
-	public float sliderValue;
+	public double sliderValue;
 	public boolean dragging;
 	private final OptionFloat option;
 	public IconCoordinate backgroundTexture;
@@ -45,8 +46,9 @@ public class SliderElement extends ButtonElement {
 		if(!visible) {
 			return;
 		}
+		final double realMouseX = (double) (Mouse.getX() * mc.resolution.getScaledWidthScreenCoords()) / mc.resolution.getWidthScreenCoords();
 		if(dragging) {
-			sliderValue = (float) (mouseX - (xPosition + 4)) / (float) (width - 8);
+			sliderValue = (realMouseX - (xPosition + 4)) / (float) (width - 8);
 			if(sliderValue < 0.0F) {
 				sliderValue = 0.0F;
 			}
@@ -54,7 +56,7 @@ public class SliderElement extends ButtonElement {
 				sliderValue = 1.0F;
 			}
 			if(option != null) {
-				option.set(sliderValue);
+				option.set((float) sliderValue);
 				displayString = option.getDisplayString();
 			}
 		}
@@ -108,7 +110,8 @@ public class SliderElement extends ButtonElement {
 	@Override
 	public boolean mouseClicked(Minecraft mc, int mouseX, int mouseY) {
 		if(super.mouseClicked(mc, mouseX, mouseY)) {
-			sliderValue = (float) (mouseX - (xPosition + 4)) / (float) (width - 8);
+			final double realMouseX = (double) (Mouse.getX() * mc.resolution.getScaledWidthScreenCoords()) / mc.resolution.getWidthScreenCoords();
+			sliderValue = (realMouseX - (xPosition + 4)) / (float) (width - 8);
 			if(sliderValue < 0.0F) {
 				sliderValue = 0.0F;
 			}
@@ -116,7 +119,7 @@ public class SliderElement extends ButtonElement {
 				sliderValue = 1.0F;
 			}
 			if(option != null) {
-				option.set(sliderValue);
+				option.set((float) sliderValue);
 				displayString = option.getDisplayString();
 			}
 			dragging = true;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java b/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java
index d64dcbbd0..89cc167c3 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java
@@ -8,9 +8,11 @@ import com.mojang.brigadier.StringReader;
 import com.mojang.brigadier.context.CommandContextBuilder;
 import com.mojang.brigadier.context.ParsedArgument;
 import com.mojang.brigadier.context.StringRange;
+import com.mojang.brigadier.context.SuggestionContext;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.brigadier.suggestion.Suggestion;
 import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 import com.mojang.brigadier.tree.CommandNode;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import com.mojang.logging.LogUtils;
@@ -35,6 +37,7 @@ import org.slf4j.Logger;
 import java.awt.*;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
@@ -239,7 +242,7 @@ public class GuiElementChatSuggestions extends Gui {
                 this.parseResults = dispatcher.parse(stringReader, this.commandSource);
             }
             if (cursor >= 1 || text.isEmpty()) {
-                this.pendingSuggestions = dispatcher.getCompletionSuggestions(this.parseResults, cursor);
+                this.pendingSuggestions = getCompletionSuggestionsReal(this.commandSource, this.parseResults, cursor);
                 this.pendingSuggestions.thenRun(() -> {
                     if (this.pendingSuggestions.isDone()) {
                         this.finishUpdatingSuggestions();
@@ -249,6 +252,42 @@ public class GuiElementChatSuggestions extends Gui {
         }
     }
 
+    // Because the command dispatcher's doesn't take into account if the user can use a node this is required
+    private <S> CompletableFuture<Suggestions> getCompletionSuggestionsReal(final S source, final ParseResults<S> parse, final int cursor) {
+        final CommandContextBuilder<S> context = parse.getContext();
+
+        final SuggestionContext<S> nodeBeforeCursor = context.findSuggestionContext(cursor);
+        final CommandNode<S> parent = nodeBeforeCursor.parent;
+        final int start = Math.min(nodeBeforeCursor.startPos, cursor);
+
+        final String fullInput = parse.getReader().getString();
+        final String truncatedInput = fullInput.substring(0, cursor);
+        final String truncatedInputLowerCase = truncatedInput.toLowerCase(Locale.ROOT);
+        @SuppressWarnings("unchecked") final CompletableFuture<Suggestions>[] futures = new CompletableFuture[parent.getChildren().size()];
+        int i = 0;
+        for (final CommandNode<S> node : parent.getChildren()) {
+            CompletableFuture<Suggestions> future = Suggestions.empty();
+            if (node.canUse(source)) {
+                try {
+                    future = node.listSuggestions(context.build(truncatedInput), new SuggestionsBuilder(truncatedInput, truncatedInputLowerCase, start));
+                } catch (final CommandSyntaxException ignored) {
+                }
+            }
+            futures[i++] = future;
+        }
+
+        final CompletableFuture<Suggestions> result = new CompletableFuture<>();
+        CompletableFuture.allOf(futures).thenRun(() -> {
+            final List<Suggestions> suggestions = new ArrayList<>();
+            for (final CompletableFuture<Suggestions> future : futures) {
+                suggestions.add(future.join());
+            }
+            result.complete(Suggestions.merge(fullInput, suggestions));
+        });
+
+        return result;
+    }
+
     private boolean shouldApplySuggestion(final char c, final int key) {
         return this.textField.isCharacterAllowed(c)
             || ((key == Keyboard.KEY_C || key == Keyboard.KEY_V) && (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)))
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
index 776ac4e5d..37190beac 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
@@ -10,6 +10,7 @@ import net.minecraft.client.gui.GuiElement;
 import net.minecraft.client.gui.ListLayout;
 import net.minecraft.client.gui.options.OverlayButtonElement;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.render.entity.EntityRenderer;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.entity.player.Player;
@@ -284,7 +285,9 @@ public class ScreenInventory extends ScreenContainerAbstract
         mc.thePlayer.entityBrightness = 1.0F;
         GL11.glTranslatef(0.0F, mc.thePlayer.heightOffset, 0.0F);
         EntityRenderDispatcher.instance.viewLerpYaw = 180F;
+        EntityRenderer.renderShadows = false;
         EntityRenderDispatcher.instance.renderEntityWithPosYaw(Tessellator.instance, mc.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F);
+        EntityRenderer.renderShadows = true;
         mc.thePlayer.entityBrightness = 0.0F;
         mc.thePlayer.yBodyRot = f2;
         mc.thePlayer.yRot = f3;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java
index a41a7ab13..c4f5c3e97 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventoryCreative.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.container;
 import net.minecraft.client.gui.ButtonElement;
 import net.minecraft.client.gui.TextFieldElement;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.render.entity.EntityRenderer;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.client.gui.options.OptionsButtonElement;
@@ -212,8 +213,10 @@ public class ScreenInventoryCreative extends ScreenInventory implements ITextCha
         mc.thePlayer.entityBrightness = 1.0F;
         GL11.glTranslatef(0.0F, mc.thePlayer.heightOffset, 0.0F);
         EntityRenderDispatcher.instance.viewLerpYaw = 180F;
+		EntityRenderer.renderShadows = false;
         EntityRenderDispatcher.instance.renderEntityWithPosYaw(Tessellator.instance, mc.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F);
-        mc.thePlayer.entityBrightness = 0.0F;
+		EntityRenderer.renderShadows = true;
+		mc.thePlayer.entityBrightness = 0.0F;
         mc.thePlayer.yBodyRot = f2;
         mc.thePlayer.yRot = f3;
         mc.thePlayer.xRot = f4;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenBadJavaArch.java b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenBadJavaArch.java
similarity index 70%
rename from game/client/src/main/java/net/minecraft/client/gui/ScreenBadJavaArch.java
rename to game/client/src/main/java/net/minecraft/client/gui/error/ScreenBadJavaArch.java
index f00bb7674..1ca47a171 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenBadJavaArch.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenBadJavaArch.java
@@ -1,17 +1,15 @@
-package net.minecraft.client.gui;
+package net.minecraft.client.gui.error;
 
-import com.mojang.logging.LogUtils;
+import net.minecraft.client.gui.ButtonElement;
+import net.minecraft.client.gui.ClickableLabelElement;
+import net.minecraft.client.gui.Screen;
+import net.minecraft.client.gui.ScreenMainMenu;
+import net.minecraft.client.util.helper.UrlHelper;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.util.helper.MathHelper;
-import org.slf4j.Logger;
-
-import java.awt.*;
-import java.net.URI;
 
 public class ScreenBadJavaArch extends Screen
 {
-    private static final Logger LOGGER = LogUtils.getLogger();
-
     public ScreenBadJavaArch()
     {
     }
@@ -37,20 +35,9 @@ public class ScreenBadJavaArch extends Screen
         {
             mc.displayScreen(new ScreenMainMenu());
         }
-        Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
-        if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE))
+        if (button.id == 1)
         {
-            if (button.id == 1)
-            {
-                try
-                {
-                    desktop.browse(URI.create("https://adoptium.net/en-GB/temurin/releases/?version=8"));
-                }
-                catch (Exception e)
-                {
-                    LOGGER.error("Exception occurred when attempting to open URL 'https://adoptium.net/en-GB/temurin/releases/?version=8'!", e);
-                }
-            }
+            UrlHelper.openURL("https://adoptium.net/en-GB/temurin/releases/?version=8");
         }
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenConflictWarning.java b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenConflictWarning.java
similarity index 89%
rename from game/client/src/main/java/net/minecraft/client/gui/ScreenConflictWarning.java
rename to game/client/src/main/java/net/minecraft/client/gui/error/ScreenConflictWarning.java
index e3da98477..9dc92c1b4 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenConflictWarning.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenConflictWarning.java
@@ -1,5 +1,8 @@
-package net.minecraft.client.gui;
+package net.minecraft.client.gui.error;
 
+import net.minecraft.client.gui.ButtonElement;
+import net.minecraft.client.gui.Screen;
+import net.minecraft.client.gui.ScreenMainMenu;
 import net.minecraft.core.lang.I18n;
 
 public class ScreenConflictWarning extends Screen
diff --git a/game/client/src/main/java/net/minecraft/client/gui/error/ScreenMissingJCE.java b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenMissingJCE.java
new file mode 100644
index 000000000..dcdc23097
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenMissingJCE.java
@@ -0,0 +1,86 @@
+package net.minecraft.client.gui.error;
+
+import com.mojang.logging.LogUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.enums.EnumGPUVendor;
+import net.minecraft.client.gui.ButtonElement;
+import net.minecraft.client.gui.ClickableLabelElement;
+import net.minecraft.client.gui.Screen;
+import net.minecraft.client.gui.ScreenMainMenu;
+import net.minecraft.client.util.helper.UrlHelper;
+import net.minecraft.core.lang.I18n;
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+
+import java.awt.*;
+import java.net.URI;
+
+public class ScreenMissingJCE extends Screen {
+    private static final Logger LOGGER = LogUtils.getLogger();
+
+    protected ButtonElement continueButton = null;
+    protected ButtonElement downloadButton = null;
+    protected ButtonElement upgradeButton = null;
+
+    @Override
+    public void init()
+    {
+        final I18n i = I18n.getInstance();
+        this.buttons.clear();
+        final String downloadString = i.translateKey("gui.no_jce.button.download");
+        final String patchString = i.translateKey("gui.no_jce.button.upgrade");
+        this.continueButton = this.add(new ButtonElement(0, this.width / 2 - 100, this.height / 4 + 120 + 12, i.translateKey("gui.no_jce.button.continue")));
+        this.downloadButton = this.add(new ClickableLabelElement(1, this.width / 2 - 170, (this.height / 4 - 60) + 60 + 64, downloadString, 0x7C99EA));
+        this.upgradeButton = this.add(new ClickableLabelElement(2, this.width / 2 - 170, (this.height / 4 - 60) + 60 + 77, patchString, 0x7C99EA));
+    }
+
+    @Override
+    protected void buttonClicked(final ButtonElement button)
+    {
+        if(!button.enabled)
+        {
+            return;
+        }
+        if(button.id == 0)
+        {
+            this.mc.displayScreen(new ScreenMainMenu());
+        }
+        if (button.id == 1)
+        {
+            UrlHelper.openURL("https://adoptium.net/en-GB/temurin/releases/?version=8");
+        }
+        if (button.id == 2) {
+            UrlHelper.openURL("https://www.oracle.com/java/technologies/javase-jce-all-downloads.html");
+        }
+    }
+
+    @Override
+    public void render(final int mx, final int my, final float partialTick)
+    {
+        final I18n i = I18n.getInstance();
+        renderBackground();
+        drawStringCenteredShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.title"), this.width / 2, (this.height / 4 - 60) + 20, 0xffffff);
+        drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.1"), this.width / 2 - 170, (this.height / 4 - 60) + 60, 0xa0a0a0);
+        drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.2"), this.width / 2 - 170, (this.height / 4 - 60) + 60 + 18, 0xa0a0a0);
+        drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.3"), this.width / 2 - 170, (this.height / 4 - 60) + 60 + 27, 0xa0a0a0);
+        drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.4"), this.width / 2 - 170, (this.height / 4 - 60) + 60 + 45, 0xa0a0a0);
+        drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.5"), this.width / 2 - 170, (this.height / 4 - 60) + 60 + 54, 0xa0a0a0);
+        if (Minecraft.GPU_VENDOR == EnumGPUVendor.INTEL) {
+            drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.intel.disclaimer.1"), this.width / 2 - 170, (this.height / 4 - 60) + 60 + 72, 0xa0a0a0);
+            drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.intel.disclaimer.2"), this.width / 2 - 170, (this.height / 4 - 60) + 60 + 81, 0xa0a0a0);
+            drawStringShadow(this.fontRenderer, i.translateKey("gui.no_jce.label.body.intel.disclaimer.3"), this.width / 2 - 170, (this.height / 4 - 60) + 60 + 90, 0xa0a0a0);
+            this.downloadButton.yPosition = (this.height / 4 - 60) + 60 + 100;
+            this.downloadButton.displayString = i.translateKey("gui.no_jce.button.download");
+            this.upgradeButton.yPosition = (this.height / 4 - 60) + 60 + 113;
+            this.upgradeButton.displayString = i.translateKey("gui.no_jce.button.upgrade.recommended");
+        } else {
+            this.downloadButton.yPosition = (this.height / 4 - 60) + 60 + 64;
+            this.downloadButton.displayString = i.translateKey("gui.no_jce.button.download.recommended");
+            this.upgradeButton.yPosition = (this.height / 4 - 60) + 60 + 77;
+            this.upgradeButton.displayString = i.translateKey("gui.no_jce.button.upgrade");
+        }
+        this.continueButton.drawButton(this.mc, mx, my);
+        this.downloadButton.drawButton(this.mc, mx, my);
+        this.upgradeButton.drawButton(this.mc, mx, my);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenMissingMinecraft.java b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenMissingMinecraft.java
similarity index 81%
rename from game/client/src/main/java/net/minecraft/client/gui/ScreenMissingMinecraft.java
rename to game/client/src/main/java/net/minecraft/client/gui/error/ScreenMissingMinecraft.java
index 9f5a24383..6ecf5780e 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenMissingMinecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenMissingMinecraft.java
@@ -1,7 +1,11 @@
-package net.minecraft.client.gui;
+package net.minecraft.client.gui.error;
 
 import com.mojang.logging.LogUtils;
+import net.minecraft.client.gui.ButtonElement;
+import net.minecraft.client.gui.ClickableLabelElement;
+import net.minecraft.client.gui.Screen;
 import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.client.util.helper.UrlHelper;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.util.helper.MathHelper;
 import org.lwjgl.opengl.GL11;
@@ -48,26 +52,10 @@ public class ScreenMissingMinecraft extends Screen {
         {
             mc.shutdown();
         }
-        Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
-        if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE))
-        {
-            if (button.id == 1)
-            {
-                try
-                {
-                    desktop.browse(URI.create("https://www.betterthanadventure.net/installation-guide/"));
-                }
-                catch (Exception e)
-                {
-                    LOGGER.error("Exception occurred when attempting to open URL 'https://www.betterthanadventure.net/installation-guide/'!", e);
-                }
-            } else if (button.id == 2) {
-                try {
-                    desktop.browse(URI.create("https://betterthanadventure.net/discord"));
-                } catch (Exception e){
-                    LOGGER.error("Exception occurred when attempting to open URL 'https://betterthanadventure.net/discord'!", e);
-                }
-            }
+        if (button.id == 1) {
+            UrlHelper.openURL("https://www.betterthanadventure.net/installation-guide/");
+        } else if (button.id == 2) {
+            UrlHelper.openURL("https://betterthanadventure.net/discord");
         }
     }
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenOutOfMemory.java b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenOutOfMemory.java
similarity index 94%
rename from game/client/src/main/java/net/minecraft/client/gui/ScreenOutOfMemory.java
rename to game/client/src/main/java/net/minecraft/client/gui/error/ScreenOutOfMemory.java
index 4e49474a1..82b899b8c 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenOutOfMemory.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/error/ScreenOutOfMemory.java
@@ -1,5 +1,6 @@
-package net.minecraft.client.gui;
+package net.minecraft.client.gui.error;
 
+import net.minecraft.client.gui.Screen;
 import net.minecraft.core.lang.I18n;
 
 public class ScreenOutOfMemory extends Screen
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
index 510108ee0..3d47aacdc 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
@@ -649,6 +649,18 @@ public class HudIngame extends Gui
             tessellator.addVertexWithUV(itemEndX,                            20, 0.0f, 0, 0);
             tessellator.draw();
         }
+
+        if (mc.gameSettings.immersiveMode.drawOverlays() && mc.downloadResourcesThread.downloading) {
+            double b = java.lang.Math.sin((System.currentTimeMillis() / 1000.0) * 4);
+            b = b * 0.2 + 0.8;
+            int ib = (int) java.lang.Math.round(b * 255);
+            int color = 0xFF000000 + (ib << 16) + (ib << 8) + (ib);
+            drawStringCenteredShadow(
+                mc.font,
+                stringtranslate.translateKeyAndFormat("gui.main_menu.label.downloading_resources.1", mc.downloadResourcesThread.downloadProgress.get(), mc.downloadResourcesThread.toDownload),
+                width / 2, 16 + sp, color);
+            drawStringCenteredShadow(mc.font, stringtranslate.translateKey("gui.main_menu.label.downloading_resources.2"), width / 2, 25 + sp, color);
+        }
     }
 
     private int debugLine = 0;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/ScreenModelViewer.java b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/ScreenModelViewer.java
index 61e9785a2..af3dc606f 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/ScreenModelViewer.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/ScreenModelViewer.java
@@ -201,7 +201,7 @@ public class ScreenModelViewer extends ScreenPhotoMode implements ListenerTextFi
                 // Update intensity slider
                 sliderIntensity.displayString = i18n.translateKeyAndFormat("gui.photo_mode.button.intensity", (int)(sliderIntensity.sliderValue * 100) + "%");
                 if (sliderIntensity.dragging) {
-                    intensityValue = sliderIntensity.sliderValue;
+                    intensityValue = (float) sliderIntensity.sliderValue;
                 }
             });
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerSliderElement.java b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerSliderElement.java
index 3335d6870..040dffc1a 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerSliderElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/modelviewer/elements/ListenerSliderElement.java
@@ -21,7 +21,7 @@ public class ListenerSliderElement extends SliderElement implements IListenerEle
     }
     @Override
     public boolean mouseClicked(Minecraft mc, int mouseX, int mouseY) {
-        float _val = sliderValue;
+        double _val = sliderValue;
         boolean flag = super.mouseClicked(mc, mouseX, mouseY);
         if (flag && action != null){
             action.onInteract();
@@ -33,7 +33,7 @@ public class ListenerSliderElement extends SliderElement implements IListenerEle
     }
     @Override
     public void mouseDragged(Minecraft mc, int mouseX, int mouseY) {
-        float _val = sliderValue;
+        double _val = sliderValue;
         super.mouseDragged(mc, mouseX, mouseY);
         if (sliderValue != _val){
             onValueChanged();
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/FloatOptionComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/FloatOptionComponent.java
index 0aba78c6e..3ecddf448 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/FloatOptionComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/FloatOptionComponent.java
@@ -22,14 +22,14 @@ public class FloatOptionComponent
     @Override
     protected void buttonClicked(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) {
         this.slider.mouseClicked(mc, this.slider.xPosition + relativeMouseX, this.slider.yPosition + relativeMouseY);
-        this.option.set(this.slider.sliderValue);
+        this.option.set((float) this.slider.sliderValue);
         this.slider.displayString = this.option.getDisplayStringValue();
         this.option.onUpdate();
     }
 
     @Override
     protected void buttonDragged(int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) {
-        this.option.set(this.slider.sliderValue);
+        this.option.set((float) this.slider.sliderValue);
         this.slider.displayString = this.option.getDisplayStringValue();
         this.option.onUpdate();
     }
@@ -37,7 +37,7 @@ public class FloatOptionComponent
     @Override
     protected void buttonReleased(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) {
         this.slider.mouseReleased(this.slider.xPosition + relativeMouseX, this.slider.yPosition + relativeMouseY);
-        this.option.set(this.slider.sliderValue);
+        this.option.set((float) this.slider.sliderValue);
         this.slider.displayString = this.option.getDisplayStringValue();
         this.option.onUpdate();
     }
diff --git a/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java b/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
index 90df8eb50..02bc0c127 100644
--- a/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
+++ b/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
@@ -54,7 +54,7 @@ public class ClientCommandSource implements CommandSource {
 
     @Override
     public boolean hasAdmin() {
-        return true;
+        return this.mc.currentWorld.getLevelData().getCheatsEnabled();
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java b/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
index cd10afc99..12f080b50 100644
--- a/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
+++ b/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
@@ -16,6 +16,7 @@ import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
 import net.minecraft.client.player.controller.PlayerControllerMP;
 import net.minecraft.client.world.WorldClientMP;
 import net.minecraft.core.Global;
+import net.minecraft.core.achievement.stat.Stat;
 import net.minecraft.core.achievement.stat.StatList;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.block.entity.TileEntity;
@@ -1107,8 +1108,10 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleStatistic(PacketStatistic statisticPacket)
+    public void handleStatistic(final PacketStatistic statisticPacket)
     {
+        final Stat stat = StatList.getStat(statisticPacket.statID);
+        if (stat != null && stat.clientside) return; // Don't allow server to give client side only stats
         mc.thePlayer.addStat(StatList.getStat(statisticPacket.statID), statisticPacket.valueChange);
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/net/thread/ThreadDownloadResources.java b/game/client/src/main/java/net/minecraft/client/net/thread/ThreadDownloadResources.java
index 6dc270bb9..93f2d1cf5 100644
--- a/game/client/src/main/java/net/minecraft/client/net/thread/ThreadDownloadResources.java
+++ b/game/client/src/main/java/net/minecraft/client/net/thread/ThreadDownloadResources.java
@@ -19,6 +19,7 @@ import com.b100.xml.element.XmlContentTag;
 import com.b100.xml.element.XmlTag;
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.sound.SoundEngine;
 import net.minecraft.client.sound.SoundRepository;
 import org.slf4j.Logger;
 
@@ -124,6 +125,9 @@ public class ThreadDownloadResources extends Thread {
             }
         }
         SoundRepository.reload();
+        this.mc.sndManager.destroy();
+        this.mc.sndManager = new SoundEngine();
+        this.mc.sndManager.init(this.mc.gameSettings);
 
         downloading = false;
     }
diff --git a/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java b/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
index f354a636c..0a4e137ed 100644
--- a/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
+++ b/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
@@ -1441,7 +1441,7 @@ public class RenderGlobal
 		double offsetZ = camera.getZ(partialTicks);
 		float expand = 0.002F;
 		List<AABB> collidingBoundingBoxes = worldObj.getCubes(mc.thePlayer, mc.thePlayer.bb.grow(expand, expand, expand));
-		glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
+        glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
 		for (AABB aabb : collidingBoundingBoxes) {
 			drawOutlinedBoundingBox(aabb.cloneMove(-offsetX, -offsetY, -offsetZ).grow(expand, expand, expand));
 		}
@@ -1450,6 +1450,7 @@ public class RenderGlobal
 		if(mc.thePlayer.getGamemode() == Gamemode.creative) {
 			entityRadius = 100.0f;
 		}
+        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
 		List<Entity> entitiesNearby = worldObj.getEntitiesWithinAABBExcludingEntity(mc.thePlayer, mc.thePlayer.bb.grow(entityRadius, entityRadius, entityRadius));
 		for (Entity e : entitiesNearby) {
 			drawInterpolatedEntityBoundingBox(e, camera, partialTicks);
@@ -1471,15 +1472,6 @@ public class RenderGlobal
         boundingBox = boundingBox.cloneMove(-entity.x, -entity.y, -entity.z);
         boundingBox = boundingBox.cloneMove(-cameraX, -cameraY, -cameraZ);
         boundingBox = boundingBox.cloneMove(lerpOffsetX, lerpOffsetY, lerpOffsetZ);
-
-        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-        drawOutlinedBoundingBox(boundingBox);
-
-        glColor4f(1.0f, 0f, 0f, 1.0f);
-        boundingBox = EntityRenderDispatcher.instance.getRenderer(entity).entityViewBox(entity);
-        boundingBox = boundingBox.cloneMove(-entity.x, -entity.y, -entity.z);
-        boundingBox = boundingBox.cloneMove(-cameraX, -cameraY, -cameraZ);
-        boundingBox = boundingBox.cloneMove(lerpOffsetX, lerpOffsetY, lerpOffsetZ);
         drawOutlinedBoundingBox(boundingBox);
     }
 
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 45f82d949..91d58e95f 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
@@ -199,6 +199,10 @@ public final class BlockModelDispatcher
         addDispatch(new BlockModelSlab<>(Blocks.SLAB_COBBLE_PERMAFROST));
         addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_SANDSTONE));
         addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_PERMAFROST));
+        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_IRON));
+        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_GOLD));
+        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_STEEL));
+        addDispatch(new BlockModelSlab<>(Blocks.SLAB_BRICK_LAPIS));
 
         addDispatch(new BlockModelStairs<>(Blocks.STAIRS_PLANKS_OAK));
         addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_STONE));
@@ -218,6 +222,10 @@ public final class BlockModelDispatcher
         addDispatch(new BlockModelStairs<>(Blocks.STAIRS_COBBLE_PERMAFROST));
         addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_SANDSTONE));
         addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_PERMAFROST));
+        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_IRON));
+        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_GOLD));
+        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_STEEL));
+        addDispatch(new BlockModelStairs<>(Blocks.STAIRS_BRICK_LAPIS));
 
         addDispatch(new BlockModelStandard<>(Blocks.OBSIDIAN).setAllTextures(BLOCK_TEXTURES, "minecraft:block/obsidian"));
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java
index 0191185b2..97fe0b14f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRenderer.java
@@ -28,9 +28,11 @@ import java.util.Map;
 
 public abstract class EntityRenderer<T extends Entity>
 {
+    public static boolean renderShadows = true;
     private final @NotNull Map<@NotNull String, @NotNull StaticEntityModel> modelMap = new HashMap<>();
     protected EntityRenderDispatcher renderDispatcher = null;
     protected Class<? extends T> appliedClass = null;
+
     protected float shadowSize;
     protected float shadowOpacity;
 
@@ -295,7 +297,7 @@ public abstract class EntityRenderer<T extends Entity>
 
     public void postRender(final @NotNull Tessellator tessellator, final @NotNull T entity, final double x, final double y, final double z, final float yaw, final float partialTick)
     {
-        if(this.renderDispatcher.settings.fancyGraphics.value == 1 && this.shadowSize > 0.0F)
+        if(renderShadows && this.renderDispatcher.settings.fancyGraphics.value == 1 && this.shadowSize > 0.0F)
         {
             final double distance = this.renderDispatcher.distanceToLerpSquared(entity.x, entity.y, entity.z);
             final float opacity = (float)((1.0D - distance / 256D) * (double) this.shadowOpacity);
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
index ff11bfdb8..51560ab2d 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import net.minecraft.client.render.EntityRenderDispatcher;
+import net.minecraft.client.render.entity.EntityRenderer;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.client.world.WorldClient;
 import net.minecraft.core.block.entity.TileEntityMobSpawner;
@@ -47,7 +48,9 @@ public class TileEntityRendererMobSpawner extends TileEntityRenderer<TileEntityM
             GL11.glScalef(f1, f1, f1);
 //            System.out.printf("X: %f, Y: %f, Z: %f\n", x, y, z);
             entity.moveTo(mobSpawner.x, mobSpawner.y, mobSpawner.z, 0.0F, 0.0F);
+            EntityRenderer.renderShadows = false;
             EntityRenderDispatcher.instance.renderEntityWithPosYaw(tessellator, entity, 0.0D, 0.0D, 0.0D, 0.0F, partialTick);
+            EntityRenderer.renderShadows = true;
         }
         GL11.glPopMatrix();
     }
diff --git a/game/client/src/main/java/net/minecraft/client/sound/SoundEngine.java b/game/client/src/main/java/net/minecraft/client/sound/SoundEngine.java
index 4cc75dadd..23be97302 100644
--- a/game/client/src/main/java/net/minecraft/client/sound/SoundEngine.java
+++ b/game/client/src/main/java/net/minecraft/client/sound/SoundEngine.java
@@ -2,6 +2,8 @@ package net.minecraft.client.sound;
 
 import java.net.URL;
 import java.util.Random;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 import com.mojang.logging.LogUtils;
 import net.betterthanadventure.sound.LibraryLWJGL3OpenAL;
@@ -20,306 +22,365 @@ import paulscode.sound.codecs.CodecWav;
 public class SoundEngine
 {
 	private static final Logger LOGGER = LogUtils.getLogger();
-  private static final int MUSIC_INTERVAL = 6000;
+	private static final int MUSIC_INTERVAL = 6000;
 	private static @Nullable SoundSystem soundSystem;
+	private static Lock lock = new ReentrantLock();
 	private static boolean loaded = false;
 
 	public static final String BG_MUSIC = "BgMusic";
 	public static final String STREAMING = "Streaming";
 
 	private int idCounter;
-	private GameSettings options;
+	private @Nullable GameSettings options;
 	private final Random random;
 	private Minecraft mc;
 	public int ticksBeforeMusic;
 	private boolean muted = false;
 
 	public SoundEngine() {
-        idCounter = 0;
-        random = new Random();
-        ticksBeforeMusic = random.nextInt(MUSIC_INTERVAL);
+        this.idCounter = 0;
+        this.random = new Random();
+        this.ticksBeforeMusic = this.random.nextInt(MUSIC_INTERVAL);
     }
 
 	public void destroy() {
-		if (loaded && soundSystem != null) {
-			soundSystem.cleanup();
+		try {
+			lock.lock();
+			if (isLoaded()) {
+				soundSystem.cleanup();
+				loaded = false;
+				soundSystem = null;
+			}
+		} finally {
+			lock.unlock();
 		}
 	}
 	
-	public void setMuted(boolean muted)
+	public void setMuted(final boolean muted)
 	{
-		if (soundSystem == null) return;
-		this.muted = muted;
-		if (this.muted) {
-			soundSystem.setVolume(BG_MUSIC, 0.0f);
-		} else {
-			soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, options));
+		try {
+			lock.lock();
+			if (!isLoaded()) return;
+			this.muted = muted;
+			if (this.muted) {
+				soundSystem.setVolume(BG_MUSIC, 0.0f);
+			} else {
+				soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options));
+			}
+		} finally {
+			lock.unlock();
 		}
 	}
 
 	public void updateListener(final Mob player, final float partialTick)
 	{
-		if (!loaded || muted || soundSystem == null || !SoundCategoryHelper.isAnyEnabled(options)) {
-			return;
-		}
-		if (player != null) {
-			final float yRot = MathHelper.lerp(player.yRotO, player.yRot, partialTick);
-			final double playerX = MathHelper.lerp(player.xo, player.x, partialTick);
-			final double playerY = MathHelper.lerp(player.yo, player.y, partialTick);
-			final double playerZ = MathHelper.lerp(player.zo, player.z, partialTick);
-			final float yCos = MathHelper.cos(MathHelper.toRadians(-yRot - 180));
-			final float ySin = MathHelper.sin(MathHelper.toRadians(-yRot - 180));
-			final float xa = -ySin;
-			final float ya = 0.0F;
-			final float za = -yCos;
-			final float xa2 = 0.0F;
-			final float ya2 = 1.0F;
-			final float za2 = 0.0F;
-			soundSystem.setListenerPosition((float) playerX, (float) playerY, (float) playerZ);
-			soundSystem.setListenerOrientation(xa, ya, za, xa2, ya2, za2);
+		try {
+			lock.lock();
+			if (!canPlaySounds()) return;
+			if (player != null) {
+				final float yRot = MathHelper.lerp(player.yRotO, player.yRot, partialTick);
+				final double playerX = MathHelper.lerp(player.xo, player.x, partialTick);
+				final double playerY = MathHelper.lerp(player.yo, player.y, partialTick);
+				final double playerZ = MathHelper.lerp(player.zo, player.z, partialTick);
+				final float yCos = MathHelper.cos(MathHelper.toRadians(-yRot - 180));
+				final float ySin = MathHelper.sin(MathHelper.toRadians(-yRot - 180));
+				final float xa = -ySin;
+				final float ya = 0.0F;
+				final float za = -yCos;
+				final float xa2 = 0.0F;
+				final float ya2 = 1.0F;
+				final float za2 = 0.0F;
+				soundSystem.setListenerPosition((float) playerX, (float) playerY, (float) playerZ);
+				soundSystem.setListenerOrientation(xa, ya, za, xa2, ya2, za2);
+			}
+		} finally {
+			lock.unlock();
 		}
     }
 
     public void init(final GameSettings gamesettings) {
-        options = gamesettings;
-        if (!loaded && (gamesettings != null && SoundCategoryHelper.isAnyEnabled(gamesettings))) {
-            loadLibrary();
-        }
-		mc = Minecraft.getMinecraft();
+		try {
+			lock.lock();
+			this.options = gamesettings;
+			if (!isLoaded() && SoundCategoryHelper.isAnyEnabled(gamesettings)) {
+				loadLibrary();
+			}
+			this.mc = Minecraft.getMinecraft();
+		} finally {
+			lock.unlock();
+		}
     }
 
     public void updateOptions() {
-        if (!loaded && SoundCategoryHelper.isAnyEnabled(options)) {
-            loadLibrary();
-        }
-        if (soundSystem != null && loaded) {
-            if (SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, options) == 0.0F) {
-                soundSystem.stop(BG_MUSIC);
-            } else {
-                soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, options));
-            }
-        }
+		try {
+			lock.lock();
+			if (!isLoaded()) {
+				loadLibrary();
+			}
+			if (soundSystem != null && loaded) {
+				if (SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options) == 0.0F) {
+					soundSystem.stop(BG_MUSIC);
+				} else {
+					soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options));
+				}
+			}
+		} finally {
+			lock.unlock();
+		}
     }
 
     public void tick() {
-        if (!loaded || soundSystem == null || SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, options) == 0.0F) {
-            return;
-        }
-
-        if (!soundSystem.playing(BG_MUSIC) && !soundSystem.playing(STREAMING)) {
-            if (ticksBeforeMusic > 0) {
-                ticksBeforeMusic--;
-                return;
-            }
-
-			// TODO a more sane way of grouping music pools with our new system
-			SoundEvent event;
-            if (mc != null && mc.thePlayer != null && !mc.thePlayer.world.canBlockSeeTheSky(MathHelper.floor(mc.thePlayer.x), MathHelper.floor(mc.thePlayer.y), MathHelper.floor(mc.thePlayer.z))) {
-				event = SoundRepository.SOUNDS.getSoundEvent("ambient.cave");
-            } else {
-				event = SoundRepository.SOUNDS.getRandomSoundFromCategory("music.");
-            }
-			if (event == null) return;
-			SoundEntry entry = event.getRandomEntry();
-            if (entry != null) {
-                ticksBeforeMusic = random.nextInt(MUSIC_INTERVAL) + MUSIC_INTERVAL;
-                soundSystem.backgroundMusic(BG_MUSIC, entry.getURL(), entry.name, false);
-				soundSystem.setPitch(BG_MUSIC, entry.pitch);
-                soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, options) * entry.volume);
-                soundSystem.play(BG_MUSIC);
-            }
-        }
+		try {
+			lock.lock();
+			if (!isLoaded() || SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options) == 0.0F) {
+				return;
+			}
+
+			if (!soundSystem.playing(BG_MUSIC) && !soundSystem.playing(STREAMING)) {
+				if (this.ticksBeforeMusic > 0) {
+					this.ticksBeforeMusic--;
+					return;
+				}
+
+				// TODO a more sane way of grouping music pools with our new system
+				final SoundEvent event;
+				if (this.mc != null && this.mc.thePlayer != null && !this.mc.thePlayer.world.canBlockSeeTheSky(MathHelper.floor(this.mc.thePlayer.x), MathHelper.floor(this.mc.thePlayer.y), MathHelper.floor(this.mc.thePlayer.z))) {
+					event = SoundRepository.SOUNDS.getSoundEvent("ambient.cave");
+				} else {
+					event = SoundRepository.SOUNDS.getRandomSoundFromCategory("music.");
+				}
+				if (event == null) return;
+				final SoundEntry entry = event.getRandomEntry();
+				if (entry != null) {
+					this.ticksBeforeMusic = this.random.nextInt(MUSIC_INTERVAL) + MUSIC_INTERVAL;
+					soundSystem.backgroundMusic(BG_MUSIC, entry.getURL(), entry.name, false);
+					soundSystem.setPitch(BG_MUSIC, entry.pitch);
+					soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options) * entry.volume);
+					soundSystem.play(BG_MUSIC);
+				}
+			}
+		} finally {
+			lock.unlock();
+		}
     }
 
-	public void playSound(String name, SoundCategory category, float volume, float pitch) {
+	public void playSound(final String name, final SoundCategory category, final float volume, final float pitch) {
 		playSound(SoundRepository.SOUNDS.getSoundEntry(name), category, volume, pitch);
 	}
 
-	public void playSound(SoundEntry entry, SoundCategory category, float volume, float pitch) {
-		if (!loaded || soundSystem == null || muted || !SoundCategoryHelper.isAnyEnabled(options))
-		{
-			return;
+	public void playSound(final SoundEntry entry, final SoundCategory category, final float volume, final float pitch) {
+		try {
+			lock.lock();
+			if (!canPlaySounds()) return;
+			this.idCounter = (this.idCounter + 1) % 256;
+			final String soundName = "sound_" + this.idCounter;
+			playSoundWithID(entry, category, volume, pitch, soundName);
+		} finally {
+			lock.unlock();
 		}
-		idCounter = (idCounter + 1) % 256;
-		final String soundName = "sound_" + idCounter;
-		playSoundWithID(entry, category, volume, pitch, soundName);
 	}
 
-	public void playSoundAt(String name, SoundCategory category, float x, float y, float z, float volume, float pitch) {
+	public void playSoundAt(final String name, final SoundCategory category, final float x, final float y, final float z, final float volume, final float pitch) {
 		playSoundAt(SoundRepository.SOUNDS.getSoundEntry(name), category, x, y, z, volume, pitch);
 	}
 
-	public void playSoundAt(SoundEntry entry, SoundCategory category, float x, float y, float z, float volume, float pitch) {
-		if (!loaded || soundSystem == null || muted || !SoundCategoryHelper.isAnyEnabled(options))
-		{
-			return;
+	public void playSoundAt(final SoundEntry entry, final SoundCategory category, final float x, final float y, final float z, final float volume, final float pitch) {
+		try {
+			lock.lock();
+			if (!canPlaySounds()) return;
+			this.idCounter = (this.idCounter + 1) % 256;
+			final String soundName = "sound_" + this.idCounter;
+			playSoundWithIdAtPos(entry, category, x, y, z, volume, pitch, soundName);
+		} finally {
+			lock.unlock();
 		}
-		idCounter = (idCounter + 1) % 256;
-		final String soundName = "sound_" + idCounter;
-		playSoundWithIdAtPos(entry, category, x, y, z, volume, pitch, soundName);
 	}
 
-	public void playSoundWithID(String name, SoundCategory category, float volume, final float pitch, String soundID) {
+	public void playSoundWithID(final String name, final SoundCategory category, final float volume, final float pitch, final String soundID) {
 		playSoundWithID(name, category, volume, pitch, soundID, true);
 	}
 
-	private void playSoundWithID(String name, SoundCategory category, float volume, final float pitch, String soundID, boolean allowSubtitle) {
+	private void playSoundWithID(final String name, final SoundCategory category, final float volume, final float pitch, final String soundID, final boolean allowSubtitle) {
 		playSoundWithID(SoundRepository.SOUNDS.getSoundEntry(name), category, volume, pitch, soundID, allowSubtitle);
 	}
 
-	public void playSoundWithID(SoundEntry entry, SoundCategory category, float volume, final float pitch, String soundID) {
+	public void playSoundWithID(final SoundEntry entry, final SoundCategory category, final float volume, final float pitch, final String soundID) {
 		playSoundWithID(entry, category, volume, pitch, soundID, true);
 	}
 
-	private void playSoundWithID(SoundEntry entry, SoundCategory category, float volume, final float pitch, String soundID, boolean allowSubtitle) {
-		if (!loaded || soundSystem == null || muted || !SoundCategoryHelper.isAnyEnabled(options))
-		{
-			return;
-		}
-		if (entry != null) {
-			if (entry.type == SoundEntry.Type.FILE) {
-				URL url = entry.getURL();
-				if (url != null){
-					if (entry.shouldStream) {
-						soundSystem.newStreamingSource(false, soundID, url, entry.name, false, 0, 0, 0, 2, 0);
-					} else {
-						soundSystem.newSource(false, soundID, url, entry.name, false, 0, 0, 0, 0, 0);
-					}
-					if (volume > 1.0F)
-					{
-						volume = 1.0F;
+	private void playSoundWithID(final SoundEntry entry, final SoundCategory category, float volume, final float pitch, final String soundID, final boolean allowSubtitle) {
+		try {
+			lock.lock();
+			if (!canPlaySounds()) return;
+			if (entry != null) {
+				if (entry.type == SoundEntry.Type.FILE) {
+					final URL url = entry.getURL();
+					if (url != null){
+						if (entry.shouldStream) {
+							soundSystem.newStreamingSource(false, soundID, url, entry.name, false, 0, 0, 0, 2, 0);
+						} else {
+							soundSystem.newSource(false, soundID, url, entry.name, false, 0, 0, 0, 0, 0);
+						}
+						if (volume > 1.0F)
+						{
+							volume = 1.0F;
+						}
+						volume *= 0.25F;
+						soundSystem.setPitch(soundID, pitch * entry.pitch);
+						soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category, this.options) * entry.volume);
+						soundSystem.play(soundID);
 					}
-					volume *= 0.25F;
-					soundSystem.setPitch(soundID, pitch * entry.pitch);
-					soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category, options) * entry.volume);
-					soundSystem.play(soundID);
+				} else if (entry.type == SoundEntry.Type.EVENT) {
+					playSoundWithID(entry.name, category, volume * entry.volume, pitch * entry.pitch, soundID, false);
+				}
+				if (allowSubtitle && entry.parent.hasSubtitle()) {
+					this.mc.subtitleTracker.heardSound(entry.parent, 0, 0, 0);
 				}
-			} else if (entry.type == SoundEntry.Type.EVENT) {
-				playSoundWithID(entry.name, category, volume * entry.volume, pitch * entry.pitch, soundID, false);
-			}
-			if (allowSubtitle && entry.parent.hasSubtitle()) {
-				mc.subtitleTracker.heardSound(entry.parent, 0, 0, 0);
 			}
+		} finally {
+			lock.unlock();
 		}
 	}
 
-	public void playSoundWithIdAtPos(String name, SoundCategory category, float x, float y, float z, float volume, final float pitch, String soundID) {
+	public void playSoundWithIdAtPos(final String name, final SoundCategory category, final float x, final float y, final float z, final float volume, final float pitch, final String soundID) {
 		playSoundWithIdAtPos(name, category, x, y, z, volume, pitch, soundID, true);
 	}
 
-	private void playSoundWithIdAtPos(String name, SoundCategory category, float x, float y, float z, float volume, final float pitch, String soundID, boolean allowSubtitle) {
+	private void playSoundWithIdAtPos(final String name, final SoundCategory category, final float x, final float y, final float z, final float volume, final float pitch, final String soundID, final boolean allowSubtitle) {
 		playSoundWithIdAtPos(SoundRepository.SOUNDS.getSoundEntry(name), category, x, y, z, volume, pitch, soundID, allowSubtitle);
 	}
-	public void playSoundWithIdAtPos(SoundEntry entry, SoundCategory category, float x, float y, float z, float volume, final float pitch, String soundID) {
+	public void playSoundWithIdAtPos(final SoundEntry entry, final SoundCategory category, final float x, final float y, final float z, final float volume, final float pitch, final String soundID) {
 		playSoundWithIdAtPos(entry, category, x, y, z, volume, pitch, soundID, true);
 	}
 
-	private void playSoundWithIdAtPos(SoundEntry entry, SoundCategory category, float x, float y, float z, float volume, final float pitch, String soundID, boolean allowSubtitle) {
-		if (!loaded || muted || soundSystem == null || !SoundCategoryHelper.isAnyEnabled(options)) {
-			return;
-		}
-		if (entry != null) {
-			float soundDistance = entry.attenuationDistance;
-			if(volume > 1.0F)
-			{
-				soundDistance *= volume;
-			}
-			if(mc.activeCamera.distanceToSqr(x, y, z) > (double)(soundDistance * soundDistance)) return;
-
-			if (entry.type == SoundEntry.Type.FILE) {
-				URL url = entry.getURL();
-				if (url != null){
-					if (entry.shouldStream) {
-						soundSystem.newStreamingSource(volume > 1.0F, soundID, url, entry.name, false, x, y, z, 2, soundDistance);
-					} else {
-						soundSystem.newSource(volume > 1.0F, soundID, url, entry.name, false, x, y, z, 2, soundDistance);
-					}
-					if (volume > 1.0F) {
-						volume = 1.0F;
-					}
+	private void playSoundWithIdAtPos(final SoundEntry entry, final SoundCategory category, final float x, final float y, final float z, float volume, final float pitch, final String soundID, final boolean allowSubtitle) {
+		try {
+			lock.lock();
+			if (!canPlaySounds()) return;
+			if (entry != null) {
+				float soundDistance = entry.attenuationDistance;
+				if(volume > 1.0F)
+				{
+					soundDistance *= volume;
+				}
+				if(this.mc.activeCamera.distanceToSqr(x, y, z) > (double)(soundDistance * soundDistance)) return;
+
+				if (entry.type == SoundEntry.Type.FILE) {
+					final URL url = entry.getURL();
+					if (url != null){
+						if (entry.shouldStream) {
+							soundSystem.newStreamingSource(volume > 1.0F, soundID, url, entry.name, false, x, y, z, 2, soundDistance);
+						} else {
+							soundSystem.newSource(volume > 1.0F, soundID, url, entry.name, false, x, y, z, 2, soundDistance);
+						}
+						if (volume > 1.0F) {
+							volume = 1.0F;
+						}
 
-					soundSystem.setPitch(soundID, pitch * entry.pitch);
-					soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category, options) * entry.volume);
-					soundSystem.play(soundID);
+						soundSystem.setPitch(soundID, pitch * entry.pitch);
+						soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category, this.options) * entry.volume);
+						soundSystem.play(soundID);
+					}
+				} else if (entry.type == SoundEntry.Type.EVENT) {
+					playSoundWithIdAtPos(entry.name, category, x, y, z, volume * entry.volume, pitch * entry.pitch, soundID, false);
+				}
+				if (allowSubtitle && entry.parent.hasSubtitle()) {
+					this.mc.subtitleTracker.heardSound(entry.parent, x, y, z);
 				}
-			} else if (entry.type == SoundEntry.Type.EVENT) {
-				playSoundWithIdAtPos(entry.name, category, x, y, z, volume * entry.volume, pitch * entry.pitch, soundID, false);
-			}
-			if (allowSubtitle && entry.parent.hasSubtitle()) {
-				mc.subtitleTracker.heardSound(entry.parent, x, y, z);
 			}
+		} finally {
+			lock.unlock();
 		}
 	}
 
-	public void playMusic(String name, float x, float y, float z, float volume, float pitch) {
+	public void playMusic(final String name, final float x, final float y, final float z, final float volume, final float pitch) {
 		playMusic(SoundRepository.SOUNDS.getSoundEntry(name), x, y, z, volume, pitch);
 	}
 
-	public void playMusic(SoundEntry entry, float x, float y, float z, float volume, float pitch)
+	public void playMusic(final SoundEntry entry, final float x, final float y, final float z, final float volume, final float pitch)
 	{
-		if (!loaded || soundSystem == null || muted || !SoundCategoryHelper.isAnyEnabled(options))
-		{
-			return;
-		}
-		if (soundSystem.playing(STREAMING))
-		{
-			soundSystem.stop(STREAMING);
-		}
-		if (entry == null)
-		{
-			return;
-		}
-		if (volume > 0.0F)
-		{
-			if (soundSystem.playing(BG_MUSIC))
+		try {
+			lock.lock();
+			if (!canPlaySounds()) { return; }
+			if (soundSystem.playing(STREAMING))
+			{
+				soundSystem.stop(STREAMING);
+			}
+			if (entry == null)
 			{
-				soundSystem.stop(BG_MUSIC);
+				return;
 			}
-			if (entry.type == SoundEntry.Type.FILE) {
-				URL url = entry.getURL();
-				if (url != null) {
-					soundSystem.newStreamingSource(true, STREAMING, url, entry.name, false, x, y, z, 2, entry.attenuationDistance);
-					soundSystem.setPitch(STREAMING, pitch * entry.pitch);
-					soundSystem.setVolume(STREAMING, volume * entry.volume * options.masterVolume.value);
-					soundSystem.play(STREAMING);
+			if (volume > 0.0F)
+			{
+				if (soundSystem.playing(BG_MUSIC))
+				{
+					soundSystem.stop(BG_MUSIC);
+				}
+				if (entry.type == SoundEntry.Type.FILE) {
+					final URL url = entry.getURL();
+					if (url != null) {
+						soundSystem.newStreamingSource(true, STREAMING, url, entry.name, false, x, y, z, 2, entry.attenuationDistance);
+						soundSystem.setPitch(STREAMING, pitch * entry.pitch);
+						soundSystem.setVolume(STREAMING, volume * entry.volume * this.options.masterVolume.value);
+						soundSystem.play(STREAMING);
+					}
+				} else if (entry.type == SoundEntry.Type.EVENT) {
+					playMusic(entry.name, x, y, z, volume, pitch);
 				}
-			} else if (entry.type == SoundEntry.Type.EVENT) {
-				playMusic(entry.name, x, y, z, volume, pitch);
 			}
+		} finally {
+			lock.unlock();
 		}
 	}
 
 	public void stopMusic() {
-		if (!loaded || soundSystem == null) {
-			return;
+		try {
+			lock.lock();
+			if (!isLoaded()) { return; }
+			soundSystem.stop(BG_MUSIC);
+			soundSystem.stop(STREAMING);
+		} finally {
+			lock.unlock();
 		}
-		soundSystem.stop(BG_MUSIC);
-		soundSystem.stop(STREAMING);
 	}
 
     private void loadLibrary() {
-        try {
-			float[] volumeStore = new float[SoundCategory.values().length];
-			for (int i = 0; i < SoundCategory.values().length; i++)
-			{
-				volumeStore[i] = SoundCategoryHelper.getVolume(SoundCategory.values()[i], options);
-			}
-            options.saveOptions();
-            SoundSystemConfig.addLibrary(LibraryLWJGL3OpenAL.class);
-            SoundSystemConfig.setCodec("ogg", CodecJOrbis.class);
-            SoundSystemConfig.setCodec("mus", CodecMus.class);
-            SoundSystemConfig.setCodec("wav", CodecWav.class);
-            soundSystem = new SoundSystem();
-			for (int i = 0; i < SoundCategory.values().length; i++)
-			{
-				SoundCategoryHelper.setVolume(SoundCategory.values()[i], options, volumeStore[i]);
+		try {
+			lock.lock();
+			try {
+				final float[] volumeStore = new float[SoundCategory.values().length];
+				for (int i = 0; i < SoundCategory.values().length; i++)
+				{
+					volumeStore[i] = SoundCategoryHelper.getVolume(SoundCategory.values()[i], this.options);
+				}
+				this.options.saveOptions();
+				SoundSystemConfig.addLibrary(LibraryLWJGL3OpenAL.class);
+				SoundSystemConfig.setCodec("ogg", CodecJOrbis.class);
+				SoundSystemConfig.setCodec("mus", CodecMus.class);
+				SoundSystemConfig.setCodec("wav", CodecWav.class);
+				soundSystem = new SoundSystem();
+				for (int i = 0; i < SoundCategory.values().length; i++)
+				{
+					SoundCategoryHelper.setVolume(SoundCategory.values()[i], this.options, volumeStore[i]);
+				}
+				this.options.saveOptions();
+			} catch (final Throwable throwable) {
+				LOGGER.error("Error linking with the LibraryJavaSound plug-in", throwable);
 			}
-			options.saveOptions();
-        } catch (final Throwable throwable) {
-			LOGGER.error("Error linking with the LibraryJavaSound plug-in", throwable);
-        }
-        loaded = true;
+			loaded = true;
+		} finally {
+			lock.unlock();
+		}
     }
+
+	private boolean isLoaded() {
+		return loaded && soundSystem != null;
+	}
+
+	private boolean canPlaySounds() {
+		return isLoaded() && !this.muted && SoundCategoryHelper.isAnyEnabled(this.options);
+	}
+
 	public static @Nullable SoundSystem getSoundSystem(){
 		return soundSystem;
 	}
diff --git a/game/client/src/main/java/net/minecraft/client/util/helper/FileOpener.java b/game/client/src/main/java/net/minecraft/client/util/helper/FileOpener.java
index a78193085..e0bc3d199 100644
--- a/game/client/src/main/java/net/minecraft/client/util/helper/FileOpener.java
+++ b/game/client/src/main/java/net/minecraft/client/util/helper/FileOpener.java
@@ -1,87 +1,76 @@
 package net.minecraft.client.util.helper;
 
-import java.awt.Desktop;
+import com.mojang.logging.LogUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.core.enums.EnumOS;
+import org.slf4j.Logger;
+
 import java.io.File;
 import java.io.IOException;
-import java.util.Locale;
 
 public final class FileOpener {
-
-    public static boolean toClipboard(String path) {
-        String os = System.getProperty("os.name").toLowerCase(Locale.ROOT);
-
-        if (os.contains("win")) {
-            return (run("powershell", "-Command %s", "Get-ChildItem \"" + path + "\" | Set-Clipboard"));
-        }
-
-        if (os.contains("mac")) {
-            return (run("osascript", "-e %s", "set the clipboard to (read (POSIX file \"" + path + "\") as {«class PNGf»})"));
+    private static final Logger LOGGER = LogUtils.getLogger();
+
+    public static boolean toClipboard(final String path) {
+        final EnumOS os = Minecraft.getOs();
+        switch (os) {
+            case windows:
+                return (run("powershell", "-Command %s", "Get-ChildItem \"" + path + "\" | Set-Clipboard"));
+            case macos:
+                return (run("osascript", "-e %s", "set the clipboard to (read (POSIX file \"" + path + "\") as {«class PNGf»})"));
+            case linux:
+            case solaris:
+            default:
+                return run("xclip-copyfile", "%s", path);
         }
-
-        return run("xclip-copyfile", "%s", path);
     }
 
-    public static void open(File file) {
-
-        if (!openSystem(file.getPath()) && !openDESKTOP(file))
-            System.err.println("unable to open file " + System.getProperty("os.name"));
-    }
-
-    private static boolean openSystem(String what) {
-
-        String os = System.getProperty("os.name").toLowerCase(Locale.ROOT);
-
-        if (os.contains("win")) {
-            return (run("explorer", "%s", what));
-        }
-
-        if (os.contains("mac")) {
-            return (run("open", "%s", what));
+    public static void open(final File file) {
+        if (!openSystem(file.getPath())) {
+            LOGGER.error("unable to open file {}", System.getProperty("os.name"));
         }
 
-        return run("kde-open", "%s", what) || run("gnome-open", "%s", what) || run("xdg-open", "%s", what);
-
     }
 
-    private static boolean openDESKTOP(File file) {
+    private static boolean openSystem(final String what) {
+        final EnumOS os = Minecraft.getOs();
 
-        if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
-            try {
-                Desktop.getDesktop().open(file);
-                return true;
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-        return false;
+        switch (os) {
+            case windows:
+                return (run("explorer", "%s", what));
+            case macos:
+                return (run("open", "%s", what));
+            case linux:
+            case solaris:
+            default:
+                return run("kde-open", "%s", what) || run("gnome-open", "%s", what) || run("xdg-open", "%s", what);
 
+        }
     }
 
-    private static boolean run(String command, String arg, String file) {
+    private static boolean run(final String command, final String arg, final String file) {
 
-        String[] args = arg.split(" ");
-        String[] parts = new String[args.length + 1];
+        final String[] args = arg.split(" ");
+        final String[] parts = new String[args.length + 1];
         parts[0] = command;
         for (int i = 0; i < args.length; i++) {
             parts[i + 1] = String.format(args[i], file).trim();
         }
 
-        System.out.println(String.join(" ", parts));
+        LOGGER.info(String.join(" ", parts));
 
         try {
-            Process p = Runtime.getRuntime().exec(parts);
+            final Process p = Runtime.getRuntime().exec(parts);
             if (p == null)
                 return false;
 
             try {
-                if (p.exitValue() == 0)
-                    return true;
-                return false;
-            } catch (IllegalThreadStateException itse) {
+                return p.exitValue() == 0;
+            } catch (final IllegalThreadStateException itse) {
                 return true;
             }
-        } catch (IOException e) {
-            //e.printStackTrace();
+        } catch (final IOException e) {
+            LOGGER.error("", e);
             return false;
         }
     }
diff --git a/game/client/src/main/java/net/minecraft/client/util/helper/UrlHelper.java b/game/client/src/main/java/net/minecraft/client/util/helper/UrlHelper.java
new file mode 100644
index 000000000..6872fd0a9
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/util/helper/UrlHelper.java
@@ -0,0 +1,46 @@
+package net.minecraft.client.util.helper;
+
+import com.mojang.logging.LogUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.core.enums.EnumOS;
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+
+public final class UrlHelper {
+    private static final Logger LOGGER = LogUtils.getLogger();
+    private UrlHelper() {}
+
+    public static boolean openURL(final @NotNull String url) {
+        final EnumOS os = Minecraft.getOs();
+        final Runtime rt = Runtime.getRuntime();
+        try {
+            switch (os) {
+                case linux: // Linux
+                case solaris: // Solaris
+                {
+                    rt.exec("xdg-open " + url);
+                    break;
+                }
+                case windows: // Windows
+                {
+                    rt.exec("rundll32 url.dll,FileProtocolHandler " + url);
+                    break;
+                }
+                case macos: // macOS
+                {
+                    rt.exec("open " + url);
+                    break;
+                }
+                default:
+                    LOGGER.error("No url handling behavior for os '{}'!", System.getProperty("os.name"));
+                    return false;
+            }
+        } catch (final IOException e) {
+            LOGGER.error("IOException while trying to open url '{}'", url, e);
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/game/client/src/main/resources/credits.txt b/game/client/src/main/resources/credits.txt
index 44cf2ff4a..88207485c 100644
--- a/game/client/src/main/resources/credits.txt
+++ b/game/client/src/main/resources/credits.txt
@@ -13,6 +13,7 @@ Useless (@uselessbullets)
 
 *Artists
 afk (@away.from.keyboard)
+Shign (@shign.bright)
 thaboar
 
 *Community Moderators
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java
index 18e93dacf..3d55beaf9 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicJar.java
@@ -70,7 +70,13 @@ public class BlockLogicJar extends BlockLogic {
                     world.setBlockMetadataWithNotify(x, y, z, 0);
                     world.playSoundAtEntity(player, player, "item.pickup", 1f, 1f);
                     if (!world.isClientSide) {
-                        world.dropItem(x, y, z, new ItemStack(flowerInPot, 1, flowerData));
+                        if (Block.hasLogicClass(Blocks.getBlock(flowerInPot), BlockLogicFlowerStackable.class)) {
+                            for (int i = 0; i <= BlockLogicFlowerStackable.getStackCount(flowerData); i++) {
+                                world.dropItem(x, y, z, new ItemStack(flowerInPot, 1, 0));
+                            }
+                        } else {
+                            world.dropItem(x, y, z, new ItemStack(flowerInPot, 1, flowerData));
+                        }
                     }
                 }
             }
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 c7129397e..f48bd507d 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
@@ -1204,6 +1204,31 @@ public final class Blocks {
     public static final Block<BlockLogicSlab> SLAB_PERMAFROST_POLISHED = register("slab.permafrost.carved", "minecraft:block/slab_permafrost_carved", 1003, (BlockLogicSupplier<BlockLogicSlab>) b -> new BlockLogicSlab(b, Blocks.PERMAFROST_CARVED))
         .withSound(BlockSounds.PERMAFROST).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
         .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+    public static final Block<BlockLogicSlab> SLAB_BRICK_IRON = register("slab.brick.iron", "minecraft:block/slab_brick_iron", 1004, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_IRON))
+        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+    public static final Block<BlockLogicSlab> SLAB_BRICK_GOLD = register("slab.brick.gold", "minecraft:block/slab_brick_gold", 1005, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_GOLD))
+        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+    public static final Block<BlockLogicSlab> SLAB_BRICK_STEEL = register("slab.brick.steel", "minecraft:block/slab_brick_steel", 1006, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_STEEL))
+        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+    public static final Block<BlockLogicSlab> SLAB_BRICK_LAPIS = register("slab.brick.lapis", "minecraft:block/slab_brick_lapis", 1007, (BlockLogicSupplier<BlockLogicSlab>)b -> new BlockLogicSlab(b, Blocks.BRICK_LAPIS))
+        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+
+    public static final Block<BlockLogicStairs> STAIRS_BRICK_IRON = register("stairs.brick.iron", "minecraft:block/stairs_brick_iron", 1050, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_IRON))
+        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+    public static final Block<BlockLogicStairs> STAIRS_BRICK_GOLD = register("stairs.brick.gold", "minecraft:block/stairs_brick_gold", 1051, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_GOLD))
+        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+    public static final Block<BlockLogicStairs> STAIRS_BRICK_STEEL = register("stairs.brick.steel", "minecraft:block/stairs_brick_steel", 1052, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_STEEL))
+        .withSound(BlockSounds.METAL).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
+    public static final Block<BlockLogicStairs> STAIRS_BRICK_LAPIS = register("stairs.brick.lapis", "minecraft:block/stairs_brick_lapis", 1053, (BlockLogicSupplier<BlockLogicStairs>)b -> new BlockLogicStairs(b, Blocks.BRICK_LAPIS))
+        .withSound(BlockSounds.STONE).withDisabledNeighborNotifyOnMetadataChange().withLitInteriorSurface(true)
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final Block<BlockLogicStatue> STATUE_STONE_LOWER = register("statue.stone.lower", "minecraft:block/statue_stone_lower", 1010, (BlockLogicSupplier<BlockLogicStatue>) b -> new BlockLogicStatue(b, Material.stone, true, () -> Items.STATUE_STONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F)
diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java b/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java
index 8fb9c02a1..2bc03d683 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/EntityPainting.java
@@ -6,6 +6,7 @@ import net.minecraft.core.enums.EnumBlockSoundEffectType;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.util.collection.NamespaceID;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.MathHelper;
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.world.World;
@@ -149,10 +150,7 @@ public class EntityPainting extends Entity
             if(!canStay())
             {
                 remove();
-                world.entityJoinedWorld(new EntityItem(world, x, y, z, new ItemStack(Items.PAINTING)));
-                if (getBorderStack() != null){
-                    this.world.entityJoinedWorld(new EntityItem(this.world, this.x, this.y, this.z, getBorderStack()));
-                }
+                drop();
             }
         }
     }
@@ -232,10 +230,7 @@ public class EntityPainting extends Entity
             markHurt();
             if (!(entity instanceof Player) || ((Player) entity).getGamemode().dropBlockOnBreak())
             {
-                world.entityJoinedWorld(new EntityItem(world, x, y, z, new ItemStack(Items.PAINTING)));
-                if (getBorderStack() != null){
-                    this.world.entityJoinedWorld(new EntityItem(this.world, this.x, this.y, this.z, getBorderStack()));
-                }
+                drop();
             }
             world.playBlockSoundEffect(null, this.x, this.y + heightOffset, this.z, Blocks.PLANKS_OAK, EnumBlockSoundEffectType.MINE);
         }
@@ -285,7 +280,7 @@ public class EntityPainting extends Entity
         if(!world.isClientSide && xd * xd + yd * yd + zd * zd > 0.0D)
         {
             remove();
-            world.entityJoinedWorld(new EntityItem(world, x, y, z, new ItemStack(Items.PAINTING)));
+            drop();
         }
     }
 
@@ -295,7 +290,37 @@ public class EntityPainting extends Entity
         if(!world.isClientSide && x * x + y * y + z * z > 0.0D)
         {
             remove();
-            world.entityJoinedWorld(new EntityItem(world, this.x, this.y, this.z, new ItemStack(Items.PAINTING)));
+            drop();
+        }
+    }
+
+    protected void drop() {
+        final Direction d;
+        switch (direction) {
+            case 0: {
+                d = Direction.NORTH;
+                break;
+            }
+            case 1: {
+                d = Direction.WEST;
+                break;
+            }
+            case 2: {
+                d = Direction.SOUTH;
+                break;
+            }
+            case 3:
+            default: {
+                d = Direction.EAST;
+                break;
+            }
+        }
+        final double x = this.x + d.getOffsetX()/4d;
+        final double y = this.y + d.getOffsetY()/4d;
+        final double z = this.z + d.getOffsetZ()/4d;
+        this.world.entityJoinedWorld(new EntityItem(this.world, x, y, z, new ItemStack(Items.PAINTING)));
+        if (getBorderStack() != null){
+            this.world.entityJoinedWorld(new EntityItem(this.world, x, y, z, getBorderStack()));
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/Utils.java b/game/core/src/main/java/net/minecraft/core/util/helper/Utils.java
index 7dd1202bf..3f2c34d21 100644
--- a/game/core/src/main/java/net/minecraft/core/util/helper/Utils.java
+++ b/game/core/src/main/java/net/minecraft/core/util/helper/Utils.java
@@ -3,9 +3,6 @@ package net.minecraft.core.util.helper;
 import com.mojang.logging.LogUtils;
 import org.slf4j.Logger;
 
-import java.awt.Desktop;
-import java.io.File;
-
 public abstract class Utils {
 	private static final Logger LOGGER = LogUtils.getLogger();
 	
diff --git a/game/core/src/main/resources/lang/en_US/gui.lang b/game/core/src/main/resources/lang/en_US/gui.lang
index bd3abd0ba..8d6aa0a84 100644
--- a/game/core/src/main/resources/lang/en_US/gui.lang
+++ b/game/core/src/main/resources/lang/en_US/gui.lang
@@ -33,6 +33,21 @@ gui.bad_java_arch.label.body.4=Please consider downloading a 64-bit JRE such as
 gui.bad_java_arch.button.download=Download
 gui.bad_java_arch.button.continue=Continue
 
+gui.no_jce.label.title=Java Cryptography Extension (JCE) not present!
+gui.no_jce.label.body.1=It looks like you're running Better than Adventure! without JCE.
+gui.no_jce.label.body.2=This will break some network related features like downloading
+gui.no_jce.label.body.3=sounds and multiplayer chatting!
+gui.no_jce.label.body.4=Please consider downloading a more up to date JRE
+gui.no_jce.label.body.5=with the extension included such as Eclipse Temurin.
+gui.no_jce.label.body.intel.disclaimer.1=Due to hardware compatibility issues on Intel Graphics hardware
+gui.no_jce.label.body.intel.disclaimer.2=you will likely have to patch your existing Java install to
+gui.no_jce.label.body.intel.disclaimer.3=include the JCE extension.
+gui.no_jce.button.download.recommended=Java Download (Recommended!)
+gui.no_jce.button.download=Java Download
+gui.no_jce.button.upgrade=JCE Patch
+gui.no_jce.button.upgrade.recommended=JCE Patch (Recommended!)
+gui.no_jce.button.continue=Continue
+
 gui.no_minecraft.label.title=Minecraft Beta 1.7.3 is Missing!
 gui.no_minecraft.label.body.1=It looks like you're running Better than Adventure! without Minecraft Beta 1.7.3.
 gui.no_minecraft.label.body.2=Better than Adventure! must be installed with an official copy of
@@ -156,7 +171,8 @@ gui.main_menu.label.splash.halloween=Happy Halloween!
 gui.main_menu.label.splash.new_year=Happy New Year!
 gui.main_menu.label.disclaimer.1=Copyright Mojang Studios. Not an official Minecraft product.
 gui.main_menu.label.disclaimer.2=Not approved by or associated with Mojang Studios or Microsoft.
-gui.main_menu.label.downloading_resources=Downloading resources: %s / %s
+gui.main_menu.label.downloading_resources.1=Downloading resources: %s / %s
+gui.main_menu.label.downloading_resources.2=Sounds may not play during this process!
 gui.main_menu.button.singleplayer=Singleplayer
 gui.main_menu.button.multiplayer=Multiplayer
 gui.main_menu.button.multiplayer.disabled=Multiplayer (not ready yet!)
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 800e92bb7..0f387b732 100644
--- a/game/core/src/main/resources/lang/en_US/item.lang
+++ b/game/core/src/main/resources/lang/en_US/item.lang
@@ -84,7 +84,7 @@ item.string.name=String
 item.string.desc=Silky smooth string from a spider.
 item.feather.chicken.name=Feather
 item.feather.chicken.desc=Plucked from a chicken.
-item.sulphur.name=Sulphur
+item.sulphur.name=Sulfur
 item.sulphur.desc=Explosive powder harvested from the deadly creeper.
 item.tool.hoe.wood.name=Wooden Hoe
 item.tool.hoe.wood.desc=Till the land with this wooden tool.
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 0d792530c..34aea4270 100644
--- a/game/core/src/main/resources/lang/en_US/tile.lang
+++ b/game/core/src/main/resources/lang/en_US/tile.lang
@@ -316,6 +316,14 @@ tile.slab.brick.sandstone.name=Sandstone Brick Slab
 tile.slab.brick.sandstone.desc=A slab of sandstone bricks.
 tile.slab.brick.permafrost.name=Permafrost Brick Slab
 tile.slab.brick.permafrost.desc=A slab of permafrost bricks.
+tile.slab.brick.iron.name=Iron Brick Slab
+tile.slab.brick.iron.desc=A slab of iron bricks.
+tile.slab.brick.gold.name=Gold Brick Slab
+tile.slab.brick.gold.desc=A slab of gold bricks.
+tile.slab.brick.steel.name=Steel Brick Slab
+tile.slab.brick.steel.desc=A slab of steel bricks.
+tile.slab.brick.lapis.name=Lapis Brick Slab
+tile.slab.brick.lapis.desc=A slab of lapis bricks.
 
 tile.stairs.planks.oak.name=Wooden Stairs
 tile.stairs.planks.oak.desc=Wooden block used for rapid vertical movement.
@@ -351,6 +359,14 @@ tile.stairs.brick.sandstone.name=Sandstone Brick Stairs
 tile.stairs.brick.sandstone.desc=Sandstone brick block used for rapid vertical movement.
 tile.stairs.brick.permafrost.name=Permafrost Brick Stairs
 tile.stairs.brick.permafrost.desc=Permafrost brick block used for rapid vertical movement.
+tile.stairs.brick.iron.name=Iron Brick Stairs
+tile.stairs.brick.iron.desc=Iron brick block used for rapid vertical movement.
+tile.stairs.brick.gold.name=Gold Brick Stairs
+tile.stairs.brick.gold.desc=Gold brick block used for rapid vertical movement.
+tile.stairs.brick.steel.name=Steel Brick Stairs
+tile.stairs.brick.steel.desc=Steel brick block used for rapid vertical movement.
+tile.stairs.brick.lapis.name=Lapis Brick Stairs
+tile.stairs.brick.lapis.desc=Lapis brick block used for rapid vertical movement.
 
 tile.stairs.planks.oak.painted.name=Mystery Wooden Stairs
 tile.stairs.planks.oak.painted.desc=How did you get this?!
@@ -1255,4 +1271,4 @@ tile.statue.marble.upper.desc=
 tile.statue.pigman.lower.name=Pigman Statue (Lower)
 tile.statue.pigman.lower.desc=
 tile.statue.pigman.upper.name=Pigman Statue (Upper)
-tile.statue.pigman.upper.desc=
\ No newline at end of file
+tile.statue.pigman.upper.desc=
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 7ade7d7f3..62e17e184 100644
--- a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
+++ b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
@@ -328,7 +328,7 @@ class WorkbenchGenerator {
                 "#X",
                 "X#")
             .addInput('#', Blocks.GLASS)
-            .addInput('X', Items.INGOT_STEEL)
+            .addInput('X', Items.INGOT_STEEL_CRUDE)
             .create("steel_glass", new ItemStack(Blocks.GLASS_STEEL, 4));
 
         RecipeBuilder.Shaped(CORE_NAMESPACE)
@@ -418,6 +418,10 @@ class WorkbenchGenerator {
             .addInput('#', Items.INGOT_STEEL_CRUDE)
             .create("crude_steel_to_steel_ingot", Items.INGOT_STEEL.getDefaultStack());
 
+        RecipeBuilder.Shapeless(CORE_NAMESPACE)
+            .addInput(Items.INGOT_STEEL)
+            .create("steel_ingot_to_crude_steel", new ItemStack(Items.INGOT_STEEL_CRUDE, 3));
+
         RecipeBuilder.Shaped(CORE_NAMESPACE)
             .setShape(
                 "#",
@@ -746,7 +750,7 @@ class WorkbenchGenerator {
         bricks.addInput('X', Items.BRICK_CLAY).create("clay_bricks", new ItemStack(Blocks.BRICK_CLAY, stackSize));
         bricks.addInput('X', Items.INGOT_GOLD).create("golden_bricks", new ItemStack(Blocks.BRICK_GOLD, stackSize));
         bricks.addInput('X', Items.INGOT_IRON).create("iron_bricks", new ItemStack(Blocks.BRICK_IRON, stackSize));
-        bricks.addInput('X', Items.INGOT_STEEL).create("steel_bricks", new ItemStack(Blocks.BRICK_STEEL, stackSize));
+        bricks.addInput('X', Items.INGOT_STEEL_CRUDE).create("steel_bricks", new ItemStack(Blocks.BRICK_STEEL, stackSize));
         bricks.addInput('X', Items.DYE, DyeColor.BLUE.itemMeta).create("lapis_lazuli_bricks", new ItemStack(Blocks.BRICK_LAPIS, stackSize));
         bricks.addInput('X', Blocks.SANDSTONE).create("sandstone_bricks", new ItemStack(Blocks.BRICK_SANDSTONE, stackSize));
         bricks.addInput('X', Blocks.STONE).create("stone_bricks", new ItemStack(Blocks.BRICK_STONE, stackSize));
@@ -800,6 +804,11 @@ class WorkbenchGenerator {
         slabs.addInput('X', Blocks.BRICK_SANDSTONE).create("brick_sandstone_slab", new ItemStack(Blocks.SLAB_BRICK_SANDSTONE, stackSize));
         slabs.addInput('X', Blocks.BRICK_PERMAFROST).create("brick_permafrost_slab", new ItemStack(Blocks.SLAB_BRICK_PERMAFROST, stackSize));
         slabs.addInput('X', Blocks.BRICK_NETHERRACK).create("netherrack_brick_slab", new ItemStack(Blocks.SLAB_BRICK_NETHERRACK, stackSize));
+
+        slabs.addInput('X', Blocks.BRICK_IRON).create("iron_brick_slab", new ItemStack(Blocks.SLAB_BRICK_IRON, stackSize));
+        slabs.addInput('X', Blocks.BRICK_GOLD).create("gold_brick_slab", new ItemStack(Blocks.SLAB_BRICK_GOLD, stackSize));
+        slabs.addInput('X', Blocks.BRICK_STEEL).create("steel_brick_slab", new ItemStack(Blocks.SLAB_BRICK_STEEL, stackSize));
+        slabs.addInput('X', Blocks.BRICK_LAPIS).create("lapis_brick_slab", new ItemStack(Blocks.SLAB_BRICK_LAPIS, stackSize));
     }
 
     private static void generateStairs() {
@@ -839,6 +848,11 @@ class WorkbenchGenerator {
         stairs.addInput('X', Blocks.BRICK_SANDSTONE).create("brick_sandstone_stairs", new ItemStack(Blocks.STAIRS_BRICK_SANDSTONE, stackSize));
         stairs.addInput('X', Blocks.BRICK_PERMAFROST).create("brick_permafrost_stairs", new ItemStack(Blocks.STAIRS_BRICK_PERMAFROST, stackSize));
         stairs.addInput('X', Blocks.BRICK_NETHERRACK).create("netherrack_brick_stairs", new ItemStack(Blocks.STAIRS_BRICK_NETHERRACK, stackSize));
+
+        stairs.addInput('X', Blocks.BRICK_IRON).create("iron_brick_stairs", new ItemStack(Blocks.STAIRS_BRICK_IRON, stackSize));
+        stairs.addInput('X', Blocks.BRICK_GOLD).create("gold_brick_stairs", new ItemStack(Blocks.STAIRS_BRICK_GOLD, stackSize));
+        stairs.addInput('X', Blocks.BRICK_STEEL).create("steel_brick_stairs", new ItemStack(Blocks.STAIRS_BRICK_STEEL, stackSize));
+        stairs.addInput('X', Blocks.BRICK_LAPIS).create("lapis_brick_stairs", new ItemStack(Blocks.STAIRS_BRICK_LAPIS, stackSize));
     }
 
     private static void generateDoors() {
@@ -856,7 +870,7 @@ class WorkbenchGenerator {
         door.addInput('X', Blocks.PLANKS_OAK).create("wooden_door", new ItemStack(Items.DOOR_OAK, stackSize));
         door.addInput('X', Blocks.GLASS).create("glass_door", new ItemStack(Items.DOOR_GLASS, stackSize));
         door.addInput('X', Items.INGOT_IRON).create("iron_door", new ItemStack(Items.DOOR_IRON, stackSize));
-        door.addInput('X', Items.INGOT_STEEL).create("steel_door", new ItemStack(Items.DOOR_STEEL, stackSize));
+        door.addInput('X', Items.INGOT_STEEL_CRUDE).create("steel_door", new ItemStack(Items.DOOR_STEEL, stackSize));
     }
 
     private static void generateTrapDoors() {
@@ -873,7 +887,7 @@ class WorkbenchGenerator {
         door.addInput('X', Blocks.PLANKS_OAK).create("wooden_trapdoor", new ItemStack(Blocks.TRAPDOOR_PLANKS_OAK, stackSize));
         door.addInput('X', Blocks.GLASS).create("glass_trapdoor", new ItemStack(Blocks.TRAPDOOR_GLASS, stackSize));
         door.addInput('X', Items.INGOT_IRON).create("iron_trapdoor", new ItemStack(Blocks.TRAPDOOR_IRON, stackSize));
-        door.addInput('X', Items.INGOT_STEEL).create("steel_trapdoor", new ItemStack(Blocks.TRAPDOOR_STEEL, stackSize));
+        door.addInput('X', Items.INGOT_STEEL_CRUDE).create("steel_trapdoor", new ItemStack(Blocks.TRAPDOOR_STEEL, stackSize));
     }
 
     private static void generateFences() {
@@ -894,7 +908,7 @@ class WorkbenchGenerator {
 
         fence.addInput('X', Items.STICK).addInput('#', Blocks.PAPER_WALL).create("paper_wall_fence", new ItemStack(Blocks.FENCE_PAPER_WALL, 4));
         fence.addInput('X', Items.INGOT_IRON).addInput('#', Items.CHAINLINK).create("chainlink_fence", new ItemStack(Blocks.FENCE_CHAINLINK, 8));
-        fence.addInput('X', Items.INGOT_STEEL).addInput('#', Items.INGOT_STEEL_CRUDE).create("steel_fence", new ItemStack(Blocks.FENCE_STEEL, 8));
+        fence.addInput('X', Items.INGOT_STEEL).addInput('#', Items.INGOT_STEEL_CRUDE).create("steel_fence", new ItemStack(Blocks.FENCE_STEEL, 16));
     }
 
     private static void generateFenceGates() {
